diff options
-rw-r--r-- | commands/digest.c | 3 | ||||
-rw-r--r-- | common/password.c | 5 | ||||
-rw-r--r-- | crypto/digest.c | 63 | ||||
-rw-r--r-- | crypto/md5.c | 34 | ||||
-rw-r--r-- | crypto/sha1.c | 34 | ||||
-rw-r--r-- | crypto/sha2.c | 55 | ||||
-rw-r--r-- | include/digest.h | 28 |
7 files changed, 119 insertions, 103 deletions
diff --git a/commands/digest.c b/commands/digest.c index bad7d3f094..c6a2751356 100644 --- a/commands/digest.c +++ b/commands/digest.c @@ -33,7 +33,7 @@ static int do_digest(char *algorithm, int argc, char *argv[]) int i; unsigned char *hash; - d = digest_get_by_name(algorithm); + d = digest_alloc(algorithm); BUG_ON(!d); if (argc < 2) @@ -71,6 +71,7 @@ static int do_digest(char *algorithm, int argc, char *argv[]) } free(hash); + digest_free(d); return ret; } diff --git a/common/password.c b/common/password.c index 16061095a8..4c33152dbe 100644 --- a/common/password.c +++ b/common/password.c @@ -280,7 +280,7 @@ static int __check_passwd(unsigned char* passwd, size_t length, int std) unsigned char *passwd2_sum; int ret = 0; - d = digest_get_by_name(PASSWD_SUM); + d = digest_alloc(PASSWD_SUM); passwd1_sum = calloc(digest_length(d), sizeof(unsigned char)); @@ -315,6 +315,7 @@ err2: free(passwd2_sum); err1: free(passwd1_sum); + digest_free(d); return ret; } @@ -347,7 +348,7 @@ int set_env_passwd(unsigned char* passwd, size_t length) unsigned char *passwd_sum; int ret; - d = digest_get_by_name(PASSWD_SUM); + d = digest_alloc(PASSWD_SUM); passwd_sum = calloc(digest_length(d), sizeof(unsigned char)); diff --git a/crypto/digest.c b/crypto/digest.c index 789c0b2fc9..65224bdbcf 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -28,12 +28,16 @@ static LIST_HEAD(digests); +static struct digest_algo* digest_algo_get_by_name(char* name); + static int dummy_init(struct digest *d) { return 0; } -int digest_register(struct digest *d) +static void dummy_free(struct digest *d) {} + +int digest_algo_register(struct digest_algo *d) { if (!d || !d->name || !d->update || !d->final || d->length < 1) return -EINVAL; @@ -41,27 +45,33 @@ int digest_register(struct digest *d) if (!d->init) d->init = dummy_init; - if (digest_get_by_name(d->name)) + if (!d->alloc) + d->alloc = dummy_init; + + if (!d->free) + d->free = dummy_free; + + if (digest_algo_get_by_name(d->name)) return -EEXIST; list_add_tail(&d->list, &digests); return 0; } -EXPORT_SYMBOL(digest_register); +EXPORT_SYMBOL(digest_algo_register); -void digest_unregister(struct digest *d) +void digest_algo_unregister(struct digest_algo *d) { if (!d) return; list_del(&d->list); } -EXPORT_SYMBOL(digest_unregister); +EXPORT_SYMBOL(digest_algo_unregister); -struct digest* digest_get_by_name(char* name) +static struct digest_algo *digest_algo_get_by_name(char* name) { - struct digest* d; + struct digest_algo* d; if (!name) return NULL; @@ -73,7 +83,37 @@ struct digest* digest_get_by_name(char* name) return NULL; } -EXPORT_SYMBOL_GPL(digest_get_by_name); + +struct digest *digest_alloc(char* name) +{ + struct digest* d; + struct digest_algo* algo; + + algo = digest_algo_get_by_name(name); + if (!algo) + return NULL; + + d = xzalloc(sizeof(*d)); + d->algo = algo; + d->ctx = xzalloc(algo->ctx_length); + if (d->algo->alloc(d)) { + digest_free(d); + return NULL; + } + + return d; +} +EXPORT_SYMBOL_GPL(digest_alloc); + +void digest_free(struct digest *d) +{ + if (!d) + return; + d->algo->free(d); + free(d->ctx); + free(d); +} +EXPORT_SYMBOL_GPL(digest_free); int digest_file_window(struct digest *d, char *filename, unsigned char *hash, @@ -164,11 +204,14 @@ int digest_file_by_name(char *algo, char *filename, unsigned char *hash) { struct digest *d; + int ret; - d = digest_get_by_name(algo); + d = digest_alloc(algo); if (!d) return -EIO; - return digest_file(d, filename, hash); + ret = digest_file(d, filename, hash); + digest_free(d); + return ret; } EXPORT_SYMBOL_GPL(digest_file_by_name); diff --git a/crypto/md5.c b/crypto/md5.c index 6c4ca1dd59..f70dd62131 100644 --- a/crypto/md5.c +++ b/crypto/md5.c @@ -265,16 +265,9 @@ MD5Transform(__u32 buf[4], __u32 const in[16]) buf[3] += d; } -struct md5 { - struct MD5Context context; - struct digest d; -}; - static int digest_md5_init(struct digest *d) { - struct md5 *m = container_of(d, struct md5, d); - - MD5Init(&m->context); + MD5Init(d->ctx); return 0; } @@ -282,35 +275,30 @@ static int digest_md5_init(struct digest *d) static int digest_md5_update(struct digest *d, const void *data, unsigned long len) { - struct md5 *m = container_of(d, struct md5, d); - - MD5Update(&m->context, data, len); + MD5Update(d->ctx, data, len); return 0; } static int digest_md5_final(struct digest *d, unsigned char *md) { - struct md5 *m = container_of(d, struct md5, d); - - MD5Final(md, &m->context); + MD5Final(md, d->ctx); return 0; } -static struct md5 m = { - .d = { - .name = "md5", - .init = digest_md5_init, - .update = digest_md5_update, - .final = digest_md5_final, - .length = 16, - } +static struct digest_algo md5 = { + .name = "md5", + .init = digest_md5_init, + .update = digest_md5_update, + .final = digest_md5_final, + .length = 16, + .ctx_length = sizeof(struct MD5Context), }; static int md5_digest_register(void) { - digest_register(&m.d); + digest_algo_register(&md5); return 0; } diff --git a/crypto/sha1.c b/crypto/sha1.c index 58d14a8b3f..b6f4cbbc5a 100644 --- a/crypto/sha1.c +++ b/crypto/sha1.c @@ -286,16 +286,9 @@ static void sha1_finish (sha1_context * ctx, uint8_t output[20]) PUT_UINT32_BE (ctx->state[4], output, 16); } -struct sha1 { - sha1_context context; - struct digest d; -}; - static int digest_sha1_init(struct digest *d) { - struct sha1 *m = container_of(d, struct sha1, d); - - sha1_starts(&m->context); + sha1_starts(d->ctx); return 0; } @@ -303,35 +296,30 @@ static int digest_sha1_init(struct digest *d) static int digest_sha1_update(struct digest *d, const void *data, unsigned long len) { - struct sha1 *m = container_of(d, struct sha1, d); - - sha1_update(&m->context, (uint8_t*)data, len); + sha1_update(d->ctx, (uint8_t*)data, len); return 0; } static int digest_sha1_final(struct digest *d, unsigned char *md) { - struct sha1 *m = container_of(d, struct sha1, d); - - sha1_finish(&m->context, md); + sha1_finish(d->ctx, md); return 0; } -static struct sha1 m = { - .d = { - .name = "sha1", - .init = digest_sha1_init, - .update = digest_sha1_update, - .final = digest_sha1_final, - .length = SHA1_SUM_LEN, - } +static struct digest_algo m = { + .name = "sha1", + .init = digest_sha1_init, + .update = digest_sha1_update, + .final = digest_sha1_final, + .length = SHA1_SUM_LEN, + .ctx_length = sizeof(sha1_context), }; static int sha1_digest_register(void) { - digest_register(&m.d); + digest_algo_register(&m); return 0; } diff --git a/crypto/sha2.c b/crypto/sha2.c index 00a1af3419..cc6b167f30 100644 --- a/crypto/sha2.c +++ b/crypto/sha2.c @@ -275,26 +275,17 @@ static void sha2_finish(sha2_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[7], digest, 28); } -struct sha2 { - sha2_context context; - struct digest d; -}; - static int digest_sha2_update(struct digest *d, const void *data, unsigned long len) { - struct sha2 *m = container_of(d, struct sha2, d); - - sha2_update(&m->context, (uint8_t *)data, len); + sha2_update(d->ctx, (uint8_t *)data, len); return 0; } static int digest_sha2_final(struct digest *d, unsigned char *md) { - struct sha2 *m = container_of(d, struct sha2, d); - - sha2_finish(&m->context, md); + sha2_finish(d->ctx, md); return 0; } @@ -302,52 +293,46 @@ static int digest_sha2_final(struct digest *d, unsigned char *md) #ifdef CONFIG_SHA224 static int digest_sha224_init(struct digest *d) { - struct sha2 *m = container_of(d, struct sha2, d); - - sha2_starts(&m->context, 1); + sha2_starts(d->ctx, 1); return 0; } -static struct sha2 m224 = { - .d = { - .name = "sha224", - .init = digest_sha224_init, - .update = digest_sha2_update, - .final = digest_sha2_final, - .length = SHA224_SUM_LEN, - } +static struct digest_algo m224 = { + .name = "sha224", + .init = digest_sha224_init, + .update = digest_sha2_update, + .final = digest_sha2_final, + .length = SHA224_SUM_LEN, + .ctx_length = sizeof(sha2_context), }; #endif #ifdef CONFIG_SHA256 static int digest_sha256_init(struct digest *d) { - struct sha2 *m = container_of(d, struct sha2, d); - - sha2_starts(&m->context, 0); + sha2_starts(d->ctx, 0); return 0; } -static struct sha2 m256 = { - .d = { - .name = "sha256", - .init = digest_sha256_init, - .update = digest_sha2_update, - .final = digest_sha2_final, - .length = SHA256_SUM_LEN, - } +static struct digest_algo m256 = { + .name = "sha256", + .init = digest_sha256_init, + .update = digest_sha2_update, + .final = digest_sha2_final, + .length = SHA256_SUM_LEN, + .ctx_length = sizeof(sha2_context), }; #endif static int sha2_digest_register(void) { #ifdef CONFIG_SHA224 - digest_register(&m224.d); + digest_algo_register(&m224); #endif #ifdef CONFIG_SHA256 - digest_register(&m256.d); + digest_algo_register(&m256); #endif return 0; diff --git a/include/digest.h b/include/digest.h index 208a463793..2fd1135175 100644 --- a/include/digest.h +++ b/include/digest.h @@ -21,26 +21,36 @@ #include <linux/list.h> -struct digest -{ +struct digest; + +struct digest_algo { char *name; + int (*alloc)(struct digest *d); + void (*free)(struct digest *d); int (*init)(struct digest *d); int (*update)(struct digest *d, const void *data, unsigned long len); int (*final)(struct digest *d, unsigned char *md); unsigned int length; + unsigned int ctx_length; struct list_head list; }; +struct digest { + struct digest_algo *algo; + void *ctx; +}; + /* * digest functions */ -int digest_register(struct digest *d); -void digest_unregister(struct digest *d); +int digest_algo_register(struct digest_algo *d); +void digest_algo_unregister(struct digest_algo *d); -struct digest* digest_get_by_name(char* name); +struct digest *digest_alloc(char* name); +void digest_free(struct digest *d); int digest_file_window(struct digest *d, char *filename, unsigned char *hash, @@ -52,23 +62,23 @@ int digest_file_by_name(char *algo, char *filename, static inline int digest_init(struct digest *d) { - return d->init(d); + return d->algo->init(d); } static inline int digest_update(struct digest *d, const void *data, unsigned long len) { - return d->update(d, data, len); + return d->algo->update(d, data, len); } static inline int digest_final(struct digest *d, unsigned char *md) { - return d->final(d, md); + return d->algo->final(d, md); } static inline int digest_length(struct digest *d) { - return d->length; + return d->algo->length; } #endif /* __SH_ST_DEVICES_H__ */ |