This is preparation to introduce AES-XCBC-MAC. - introducing common interface "keyed hash" - making HMAC use the interface
--- commit 9c6b9affbacf12fc1e32868eaa14fef279b2696c tree 67b19707fae179e20bfb8060444f287d0bda7bb1 parent 650fb8382287f7990d5127a82a54295139224606 author Kazunori MIYAZAWA <[EMAIL PROTECTED]> Tue, 13 Jun 2006 10:02:54 +0900 committer Kazunori MIYAZAWA <[EMAIL PROTECTED]> Tue, 13 Jun 2006 10:02:54 +0900 crypto/digest.c | 23 +++++++++++++++++++---- crypto/hmac.c | 36 +++++++++++++++++++++++++----------- crypto/tcrypt.c | 2 +- include/linux/crypto.h | 31 +++++++++++++++++++++++++------ 4 files changed, 70 insertions(+), 22 deletions(-) diff --git a/crypto/digest.c b/crypto/digest.c index d9b6ac9..66bc263 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -85,11 +85,13 @@ static void digest(struct crypto_tfm *tf int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) { - return flags ? -EINVAL : 0; + tfm->crt_digest.cit_mode = flags & CRYPTO_TFM_MODE_MASK; + return 0; } int crypto_init_digest_ops(struct crypto_tfm *tfm) { + int ret = 0; struct digest_tfm *ops = &tfm->crt_digest; ops->dit_init = init; @@ -97,11 +99,24 @@ int crypto_init_digest_ops(struct crypto ops->dit_final = final; ops->dit_digest = digest; ops->dit_setkey = setkey; - - return crypto_alloc_hmac_block(tfm); + +#ifdef CONFIG_CRYPTO_HMAC + if (tfm->crt_digest.cit_mode & CRYPTO_TFM_MODE_HMAC) { + ret = crypto_alloc_hmac_block(tfm); + tfm->crt_keyedhash.kht_init = crypto_hmac_init; + tfm->crt_keyedhash.kht_update = crypto_hmac_update; + tfm->crt_keyedhash.kht_final = crypto_hmac_final; + tfm->crt_keyedhash.keyed_hash = crypto_hmac; + tfm->crt_keyedhash.kht_digestsize = crypto_tfm_alg_digestsize; + } +#endif + return ret; } void crypto_exit_digest_ops(struct crypto_tfm *tfm) { - crypto_free_hmac_block(tfm); +#ifdef CONFIG_CRYPTO_HMAC + if (tfm->crt_digest.cit_mode & CRYPTO_TFM_MODE_HMAC) + crypto_free_hmac_block(tfm); +#endif } diff --git a/crypto/hmac.c b/crypto/hmac.c index 46120de..d9610ca 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -34,10 +34,10 @@ int crypto_alloc_hmac_block(struct crypt int ret = 0; BUG_ON(!crypto_tfm_alg_blocksize(tfm)); - - tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), + + tfm->crt_keyedhash.kht_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), GFP_KERNEL); - if (tfm->crt_digest.dit_hmac_block == NULL) + if (tfm->crt_keyedhash.kht_hmac_block == NULL) ret = -ENOMEM; return ret; @@ -46,14 +46,16 @@ int crypto_alloc_hmac_block(struct crypt void crypto_free_hmac_block(struct crypto_tfm *tfm) { - kfree(tfm->crt_digest.dit_hmac_block); + kfree(tfm->crt_keyedhash.kht_hmac_block); } -void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) +int crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) { unsigned int i; struct scatterlist tmp; - char *ipad = tfm->crt_digest.dit_hmac_block; + char *ipad = tfm->crt_keyedhash.kht_hmac_block; + + BUG_ON(ipad == NULL); if (*keylen > crypto_tfm_alg_blocksize(tfm)) { hash_key(tfm, key, *keylen); @@ -70,6 +72,8 @@ void crypto_hmac_init(struct crypto_tfm crypto_digest_init(tfm); crypto_digest_update(tfm, &tmp, 1); + + return 0; } void crypto_hmac_update(struct crypto_tfm *tfm, @@ -78,13 +82,15 @@ void crypto_hmac_update(struct crypto_tf crypto_digest_update(tfm, sg, nsg); } -void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, +int crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8 *out) { unsigned int i; struct scatterlist tmp; - char *opad = tfm->crt_digest.dit_hmac_block; + char *opad = tfm->crt_keyedhash.kht_hmac_block; + BUG_ON(opad == NULL); + if (*keylen > crypto_tfm_alg_blocksize(tfm)) { hash_key(tfm, key, *keylen); *keylen = crypto_tfm_alg_digestsize(tfm); @@ -107,14 +113,22 @@ void crypto_hmac_final(struct crypto_tfm crypto_digest_update(tfm, &tmp, 1); crypto_digest_final(tfm, out); + + return 0; } -void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, +int crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, struct scatterlist *sg, unsigned int nsg, u8 *out) { - crypto_hmac_init(tfm, key, keylen); + int ret = 0; + + ret = crypto_hmac_init(tfm, key, keylen); + if (ret != 0) + return ret; crypto_hmac_update(tfm, sg, nsg); - crypto_hmac_final(tfm, key, keylen, out); + ret = crypto_hmac_final(tfm, key, keylen, out); + + return ret; } EXPORT_SYMBOL_GPL(crypto_hmac_init); diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 49e344f..37aeced 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -180,7 +180,7 @@ static void test_hmac(char *algo, struct struct hmac_testvec *hmac_tv; unsigned int tsize, klen; - tfm = crypto_alloc_tfm(algo, 0); + tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_HMAC); if (tfm == NULL) { printk("failed to load transform for %s\n", algo); return; diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 0ab1bc1..1ade651 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -44,6 +44,7 @@ #define CRYPTO_TFM_MODE_CBC 0x00000002 #define CRYPTO_TFM_MODE_CFB 0x00000004 #define CRYPTO_TFM_MODE_CTR 0x00000008 +#define CRYPTO_TFM_MODE_HMAC 0x00000080 #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 #define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200 @@ -192,6 +193,7 @@ struct cipher_tfm { }; struct digest_tfm { + u32 cit_mode; void (*dit_init)(struct crypto_tfm *tfm); void (*dit_update)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg); @@ -200,9 +202,6 @@ struct digest_tfm { unsigned int nsg, u8 *out); int (*dit_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); -#ifdef CONFIG_CRYPTO_HMAC - void *dit_hmac_block; -#endif }; struct compress_tfm { @@ -218,6 +217,23 @@ struct compress_tfm { #define crt_digest crt_u.digest #define crt_compress crt_u.compress +#if defined(CONFIG_CRYPTO_HMAC) + +#define kht_hmac_block kht_u.hmac_block + +struct keyed_hash_tfm { + int (*kht_init)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); + void (*kht_update)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg); + int (*kht_final)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8 *out); + int (*keyed_hash)(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, + struct scatterlist *sg, unsigned int nsg, u8 *out); + unsigned int (*kht_digestsize)(struct crypto_tfm *tfm); + union { + void *hmac_block; + } kht_u; +}; +#endif + struct crypto_tfm { u32 crt_flags; @@ -228,6 +244,9 @@ struct crypto_tfm { struct compress_tfm compress; } crt_u; +#if defined(CONFIG_CRYPTO_HMAC) + struct keyed_hash_tfm crt_keyedhash; +#endif struct crypto_alg *__crt_alg; char __crt_ctx[] __attribute__ ((__aligned__)); @@ -431,12 +450,12 @@ static inline int crypto_comp_decompress * HMAC support. */ #ifdef CONFIG_CRYPTO_HMAC -void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); +int crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); void crypto_hmac_update(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg); -void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, +int crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, u8 *out); -void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, +int crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, struct scatterlist *sg, unsigned int nsg, u8 *out); #endif /* CONFIG_CRYPTO_HMAC */ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html