summaryrefslogtreecommitdiff
path: root/crypto/shash.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-07-14 21:35:36 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2009-07-14 21:35:36 +0800
commit8c32c516eb1c1f9c14d25478442137c698788975 (patch)
treeba238ddbff551ac6c445e90ad9698a5aba55876a /crypto/shash.c
parent500b3e3c3dc8e4845b77ae81e5b7b085ab183ce6 (diff)
crypto: hash - Zap unaligned buffers
Some unaligned buffers on the stack weren't zapped properly which may cause secret data to be leaked. This patch fixes them by doing a zero memset. It is also possible for us to place random kernel stack contents in the digest buffer if a digest operation fails. This is fixed by only copying if the operation succeeded. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/shash.c')
-rw-r--r--crypto/shash.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/crypto/shash.c b/crypto/shash.c
index fd92c03b38fc..e54328364a85 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -45,8 +45,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
err = shash->setkey(tfm, alignbuffer, keylen);
- memset(alignbuffer, 0, keylen);
- kfree(buffer);
+ kzfree(buffer);
return err;
}
@@ -79,13 +78,16 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
((unsigned long)data & alignmask);
u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
__attribute__ ((aligned));
+ int err;
if (unaligned_len > len)
unaligned_len = len;
memcpy(buf, data, unaligned_len);
+ err = shash->update(desc, buf, unaligned_len);
+ memset(buf, 0, unaligned_len);
- return shash->update(desc, buf, unaligned_len) ?:
+ return err ?:
shash->update(desc, data + unaligned_len, len - unaligned_len);
}
@@ -114,7 +116,13 @@ static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
int err;
err = shash->final(desc, buf);
+ if (err)
+ goto out;
+
memcpy(out, buf, ds);
+
+out:
+ memset(buf, 0, ds);
return err;
}