The AEAD decryption operation requires the authentication tag to be present as part of the cipher text buffer. The added check verifies that the caller provides a cipher text buffer with at least the authentication tag.
As the cipher text is provided as a scatterlist, loop through the scatterlist until we know we have sufficient cipher text bytes to invoke the AEAD decryption operation. As the authentication tag is typically smaller or equal to one block of the cipher (except for authenc operations), it is expected that the while loop iterating through the scatterlist is traversed not more than once. Thus, the speed penalty should be marginal. Signed-off-by: Stephan Mueller <smuel...@chronox.de> --- include/linux/crypto.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 9c8776d..badc53b 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -24,6 +24,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/uaccess.h> +#include <linux/scatterlist.h> /* * Autoloaded crypto modules should only use a prefixed name to avoid allowing @@ -1412,7 +1413,18 @@ static inline int crypto_aead_encrypt(struct aead_request *req) */ static inline int crypto_aead_decrypt(struct aead_request *req) { - return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req); + struct scatterlist *sg = req->src; + unsigned int size = 0; + + /* ensure that the ciphertext at least contains the auth tag */ + while (sg) { + size += sg->length; + if (crypto_aead_authsize(crypto_aead_reqtfm(req)) <= size) + return crypto_aead_crt( + crypto_aead_reqtfm(req))->decrypt(req); + sg = sg_next(sg); + } + return -EINVAL; } /** -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/