From 27b2336029335ea3f02243ff170986cdab1f98ef Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 11 Mar 2015 17:53:04 +0100 Subject: digest: make it multi-instance Now you need to call digest_alloc and when you finish to use it digest_free. We need this for upcomming aes encryption support and secure boot as we will need multiple instance of the same digest. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Sascha Hauer --- crypto/digest.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--------- crypto/md5.c | 34 ++++++++++--------------------- crypto/sha1.c | 34 ++++++++++--------------------- crypto/sha2.c | 55 ++++++++++++++++++------------------------------- 4 files changed, 95 insertions(+), 91 deletions(-) (limited to 'crypto') 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; -- cgit v1.2.3