aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-03-28 15:54:03 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-04-02 05:56:15 -0400
commitd3dde52209ab571e4e2ec26c66f85ad1355f7475 (patch)
treeca1f749ba9eb9fb5e164c61d5b9ccb60a9a78aaf /crypto
parent246bbedb9aaf27e2207501d93a869023a439fce5 (diff)
crypto: gcm - fix assumption that assoc has one segment
rfc4543(gcm(*)) code for GMAC assumes that assoc scatterlist always contains only one segment and only makes use of this first segment. However ipsec passes assoc with three segments when using 'extended sequence number' thus in this case rfc4543(gcm(*)) fails to function correctly. Patch fixes this issue. Reported-by: Chaoxing Lin <Chaoxing.Lin@ultra-3eti.com> Tested-by: Chaoxing Lin <Chaoxing.Lin@ultra-3eti.com> Cc: stable@vger.kernel.org Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/gcm.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 137ad1ec5438..13ccbda34ff9 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -44,6 +44,7 @@ struct crypto_rfc4543_ctx {
44 44
45struct crypto_rfc4543_req_ctx { 45struct crypto_rfc4543_req_ctx {
46 u8 auth_tag[16]; 46 u8 auth_tag[16];
47 u8 assocbuf[32];
47 struct scatterlist cipher[1]; 48 struct scatterlist cipher[1];
48 struct scatterlist payload[2]; 49 struct scatterlist payload[2];
49 struct scatterlist assoc[2]; 50 struct scatterlist assoc[2];
@@ -1133,9 +1134,19 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req,
1133 scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); 1134 scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2);
1134 assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); 1135 assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);
1135 1136
1136 sg_init_table(assoc, 2); 1137 if (req->assoc->length == req->assoclen) {
1137 sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, 1138 sg_init_table(assoc, 2);
1138 req->assoc->offset); 1139 sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
1140 req->assoc->offset);
1141 } else {
1142 BUG_ON(req->assoclen > sizeof(rctx->assocbuf));
1143
1144 scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0,
1145 req->assoclen, 0);
1146
1147 sg_init_table(assoc, 2);
1148 sg_set_buf(assoc, rctx->assocbuf, req->assoclen);
1149 }
1139 scatterwalk_crypto_chain(assoc, payload, 0, 2); 1150 scatterwalk_crypto_chain(assoc, payload, 0, 2);
1140 1151
1141 aead_request_set_tfm(subreq, ctx->child); 1152 aead_request_set_tfm(subreq, ctx->child);