Skip to content

Commit

Permalink
[CRYPTO] hmac: Avoid calling virt_to_page on key
Browse files Browse the repository at this point in the history
When HMAC gets a key longer than the block size of the hash, it needs
to feed it as input to the hash to reduce it to a fixed length.  As
it is HMAC converts the key to a scatter and gather list.  However,
this doesn't work on certain platforms if the key is not allocated
via kmalloc.  For example, the keys from tcrypt are stored in the
rodata section and this causes it to fail with HMAC on x86-64.

This patch fixes this by copying the key to memory obtained via
kmalloc before hashing it.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
herbertx committed May 7, 2008
1 parent c0a1811 commit 67412f0
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions crypto/hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,35 @@ static int hmac_setkey(struct crypto_hash *parent,
if (keylen > bs) {
struct hash_desc desc;
struct scatterlist tmp;
int tmplen;
int err;

desc.tfm = tfm;
desc.flags = crypto_hash_get_flags(parent);
desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP;
sg_init_one(&tmp, inkey, keylen);

err = crypto_hash_digest(&desc, &tmp, keylen, digest);
err = crypto_hash_init(&desc);
if (err)
return err;

tmplen = bs * 2 + ds;
sg_init_one(&tmp, ipad, tmplen);

for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) {
memcpy(ipad, inkey, tmplen);
err = crypto_hash_update(&desc, &tmp, tmplen);
if (err)
return err;
}

if (keylen) {
memcpy(ipad, inkey, keylen);
err = crypto_hash_update(&desc, &tmp, keylen);
if (err)
return err;
}

err = crypto_hash_final(&desc, digest);
if (err)
return err;

Expand Down

0 comments on commit 67412f0

Please sign in to comment.