diff options
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r-- | crypto/authenc.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c index 18870906ea06..05eb32e0d949 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -46,6 +46,12 @@ struct authenc_request_ctx { | |||
46 | char tail[]; | 46 | char tail[]; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static void authenc_request_complete(struct aead_request *req, int err) | ||
50 | { | ||
51 | if (err != -EINPROGRESS) | ||
52 | aead_request_complete(req, err); | ||
53 | } | ||
54 | |||
49 | static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, | 55 | static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, |
50 | unsigned int keylen) | 56 | unsigned int keylen) |
51 | { | 57 | { |
@@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, | |||
142 | crypto_aead_authsize(authenc), 1); | 148 | crypto_aead_authsize(authenc), 1); |
143 | 149 | ||
144 | out: | 150 | out: |
145 | aead_request_complete(req, err); | 151 | authenc_request_complete(req, err); |
146 | } | 152 | } |
147 | 153 | ||
148 | static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err) | 154 | static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err) |
@@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq, | |||
208 | err = crypto_ablkcipher_decrypt(abreq); | 214 | err = crypto_ablkcipher_decrypt(abreq); |
209 | 215 | ||
210 | out: | 216 | out: |
211 | aead_request_complete(req, err); | 217 | authenc_request_complete(req, err); |
212 | } | 218 | } |
213 | 219 | ||
214 | static void authenc_verify_ahash_done(struct crypto_async_request *areq, | 220 | static void authenc_verify_ahash_done(struct crypto_async_request *areq, |
@@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq, | |||
245 | err = crypto_ablkcipher_decrypt(abreq); | 251 | err = crypto_ablkcipher_decrypt(abreq); |
246 | 252 | ||
247 | out: | 253 | out: |
248 | aead_request_complete(req, err); | 254 | authenc_request_complete(req, err); |
249 | } | 255 | } |
250 | 256 | ||
251 | static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags) | 257 | static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags) |
@@ -379,18 +385,20 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req, | |||
379 | err = crypto_authenc_genicv(areq, iv, 0); | 385 | err = crypto_authenc_genicv(areq, iv, 0); |
380 | } | 386 | } |
381 | 387 | ||
382 | aead_request_complete(areq, err); | 388 | authenc_request_complete(areq, err); |
383 | } | 389 | } |
384 | 390 | ||
385 | static int crypto_authenc_encrypt(struct aead_request *req) | 391 | static int crypto_authenc_encrypt(struct aead_request *req) |
386 | { | 392 | { |
387 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 393 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
388 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | 394 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
389 | struct ablkcipher_request *abreq = aead_request_ctx(req); | 395 | struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); |
390 | struct crypto_ablkcipher *enc = ctx->enc; | 396 | struct crypto_ablkcipher *enc = ctx->enc; |
391 | struct scatterlist *dst = req->dst; | 397 | struct scatterlist *dst = req->dst; |
392 | unsigned int cryptlen = req->cryptlen; | 398 | unsigned int cryptlen = req->cryptlen; |
393 | u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc); | 399 | struct ablkcipher_request *abreq = (void *)(areq_ctx->tail |
400 | + ctx->reqoff); | ||
401 | u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc); | ||
394 | int err; | 402 | int err; |
395 | 403 | ||
396 | ablkcipher_request_set_tfm(abreq, enc); | 404 | ablkcipher_request_set_tfm(abreq, enc); |
@@ -418,7 +426,7 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, | |||
418 | err = crypto_authenc_genicv(areq, greq->giv, 0); | 426 | err = crypto_authenc_genicv(areq, greq->giv, 0); |
419 | } | 427 | } |
420 | 428 | ||
421 | aead_request_complete(areq, err); | 429 | authenc_request_complete(areq, err); |
422 | } | 430 | } |
423 | 431 | ||
424 | static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) | 432 | static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) |
@@ -454,7 +462,7 @@ static int crypto_authenc_verify(struct aead_request *req, | |||
454 | unsigned int authsize; | 462 | unsigned int authsize; |
455 | 463 | ||
456 | areq_ctx->complete = authenc_verify_ahash_done; | 464 | areq_ctx->complete = authenc_verify_ahash_done; |
457 | areq_ctx->complete = authenc_verify_ahash_update_done; | 465 | areq_ctx->update_complete = authenc_verify_ahash_update_done; |
458 | 466 | ||
459 | ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP); | 467 | ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP); |
460 | if (IS_ERR(ohash)) | 468 | if (IS_ERR(ohash)) |
@@ -546,10 +554,6 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
546 | if (IS_ERR(auth)) | 554 | if (IS_ERR(auth)) |
547 | return PTR_ERR(auth); | 555 | return PTR_ERR(auth); |
548 | 556 | ||
549 | ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) + | ||
550 | crypto_ahash_alignmask(auth), | ||
551 | crypto_ahash_alignmask(auth) + 1); | ||
552 | |||
553 | enc = crypto_spawn_skcipher(&ictx->enc); | 557 | enc = crypto_spawn_skcipher(&ictx->enc); |
554 | err = PTR_ERR(enc); | 558 | err = PTR_ERR(enc); |
555 | if (IS_ERR(enc)) | 559 | if (IS_ERR(enc)) |
@@ -558,13 +562,18 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
558 | ctx->auth = auth; | 562 | ctx->auth = auth; |
559 | ctx->enc = enc; | 563 | ctx->enc = enc; |
560 | 564 | ||
561 | tfm->crt_aead.reqsize = max_t(unsigned int, | 565 | ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) + |
562 | crypto_ahash_reqsize(auth) + ctx->reqoff + | 566 | crypto_ahash_alignmask(auth), |
563 | sizeof(struct authenc_request_ctx) + | 567 | crypto_ahash_alignmask(auth) + 1) + |
568 | crypto_ablkcipher_ivsize(enc); | ||
569 | |||
570 | tfm->crt_aead.reqsize = sizeof(struct authenc_request_ctx) + | ||
571 | ctx->reqoff + | ||
572 | max_t(unsigned int, | ||
573 | crypto_ahash_reqsize(auth) + | ||
564 | sizeof(struct ahash_request), | 574 | sizeof(struct ahash_request), |
565 | sizeof(struct skcipher_givcrypt_request) + | 575 | sizeof(struct skcipher_givcrypt_request) + |
566 | crypto_ablkcipher_reqsize(enc) + | 576 | crypto_ablkcipher_reqsize(enc)); |
567 | crypto_ablkcipher_ivsize(enc)); | ||
568 | 577 | ||
569 | return 0; | 578 | return 0; |
570 | 579 | ||