diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/hmac.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/crypto/hmac.c b/crypto/hmac.c index b60c3c7aa320..14c6351e639d 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c | |||
@@ -57,14 +57,35 @@ static int hmac_setkey(struct crypto_hash *parent, | |||
57 | if (keylen > bs) { | 57 | if (keylen > bs) { |
58 | struct hash_desc desc; | 58 | struct hash_desc desc; |
59 | struct scatterlist tmp; | 59 | struct scatterlist tmp; |
60 | int tmplen; | ||
60 | int err; | 61 | int err; |
61 | 62 | ||
62 | desc.tfm = tfm; | 63 | desc.tfm = tfm; |
63 | desc.flags = crypto_hash_get_flags(parent); | 64 | desc.flags = crypto_hash_get_flags(parent); |
64 | desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; | 65 | desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; |
65 | sg_init_one(&tmp, inkey, keylen); | ||
66 | 66 | ||
67 | err = crypto_hash_digest(&desc, &tmp, keylen, digest); | 67 | err = crypto_hash_init(&desc); |
68 | if (err) | ||
69 | return err; | ||
70 | |||
71 | tmplen = bs * 2 + ds; | ||
72 | sg_init_one(&tmp, ipad, tmplen); | ||
73 | |||
74 | for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) { | ||
75 | memcpy(ipad, inkey, tmplen); | ||
76 | err = crypto_hash_update(&desc, &tmp, tmplen); | ||
77 | if (err) | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | if (keylen) { | ||
82 | memcpy(ipad, inkey, keylen); | ||
83 | err = crypto_hash_update(&desc, &tmp, keylen); | ||
84 | if (err) | ||
85 | return err; | ||
86 | } | ||
87 | |||
88 | err = crypto_hash_final(&desc, digest); | ||
68 | if (err) | 89 | if (err) |
69 | return err; | 90 | return err; |
70 | 91 | ||