[PATCH v2 7/7] crypto: ti - Validate sg_nents_for_len() return value in DTHEv2 AEAD
From: T Pratham
Date: Thu Aug 27 2026 - 09:39:48 EST
sg_nents_for_len() returns -EINVAL if the supplied scatterlist is
shorter than the requested length.
Add explicit checks after each sg_nents_for_len() call in DTHEv2 AEAD
driver.
Fixes: 37b902c603042 ("crypto: ti - Add support for AES-GCM in DTHEv2 driver")
Signed-off-by: T Pratham <t-pratham@xxxxxx>
---
drivers/crypto/ti/dthev2-aes.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 99fce19de81d3..7e7a232f5ed10 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -627,6 +627,8 @@ static struct scatterlist *dthe_aead_prep_aad(struct scatterlist *sg,
return NULL;
aad_nents = sg_nents_for_len(sg, assoclen);
+ if (aad_nents < 0)
+ return ERR_PTR(aad_nents);
if (assoclen % AES_BLOCK_SIZE)
aad_nents++;
@@ -683,6 +685,10 @@ static struct scatterlist *dthe_aead_prep_crypt(struct scatterlist *sg,
goto dthe_aead_prep_crypt_split_err;
crypt_nents = sg_nents_for_len(out_sg[0], cryptlen);
+ if (crypt_nents < 0) {
+ err = crypt_nents;
+ goto dthe_aead_prep_crypt_mem_err;
+ }
if (cryptlen % AES_BLOCK_SIZE)
crypt_nents++;
@@ -741,6 +747,8 @@ static int dthe_aead_enc_get_tag(struct aead_request *req)
return ret;
nents = sg_nents_for_len(req->dst, req->cryptlen + req->assoclen + ctx->authsize);
+ if (nents < 0)
+ return nents;
sg_pcopy_from_buffer(req->dst, nents, tag, ctx->authsize,
req->assoclen + req->cryptlen);
@@ -761,6 +769,8 @@ static int dthe_aead_dec_verify_tag(struct aead_request *req)
return ret;
nents = sg_nents_for_len(req->src, req->assoclen + req->cryptlen);
+ if (nents < 0)
+ return nents;
sg_pcopy_to_buffer(req->src, nents, tag_in, ctx->authsize,
req->assoclen + req->cryptlen - ctx->authsize);
@@ -957,6 +967,10 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (assoclen != 0) {
/* Map AAD for TX only */
aad_nents = sg_nents_for_len(aad_sg, assoclen);
+ if (aad_nents < 0) {
+ ret = aad_nents;
+ goto aead_dma_map_aad_err;
+ }
aad_mapped_nents = dma_map_sg(tx_dev, aad_sg, aad_nents, aad_dir);
if (aad_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map AAD for TX\n");
@@ -978,6 +992,10 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (cryptlen != 0) {
/* Map ciphertext src for TX (BIDIRECTIONAL if in-place) */
src_nents = sg_nents_for_len(src, cryptlen);
+ if (src_nents < 0) {
+ ret = src_nents;
+ goto aead_dma_prep_aad_err;
+ }
src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
if (src_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext src for TX\n");
@@ -998,6 +1016,10 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
/* Map ciphertext dst for RX (only if separate dst) */
if (diff_dst) {
dst_nents = sg_nents_for_len(dst, cryptlen);
+ if (dst_nents < 0) {
+ ret = dst_nents;
+ goto aead_dma_prep_src_err;
+ }
dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
if (dst_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext dst for RX\n");
--
2.34.1