aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-08-22 11:04:06 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-08-22 11:04:06 -0400
commita697690bece75d4ba424c1318eb25c37d41d5829 (patch)
tree0ff76eb4486bfa02708ea9a19d330b68bde83a81 /crypto
parent0c7281c0faa1d0bdbdc647430cbdf7e0aed7f385 (diff)
crypto: authenc - Avoid using clobbered request pointer
Authenc works in two stages for encryption, it first encrypts and then computes an ICV. The context memory of the request is used by both operations. The problem is that when an asynchronous encryption completes, we will compute the ICV and then reread the context memory of the encryption to get the original request. It just happens that we have a buffer of 16 bytes in front of the request pointer, so ICVs of 16 bytes (such as SHA1) do not trigger the bug. However, any attempt to uses a larger ICV instantly kills the machine when the first asynchronous encryption is completed. This patch fixes this by saving the request pointer before we start the ICV computation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/authenc.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 4b226768752a..fd9f06c63d76 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -174,8 +174,9 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
174static void crypto_authenc_encrypt_done(struct crypto_async_request *req, 174static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
175 int err) 175 int err)
176{ 176{
177 struct aead_request *areq = req->data;
178
177 if (!err) { 179 if (!err) {
178 struct aead_request *areq = req->data;
179 struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 180 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
180 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 181 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
181 struct ablkcipher_request *abreq = aead_request_ctx(areq); 182 struct ablkcipher_request *abreq = aead_request_ctx(areq);
@@ -185,7 +186,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
185 err = crypto_authenc_genicv(areq, iv, 0); 186 err = crypto_authenc_genicv(areq, iv, 0);
186 } 187 }
187 188
188 aead_request_complete(req->data, err); 189 aead_request_complete(areq, err);
189} 190}
190 191
191static int crypto_authenc_encrypt(struct aead_request *req) 192static int crypto_authenc_encrypt(struct aead_request *req)
@@ -216,14 +217,15 @@ static int crypto_authenc_encrypt(struct aead_request *req)
216static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, 217static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
217 int err) 218 int err)
218{ 219{
220 struct aead_request *areq = req->data;
221
219 if (!err) { 222 if (!err) {
220 struct aead_request *areq = req->data;
221 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); 223 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
222 224
223 err = crypto_authenc_genicv(areq, greq->giv, 0); 225 err = crypto_authenc_genicv(areq, greq->giv, 0);
224 } 226 }
225 227
226 aead_request_complete(req->data, err); 228 aead_request_complete(areq, err);
227} 229}
228 230
229static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) 231static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)