9
0
Fork 0

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 <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Jean-Christophe PLAGNIOL-VILLARD 2015-03-11 17:53:04 +01:00 committed by Sascha Hauer
parent 804fae5d16
commit 27b2336029
7 changed files with 119 additions and 103 deletions

View File

@ -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;
}

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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__ */