Commit a697690bece75d4ba424c1318eb25c37d41d5829

Authored by Herbert Xu
1 parent 0c7281c0fa

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>

Showing 1 changed file with 6 additions and 4 deletions Side-by-side Diff

... ... @@ -174,8 +174,9 @@
174 174 static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
175 175 int err)
176 176 {
  177 + struct aead_request *areq = req->data;
  178 +
177 179 if (!err) {
178   - struct aead_request *areq = req->data;
179 180 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
180 181 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
181 182 struct ablkcipher_request *abreq = aead_request_ctx(areq);
... ... @@ -185,7 +186,7 @@
185 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  
191 192 static int crypto_authenc_encrypt(struct aead_request *req)
192 193  
193 194  
... ... @@ -216,14 +217,15 @@
216 217 static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
217 218 int err)
218 219 {
  220 + struct aead_request *areq = req->data;
  221 +
219 222 if (!err) {
220   - struct aead_request *areq = req->data;
221 223 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
222 224  
223 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  
229 231 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)