|
@@ -29,107 +29,6 @@ struct hmac_ctx {
|
|
|
struct crypto_hash *child;
|
|
|
};
|
|
|
|
|
|
-static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
|
|
|
-{
|
|
|
- struct scatterlist tmp;
|
|
|
-
|
|
|
- sg_set_buf(&tmp, key, keylen);
|
|
|
- crypto_digest_digest(tfm, &tmp, 1, key);
|
|
|
-}
|
|
|
-
|
|
|
-int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
-
|
|
|
- BUG_ON(!crypto_tfm_alg_blocksize(tfm));
|
|
|
-
|
|
|
- tfm->crt_hash.hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
|
|
|
- GFP_KERNEL);
|
|
|
- if (tfm->crt_hash.hmac_block == NULL)
|
|
|
- ret = -ENOMEM;
|
|
|
-
|
|
|
- return ret;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-void crypto_free_hmac_block(struct crypto_tfm *tfm)
|
|
|
-{
|
|
|
- kfree(tfm->crt_hash.hmac_block);
|
|
|
-}
|
|
|
-
|
|
|
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
|
|
|
-{
|
|
|
- unsigned int i;
|
|
|
- struct scatterlist tmp;
|
|
|
- char *ipad = tfm->crt_hash.hmac_block;
|
|
|
-
|
|
|
- if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
|
|
|
- hash_key(tfm, key, *keylen);
|
|
|
- *keylen = crypto_tfm_alg_digestsize(tfm);
|
|
|
- }
|
|
|
-
|
|
|
- memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
|
|
|
- memcpy(ipad, key, *keylen);
|
|
|
-
|
|
|
- for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
|
|
|
- ipad[i] ^= 0x36;
|
|
|
-
|
|
|
- sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
|
|
|
-
|
|
|
- crypto_digest_init(tfm);
|
|
|
- crypto_digest_update(tfm, &tmp, 1);
|
|
|
-}
|
|
|
-
|
|
|
-void crypto_hmac_update(struct crypto_tfm *tfm,
|
|
|
- struct scatterlist *sg, unsigned int nsg)
|
|
|
-{
|
|
|
- crypto_digest_update(tfm, sg, nsg);
|
|
|
-}
|
|
|
-
|
|
|
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
|
|
|
- unsigned int *keylen, u8 *out)
|
|
|
-{
|
|
|
- unsigned int i;
|
|
|
- struct scatterlist tmp;
|
|
|
- char *opad = tfm->crt_hash.hmac_block;
|
|
|
-
|
|
|
- if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
|
|
|
- hash_key(tfm, key, *keylen);
|
|
|
- *keylen = crypto_tfm_alg_digestsize(tfm);
|
|
|
- }
|
|
|
-
|
|
|
- crypto_digest_final(tfm, out);
|
|
|
-
|
|
|
- memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
|
|
|
- memcpy(opad, key, *keylen);
|
|
|
-
|
|
|
- for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
|
|
|
- opad[i] ^= 0x5c;
|
|
|
-
|
|
|
- sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm));
|
|
|
-
|
|
|
- crypto_digest_init(tfm);
|
|
|
- crypto_digest_update(tfm, &tmp, 1);
|
|
|
-
|
|
|
- sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
|
|
|
-
|
|
|
- crypto_digest_update(tfm, &tmp, 1);
|
|
|
- crypto_digest_final(tfm, out);
|
|
|
-}
|
|
|
-
|
|
|
-void 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);
|
|
|
- crypto_hmac_update(tfm, sg, nsg);
|
|
|
- crypto_hmac_final(tfm, key, keylen, out);
|
|
|
-}
|
|
|
-
|
|
|
-EXPORT_SYMBOL_GPL(crypto_hmac_init);
|
|
|
-EXPORT_SYMBOL_GPL(crypto_hmac_update);
|
|
|
-EXPORT_SYMBOL_GPL(crypto_hmac_final);
|
|
|
-EXPORT_SYMBOL_GPL(crypto_hmac);
|
|
|
-
|
|
|
static inline void *align_ptr(void *p, unsigned int align)
|
|
|
{
|
|
|
return (void *)ALIGN((unsigned long)p, align);
|