diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-14 09:35:36 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-14 09:35:36 -0400 |
commit | 8c32c516eb1c1f9c14d25478442137c698788975 (patch) | |
tree | ba238ddbff551ac6c445e90ad9698a5aba55876a | |
parent | 500b3e3c3dc8e4845b77ae81e5b7b085ab183ce6 (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>
-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, | |||
152 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | 152 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); |
153 | memcpy(alignbuffer, key, keylen); | 153 | memcpy(alignbuffer, key, keylen); |
154 | ret = ahash->setkey(tfm, alignbuffer, keylen); | 154 | ret = ahash->setkey(tfm, alignbuffer, keylen); |
155 | memset(alignbuffer, 0, keylen); | 155 | kzfree(buffer); |
156 | kfree(buffer); | ||
157 | return ret; | 156 | return ret; |
158 | } | 157 | } |
159 | 158 | ||
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, | |||
45 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | 45 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); |
46 | memcpy(alignbuffer, key, keylen); | 46 | memcpy(alignbuffer, key, keylen); |
47 | err = shash->setkey(tfm, alignbuffer, keylen); | 47 | err = shash->setkey(tfm, alignbuffer, keylen); |
48 | memset(alignbuffer, 0, keylen); | 48 | kzfree(buffer); |
49 | kfree(buffer); | ||
50 | return err; | 49 | return err; |
51 | } | 50 | } |
52 | 51 | ||
@@ -79,13 +78,16 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, | |||
79 | ((unsigned long)data & alignmask); | 78 | ((unsigned long)data & alignmask); |
80 | u8 buf[shash_align_buffer_size(unaligned_len, alignmask)] | 79 | u8 buf[shash_align_buffer_size(unaligned_len, alignmask)] |
81 | __attribute__ ((aligned)); | 80 | __attribute__ ((aligned)); |
81 | int err; | ||
82 | 82 | ||
83 | if (unaligned_len > len) | 83 | if (unaligned_len > len) |
84 | unaligned_len = len; | 84 | unaligned_len = len; |
85 | 85 | ||
86 | memcpy(buf, data, unaligned_len); | 86 | memcpy(buf, data, unaligned_len); |
87 | err = shash->update(desc, buf, unaligned_len); | ||
88 | memset(buf, 0, unaligned_len); | ||
87 | 89 | ||
88 | return shash->update(desc, buf, unaligned_len) ?: | 90 | return err ?: |
89 | shash->update(desc, data + unaligned_len, len - unaligned_len); | 91 | shash->update(desc, data + unaligned_len, len - unaligned_len); |
90 | } | 92 | } |
91 | 93 | ||
@@ -114,7 +116,13 @@ static int shash_final_unaligned(struct shash_desc *desc, u8 *out) | |||
114 | int err; | 116 | int err; |
115 | 117 | ||
116 | err = shash->final(desc, buf); | 118 | err = shash->final(desc, buf); |
119 | if (err) | ||
120 | goto out; | ||
121 | |||
117 | memcpy(out, buf, ds); | 122 | memcpy(out, buf, ds); |
123 | |||
124 | out: | ||
125 | memset(buf, 0, ds); | ||
118 | return err; | 126 | return err; |
119 | } | 127 | } |
120 | 128 | ||