diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2010-03-03 09:41:08 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-03-03 09:41:08 -0500 |
commit | 50beceba7fdf5f10a04d8a053e62d40b742099ad (patch) | |
tree | 0c0a57f6b13d2dc955a6f5ecbbe647d9e3248322 | |
parent | cbb9bf65ae25dee772e85589136e7dd1c3e743ae (diff) |
crypto: authenc - Move saved IV in front of the ablkcipher request
In crypto_authenc_encrypt() we save the IV behind the ablkcipher
request. To save space on the request, we overwrite the ablkcipher
request with a ahash request after encryption. So the IV may be
overwritten by the ahash request. This patch fixes this by placing
the IV in front of the ablkcipher/ahash request.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/authenc.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c index 6287cfd4d7a0..2bb7348d8d55 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -386,11 +386,13 @@ static int crypto_authenc_encrypt(struct aead_request *req) | |||
386 | { | 386 | { |
387 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 387 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
388 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | 388 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
389 | struct ablkcipher_request *abreq = aead_request_ctx(req); | 389 | struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); |
390 | struct crypto_ablkcipher *enc = ctx->enc; | 390 | struct crypto_ablkcipher *enc = ctx->enc; |
391 | struct scatterlist *dst = req->dst; | 391 | struct scatterlist *dst = req->dst; |
392 | unsigned int cryptlen = req->cryptlen; | 392 | unsigned int cryptlen = req->cryptlen; |
393 | u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc); | 393 | struct ablkcipher_request *abreq = (void *)(areq_ctx->tail |
394 | + ctx->reqoff); | ||
395 | u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc); | ||
394 | int err; | 396 | int err; |
395 | 397 | ||
396 | ablkcipher_request_set_tfm(abreq, enc); | 398 | ablkcipher_request_set_tfm(abreq, enc); |
@@ -546,10 +548,6 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
546 | if (IS_ERR(auth)) | 548 | if (IS_ERR(auth)) |
547 | return PTR_ERR(auth); | 549 | return PTR_ERR(auth); |
548 | 550 | ||
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); | 551 | enc = crypto_spawn_skcipher(&ictx->enc); |
554 | err = PTR_ERR(enc); | 552 | err = PTR_ERR(enc); |
555 | if (IS_ERR(enc)) | 553 | if (IS_ERR(enc)) |
@@ -558,13 +556,18 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
558 | ctx->auth = auth; | 556 | ctx->auth = auth; |
559 | ctx->enc = enc; | 557 | ctx->enc = enc; |
560 | 558 | ||
561 | tfm->crt_aead.reqsize = max_t(unsigned int, | 559 | ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) + |
562 | crypto_ahash_reqsize(auth) + ctx->reqoff + | 560 | crypto_ahash_alignmask(auth), |
563 | sizeof(struct authenc_request_ctx) + | 561 | crypto_ahash_alignmask(auth) + 1) + |
562 | crypto_ablkcipher_ivsize(enc); | ||
563 | |||
564 | tfm->crt_aead.reqsize = sizeof(struct authenc_request_ctx) + | ||
565 | ctx->reqoff + | ||
566 | max_t(unsigned int, | ||
567 | crypto_ahash_reqsize(auth) + | ||
564 | sizeof(struct ahash_request), | 568 | sizeof(struct ahash_request), |
565 | sizeof(struct skcipher_givcrypt_request) + | 569 | sizeof(struct skcipher_givcrypt_request) + |
566 | crypto_ablkcipher_reqsize(enc) + | 570 | crypto_ablkcipher_reqsize(enc)); |
567 | crypto_ablkcipher_ivsize(enc)); | ||
568 | 571 | ||
569 | return 0; | 572 | return 0; |
570 | 573 | ||