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:
parent
804fae5d16
commit
27b2336029
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
34
crypto/md5.c
34
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue