From 74ae32512357bdd4872bf160dc697ff7b54b54c5 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 19 Oct 2010 18:09:16 +0100 Subject: [PATCH] liblib: Added a common API for accessing all hash methods. --- src/lib/Makefile.am | 2 ++ src/lib/hash-method.c | 68 +++++++++++++++++++++++++++++++++++++++++++ src/lib/hash-method.h | 21 +++++++++++++ src/lib/md4.c | 24 +++++++++++++++ src/lib/md4.h | 4 +++ src/lib/md5.c | 24 +++++++++++++++ src/lib/md5.h | 4 +++ src/lib/sha1.c | 24 +++++++++++++++ src/lib/sha1.h | 4 +++ src/lib/sha2.c | 48 ++++++++++++++++++++++++++++++ src/lib/sha2.h | 5 ++++ 11 files changed, 228 insertions(+) create mode 100644 src/lib/hash-method.c create mode 100644 src/lib/hash-method.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 0ee3f61fa0..69700e5122 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -36,6 +36,7 @@ liblib_la_SOURCES = \ file-lock.c \ file-set-size.c \ hash.c \ + hash-method.c \ hash2.c \ hex-binary.c \ hex-dec.c \ @@ -145,6 +146,7 @@ headers = \ file-set-size.h \ fsync-mode.h \ hash.h \ + hash-method.h \ hash2.h \ hex-binary.h \ hex-dec.h \ diff --git a/src/lib/hash-method.c b/src/lib/hash-method.c new file mode 100644 index 0000000000..2e16b86505 --- /dev/null +++ b/src/lib/hash-method.c @@ -0,0 +1,68 @@ +/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "md4.h" +#include "md5.h" +#include "sha1.h" +#include "sha2.h" +#include "hash-method.h" + +const struct hash_method *hash_method_lookup(const char *name) +{ + unsigned int i; + + for (i = 0; hash_methods[i] != NULL; i++) { + if (strcmp(hash_methods[i]->name, name) == 0) + return hash_methods[i]; + } + return NULL; +} + +static void hash_method_init_size(void *context) +{ + uint64_t *ctx = context; + + *ctx = 0; +} + +static void +hash_method_loop_size(void *context, const void *data ATTR_UNUSED, size_t size) +{ + uint64_t *ctx = context; + + *ctx += size; +} + +static void hash_method_result_size(void *context, unsigned char *result_r) +{ + uint64_t *ctx = context; + + result_r[0] = (*ctx & 0xff00000000000000ULL) >> 56; + result_r[1] = (*ctx & 0x00ff000000000000ULL) >> 48; + result_r[2] = (*ctx & 0x0000ff0000000000ULL) >> 40; + result_r[3] = (*ctx & 0x000000ff00000000ULL) >> 32; + result_r[4] = (*ctx & 0x00000000ff000000ULL) >> 24; + result_r[5] = (*ctx & 0x0000000000ff0000ULL) >> 16; + result_r[6] = (*ctx & 0x000000000000ff00ULL) >> 8; + result_r[7] = (*ctx & 0x00000000000000ffULL); +} + +const struct hash_method hash_method_size = { + "size", + sizeof(uint64_t), + sizeof(uint64_t), + + hash_method_init_size, + hash_method_loop_size, + hash_method_result_size +}; + +const struct hash_method *hash_methods[] = { + &hash_method_md4, + &hash_method_md5, + &hash_method_sha1, + &hash_method_sha256, + &hash_method_sha512, + &hash_method_size, + NULL +}; diff --git a/src/lib/hash-method.h b/src/lib/hash-method.h new file mode 100644 index 0000000000..a330e60e52 --- /dev/null +++ b/src/lib/hash-method.h @@ -0,0 +1,21 @@ +#ifndef HASH_METHOD_H +#define HASH_METHOD_H + +struct hash_method { + const char *name; + /* Number of bytes that must be allocated for context */ + unsigned int context_size; + /* Number of bytes that must be allocated for result()'s digest */ + unsigned int digest_size; + + void (*init)(void *context); + void (*loop)(void *context, const void *data, size_t size); + void (*result)(void *context, unsigned char *digest_r); +}; + +const struct hash_method *hash_method_lookup(const char *name); + +/* NULL-terminated list of all hash methods */ +extern const struct hash_method *hash_methods[]; + +#endif diff --git a/src/lib/md4.c b/src/lib/md4.c index 034f24fe54..114d8f7c61 100644 --- a/src/lib/md4.c +++ b/src/lib/md4.c @@ -265,3 +265,27 @@ void md4_get_digest(const void *data, size_t size, md4_update(&ctx, data, size); md4_final(&ctx, result); } + +static void hash_method_init_md4(void *context) +{ + md4_init(context); +} +static void hash_method_loop_md4(void *context, const void *data, size_t size) +{ + md4_update(context, data, size); +} + +static void hash_method_result_md4(void *context, unsigned char *result_r) +{ + md4_final(context, result_r); +} + +const struct hash_method hash_method_md4 = { + "md4", + sizeof(struct md4_context), + MD4_RESULTLEN, + + hash_method_init_md4, + hash_method_loop_md4, + hash_method_result_md4 +}; diff --git a/src/lib/md4.h b/src/lib/md4.h index fce40bd289..771e08c850 100644 --- a/src/lib/md4.h +++ b/src/lib/md4.h @@ -9,6 +9,8 @@ #ifndef MD4_H #define MD4_H +#include "hash-method.h" + #define MD4_RESULTLEN (128/8) struct md4_context { @@ -25,4 +27,6 @@ void md4_final(struct md4_context *ctx, unsigned char result[MD4_RESULTLEN]); void md4_get_digest(const void *data, size_t size, unsigned char result[MD4_RESULTLEN]); +extern const struct hash_method hash_method_md4; + #endif diff --git a/src/lib/md5.c b/src/lib/md5.c index c7c645e5e0..9f1dfea7fc 100644 --- a/src/lib/md5.c +++ b/src/lib/md5.c @@ -280,3 +280,27 @@ void md5_get_digest(const void *data, size_t size, md5_update(&ctx, data, size); md5_final(&ctx, result); } + +static void hash_method_init_md5(void *context) +{ + md5_init(context); +} +static void hash_method_loop_md5(void *context, const void *data, size_t size) +{ + md5_update(context, data, size); +} + +static void hash_method_result_md5(void *context, unsigned char *result_r) +{ + md5_final(context, result_r); +} + +const struct hash_method hash_method_md5 = { + "md5", + sizeof(struct md5_context), + MD5_RESULTLEN, + + hash_method_init_md5, + hash_method_loop_md5, + hash_method_result_md5 +}; diff --git a/src/lib/md5.h b/src/lib/md5.h index aa0e426147..3da87fba37 100644 --- a/src/lib/md5.h +++ b/src/lib/md5.h @@ -9,6 +9,8 @@ #ifndef MD5_H #define MD5_H +#include "hash-method.h" + #define MD5_RESULTLEN (128/8) struct md5_context { @@ -25,4 +27,6 @@ void md5_final(struct md5_context *ctx, unsigned char result[MD5_RESULTLEN]); void md5_get_digest(const void *data, size_t size, unsigned char result[MD5_RESULTLEN]); +extern const struct hash_method hash_method_md5; + #endif diff --git a/src/lib/sha1.c b/src/lib/sha1.c index 48ef5111dd..947f3f7d8f 100644 --- a/src/lib/sha1.c +++ b/src/lib/sha1.c @@ -261,3 +261,27 @@ void sha1_get_digest(const void *data, size_t size, sha1_loop(&ctx, data, size); sha1_result(&ctx, result); } + +static void hash_method_init_sha1(void *context) +{ + sha1_init(context); +} +static void hash_method_loop_sha1(void *context, const void *data, size_t size) +{ + sha1_loop(context, data, size); +} + +static void hash_method_result_sha1(void *context, unsigned char *result_r) +{ + sha1_result(context, result_r); +} + +const struct hash_method hash_method_sha1 = { + "sha1", + sizeof(struct sha1_ctxt), + SHA1_RESULTLEN, + + hash_method_init_sha1, + hash_method_loop_sha1, + hash_method_result_sha1 +}; diff --git a/src/lib/sha1.h b/src/lib/sha1.h index a7d6cf8480..539f3c50c5 100644 --- a/src/lib/sha1.h +++ b/src/lib/sha1.h @@ -38,6 +38,8 @@ #ifndef SHA1_H #define SHA1_H +#include "hash-method.h" + /* libmysqlclient really should try to keep its internal stuff internal so they won't conflict with the actual programs that are trying to use it. This particular instance has been fixed in 4.1.18 and 5.0.19, but there @@ -77,4 +79,6 @@ typedef struct sha1_ctxt SHA1_CTX; extern void sha1_get_digest(const void *, size_t, unsigned char [SHA1_RESULTLEN]); +extern const struct hash_method hash_method_sha1; + #endif diff --git a/src/lib/sha2.c b/src/lib/sha2.c index a1815b781b..9ea500d6f0 100644 --- a/src/lib/sha2.c +++ b/src/lib/sha2.c @@ -423,3 +423,51 @@ void sha512_get_digest(const void *data, size_t size, sha512_loop(&ctx, data, size); sha512_result(&ctx, digest); } + +static void hash_method_init_sha256(void *context) +{ + sha256_init(context); +} +static void hash_method_loop_sha256(void *context, const void *data, size_t size) +{ + sha256_loop(context, data, size); +} + +static void hash_method_result_sha256(void *context, unsigned char *result_r) +{ + sha256_result(context, result_r); +} + +const struct hash_method hash_method_sha256 = { + "sha256", + sizeof(struct sha256_ctx), + SHA256_RESULTLEN, + + hash_method_init_sha256, + hash_method_loop_sha256, + hash_method_result_sha256 +}; + +static void hash_method_init_sha512(void *context) +{ + sha512_init(context); +} +static void hash_method_loop_sha512(void *context, const void *data, size_t size) +{ + sha512_loop(context, data, size); +} + +static void hash_method_result_sha512(void *context, unsigned char *result_r) +{ + sha512_result(context, result_r); +} + +const struct hash_method hash_method_sha512 = { + "sha512", + sizeof(struct sha512_ctx), + SHA512_RESULTLEN, + + hash_method_init_sha512, + hash_method_loop_sha512, + hash_method_result_sha512 +}; diff --git a/src/lib/sha2.h b/src/lib/sha2.h index 7318fae0df..3ee937441d 100644 --- a/src/lib/sha2.h +++ b/src/lib/sha2.h @@ -34,6 +34,8 @@ #ifndef SHA2_H #define SHA2_H +#include "hash-method.h" + #define SHA256_RESULTLEN (256 / 8) #define SHA256_BLOCK_SIZE (512 / 8) @@ -70,4 +72,7 @@ void sha512_result(struct sha512_ctx *ctx, void sha512_get_digest(const void *data, size_t size, unsigned char digest[SHA512_RESULTLEN]); +extern const struct hash_method hash_method_sha256; +extern const struct hash_method hash_method_sha512; + #endif /* !SHA2_H */ -- 2.47.3