summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-04-07 16:43:46 +0300
committerHerbert Xu <herbert@gondor.apana.org.au>2013-04-25 21:01:47 +0800
commitf1dfdf9fc79900b810ea02dd6245dd133176c467 (patch)
tree9c5149ca74e3af3874c6020f6f4bf81f67f53222
parent31dd4d840115fef6f72894c816fc39c46abfd77d (diff)
downloadlinux-crypto-f1dfdf9fc79900b810ea02dd6245dd133176c467.tar.gz
linux-crypto-f1dfdf9fc79900b810ea02dd6245dd133176c467.zip
crypto: gcm - fix rfc4543 to handle async crypto correctly
If the gcm cipher used by rfc4543 does not complete request immediately, the authentication tag is not copied to destination buffer. Patch adds correct async logic for this case. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/gcm.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 4ff21399..b0d3cb12 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -1099,6 +1099,21 @@ static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
return crypto_aead_setauthsize(ctx->child, authsize);
}
+static void crypto_rfc4543_done(struct crypto_async_request *areq, int err)
+{
+ struct aead_request *req = areq->data;
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req);
+
+ if (!err) {
+ scatterwalk_map_and_copy(rctx->auth_tag, req->dst,
+ req->cryptlen,
+ crypto_aead_authsize(aead), 1);
+ }
+
+ aead_request_complete(req, err);
+}
+
static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
bool enc)
{
@@ -1145,8 +1160,8 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
scatterwalk_crypto_chain(assoc, payload, 0, 2);
aead_request_set_tfm(subreq, ctx->child);
- aead_request_set_callback(subreq, req->base.flags, req->base.complete,
- req->base.data);
+ aead_request_set_callback(subreq, req->base.flags, crypto_rfc4543_done,
+ req);
aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv);
aead_request_set_assoc(subreq, assoc, assoclen);