crypto: authenc - Fix cryptlen calculation
Shikhar Khattar [Thu, 20 May 2010 09:40:31 +0000 (19:40 +1000)]
This patch (applied against 2.6.34) fixes the calculation of the
length of the ABLKCIPHER decrypt request ("cryptlen") after an
asynchronous hash request has been completed in the AUTHENC interface.

Signed-off-by: Shikhar Khattar <shikhark@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

crypto/authenc.c

index 05eb32e..b9884ee 100644 (file)
@@ -181,6 +181,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
        struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
        struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
        struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
+       unsigned int cryptlen = req->cryptlen;
 
        if (err)
                goto out;
@@ -196,6 +197,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
                goto out;
 
        authsize = crypto_aead_authsize(authenc);
+       cryptlen -= authsize;
        ihash = ahreq->result + authsize;
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
@@ -209,7 +211,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
        ablkcipher_request_set_callback(abreq, aead_request_flags(req),
                                        req->base.complete, req->base.data);
        ablkcipher_request_set_crypt(abreq, req->src, req->dst,
-                                    req->cryptlen, req->iv);
+                                    cryptlen, req->iv);
 
        err = crypto_ablkcipher_decrypt(abreq);
 
@@ -228,11 +230,13 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
        struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
        struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
        struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
+       unsigned int cryptlen = req->cryptlen;
 
        if (err)
                goto out;
 
        authsize = crypto_aead_authsize(authenc);
+       cryptlen -= authsize;
        ihash = ahreq->result + authsize;
        scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
                                 authsize, 0);
@@ -246,7 +250,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
        ablkcipher_request_set_callback(abreq, aead_request_flags(req),
                                        req->base.complete, req->base.data);
        ablkcipher_request_set_crypt(abreq, req->src, req->dst,
-                                    req->cryptlen, req->iv);
+                                    cryptlen, req->iv);
 
        err = crypto_ablkcipher_decrypt(abreq);