aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2015-03-12 04:17:51 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-03-13 06:32:21 -0400
commitccfe8c3f7e52ae83155cb038753f4c75b774ca8a (patch)
treebda8f786f405e84bf01d54d7b082da771ffc1319
parent001eabfd54c0cbf9d7d16264ddc8cc0bee67e3ed (diff)
crypto: aesni - fix memory usage in GCM decryption
The kernel crypto API logic requires the caller to provide the length of (ciphertext || authentication tag) as cryptlen for the AEAD decryption operation. Thus, the cipher implementation must calculate the size of the plaintext output itself and cannot simply use cryptlen. The RFC4106 GCM decryption operation tries to overwrite cryptlen memory in req->dst. As the destination buffer for decryption only needs to hold the plaintext memory but cryptlen references the input buffer holding (ciphertext || authentication tag), the assumption of the destination buffer length in RFC4106 GCM operation leads to a too large size. This patch simply uses the already calculated plaintext size. In addition, this patch fixes the offset calculation of the AAD buffer pointer: as mentioned before, cryptlen already includes the size of the tag. Thus, the tag does not need to be added. With the addition, the AAD will be written beyond the already allocated buffer. Note, this fixes a kernel crash that can be triggered from user space via AF_ALG(aead) -- simply use the libkcapi test application from [1] and update it to use rfc4106-gcm-aes. Using [1], the changes were tested using CAVS vectors to demonstrate that the crypto operation still delivers the right results. [1] http://www.chronox.de/libkcapi.html CC: Tadeusz Struk <tadeusz.struk@intel.com> Cc: stable@vger.kernel.org Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 947c6bf52c33..54f60ab41c63 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -1155,7 +1155,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
1155 src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); 1155 src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC);
1156 if (!src) 1156 if (!src)
1157 return -ENOMEM; 1157 return -ENOMEM;
1158 assoc = (src + req->cryptlen + auth_tag_len); 1158 assoc = (src + req->cryptlen);
1159 scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); 1159 scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0);
1160 scatterwalk_map_and_copy(assoc, req->assoc, 0, 1160 scatterwalk_map_and_copy(assoc, req->assoc, 0,
1161 req->assoclen, 0); 1161 req->assoclen, 0);
@@ -1180,7 +1180,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
1180 scatterwalk_done(&src_sg_walk, 0, 0); 1180 scatterwalk_done(&src_sg_walk, 0, 0);
1181 scatterwalk_done(&assoc_sg_walk, 0, 0); 1181 scatterwalk_done(&assoc_sg_walk, 0, 0);
1182 } else { 1182 } else {
1183 scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); 1183 scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1);
1184 kfree(src); 1184 kfree(src);
1185 } 1185 }
1186 return retval; 1186 return retval;