diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-14 21:35:36 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-14 21:35:36 +0800 |
commit | 8c32c516eb1c1f9c14d25478442137c698788975 (patch) | |
tree | ba238ddbff551ac6c445e90ad9698a5aba55876a /crypto | |
parent | 500b3e3c3dc8e4845b77ae81e5b7b085ab183ce6 (diff) | |
download | linux-8c32c516eb1c1f9c14d25478442137c698788975.tar.bz2 |
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')
-rw-r--r-- | crypto/ahash.c | 3 | ||||
-rw-r--r-- | crypto/shash.c | 14 |
2 files changed, 12 insertions, 5 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index cc824ef25830..1576f95f9afe 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -152,8 +152,7 @@ static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); memcpy(alignbuffer, key, keylen); ret = ahash->setkey(tfm, alignbuffer, keylen); - memset(alignbuffer, 0, keylen); - kfree(buffer); + kzfree(buffer); return ret; } 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; } |