bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "lib.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "md4.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "md5.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "sha1.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "sha2.h"
70ee483d320a270993b56c713e350b736edd753fAki Tuomi#include "sha3.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen#include "hash-method.h"
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenconst struct hash_method *hash_method_lookup(const char *name)
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen{
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen unsigned int i;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen for (i = 0; hash_methods[i] != NULL; i++) {
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen if (strcmp(hash_methods[i]->name, name) == 0)
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen return hash_methods[i];
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen }
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen return NULL;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen}
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenstatic void hash_method_init_size(void *context)
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen{
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen uint64_t *ctx = context;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen *ctx = 0;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen}
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenstatic void
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenhash_method_loop_size(void *context, const void *data ATTR_UNUSED, size_t size)
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen{
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen uint64_t *ctx = context;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen *ctx += size;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen}
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenstatic void hash_method_result_size(void *context, unsigned char *result_r)
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen{
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen uint64_t *ctx = context;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[0] = (*ctx & 0xff00000000000000ULL) >> 56;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[1] = (*ctx & 0x00ff000000000000ULL) >> 48;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[2] = (*ctx & 0x0000ff0000000000ULL) >> 40;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[3] = (*ctx & 0x000000ff00000000ULL) >> 32;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[4] = (*ctx & 0x00000000ff000000ULL) >> 24;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[5] = (*ctx & 0x0000000000ff0000ULL) >> 16;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[6] = (*ctx & 0x000000000000ff00ULL) >> 8;
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen result_r[7] = (*ctx & 0x00000000000000ffULL);
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen}
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomibuffer_t *t_hash_data(const struct hash_method *meth,
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi const void *data, size_t data_len)
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi{
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi i_assert(meth != NULL);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi i_assert(data_len == 0 || data != NULL);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi unsigned char ctx[meth->context_size];
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi buffer_t *result = t_buffer_create(meth->digest_size);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi unsigned char *resptr = buffer_append_space_unsafe(result,
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi meth->digest_size);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi meth->init(ctx);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi meth->loop(ctx, data == NULL ? "" : data, data_len);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi meth->result(ctx, resptr);
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi return result;
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi}
ba706bd508fdbe3e6c971769d0c913b32bf458ebAki Tuomi
0b3e92b6043435c5aa9f1cf1d04b632f3e19abd9Phil Carmodystatic const struct hash_method hash_method_size = {
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen "size",
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen sizeof(uint64_t),
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen sizeof(uint64_t),
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen hash_method_init_size,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen hash_method_loop_size,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen hash_method_result_size
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen};
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainenconst struct hash_method *hash_methods[] = {
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_md4,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_md5,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_sha1,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_sha256,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_sha512,
70ee483d320a270993b56c713e350b736edd753fAki Tuomi &hash_method_sha3_256,
70ee483d320a270993b56c713e350b736edd753fAki Tuomi &hash_method_sha3_512,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen &hash_method_size,
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen NULL
74ae32512357bdd4872bf160dc697ff7b54b54c5Timo Sirainen};