crypto: caam - reject overlong RSA CRT parameters
Subsystems (3)
PATCH 1/1 crypto: caam - reject overlong RSA CRT parameters
caam_read_rsa_crt() right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime. rsa_parse_priv_key() only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one-byte p. dstlen - nbytes then underflows and memcpy() writes outside the allocation during set_priv_key(). KASAN reports a slab-out-of-bounds write in caam_read_rsa_crt().
Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.
Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
drivers/crypto/caam/caampkc.c +30 -39
@@ -880,7 +880,7 @@ static void caam_rsa_free_key(struct caam_rsa_key *key)static void caam_rsa_drop_leading_zeros (const u8 **ptr,size_t *nbytes) { -while (!**ptr && *nbytes) { +while (*nbytes && !**ptr) { (*ptr)++; (*nbytes)--; }
@@ -896,22 +896,22 @@ static void caam_rsa_drop_leading_zeros(const u8 **ptr, size_t *nbytes)* @ptr : pointer to {dP, dQ, qInv} CRT member * @nbytes: length in bytes of {dP, dQ, qInv} CRT member * @dstlen: length in bytes of corresponding p or q prime factor +* @dst : pointer to the zero-padded output buffer */ -static u8 *caam_read_rsa_crt (const u8 *ptr,size_t nbytes,size_t dstlen) +static int caam_read_rsa_crt (const u8 *ptr,size_t nbytes,size_t dstlen, +u8 **dst) { -u8 *dst; -caam_rsa_drop_leading_zeros (&ptr, &nbytes); -if (!nbytes) -return NULL ; +if (!nbytes || nbytes > dstlen) +return -EINVAL ; - dst =kzalloc (dstlen,GFP_KERNEL ); -if (!dst) -return NULL ; + *dst =kzalloc (dstlen,GFP_KERNEL ); +if (!*dst) +return -ENOMEM ; -memcpy (dst + (dstlen - nbytes), ptr, nbytes); +memcpy (*dst + (dstlen - nbytes), ptr, nbytes); -return dst; +return 0 ; }/**
@@ -991,6 +991,7 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,size_t p_sz = raw_key->p_sz;size_t q_sz = raw_key->q_sz;unsigned aligned_size; +int ret; rsa_key->p =caam_read_raw_data (raw_key->p, &p_sz);if (!rsa_key->p)
@@ -999,51 +1000,39 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, rsa_key->q =caam_read_raw_data (raw_key->q, &q_sz);if (!rsa_key->q) - goto free_p; +return -ENOMEM ; rsa_key->q_sz = q_sz; aligned_size =ALIGN (raw_key->p_sz,dma_get_cache_alignment ()); rsa_key->tmp1 =kzalloc (aligned_size,GFP_KERNEL );if (!rsa_key->tmp1) - goto free_q; +return -ENOMEM ; aligned_size =ALIGN (raw_key->q_sz,dma_get_cache_alignment ()); rsa_key->tmp2 =kzalloc (aligned_size,GFP_KERNEL );if (!rsa_key->tmp2) - goto free_tmp1; +return -ENOMEM ; rsa_key->priv_form =FORM2 ; - rsa_key->dp =caam_read_rsa_crt (raw_key->dp, raw_key->dp_sz, p_sz); -if (!rsa_key->dp) - goto free_tmp2; + ret =caam_read_rsa_crt (raw_key->dp, raw_key->dp_sz, p_sz, + &rsa_key->dp); +if (ret) +return ret; - rsa_key->dq =caam_read_rsa_crt (raw_key->dq, raw_key->dq_sz, q_sz); -if (!rsa_key->dq) - goto free_dp; + ret =caam_read_rsa_crt (raw_key->dq, raw_key->dq_sz, q_sz, + &rsa_key->dq); +if (ret) +return ret; - rsa_key->qinv =caam_read_rsa_crt (raw_key->qinv, raw_key->qinv_sz, - q_sz); -if (!rsa_key->qinv) - goto free_dq; + ret =caam_read_rsa_crt (raw_key->qinv, raw_key->qinv_sz, p_sz, + &rsa_key->qinv); +if (ret) +return ret; rsa_key->priv_form =FORM3 ;return 0 ; - -free_dq: -kfree_sensitive (rsa_key->dq); -free_dp: -kfree_sensitive (rsa_key->dp); -free_tmp2: -kfree_sensitive (rsa_key->tmp2); -free_tmp1: -kfree_sensitive (rsa_key->tmp1); -free_q: -kfree_sensitive (rsa_key->q); -free_p: -kfree_sensitive (rsa_key->p); -return -ENOMEM ; } static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
@@ -1061,6 +1050,8 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,if (ret)return ret; + ret = -ENOMEM ; +/* Copy key in DMA zone */ rsa_key->d =kmemdup (raw_key.d, raw_key.d_sz,GFP_KERNEL );if (!rsa_key->d)
@@ -1097,7 +1088,7 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, err:caam_rsa_free_key (rsa_key); -return -ENOMEM ; +return ret; }static unsigned int caam_rsa_max_size (struct crypto_akcipher *tfm)
Signature · 1 line
2.47.3
Herbert Xu
maintainerQuoted 16 lines · Jérémy Jean
caam_read_rsa_crt()right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime.rsa_parse_priv_key()only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one-byte p. dstlen - nbytes then underflows andmemcpy()writes outside the allocation duringset_priv_key(). KASAN reports a slab-out-of-bounds write incaam_read_rsa_crt().Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in
set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
Quoted 7 lines
Fixes 4a651b122adb ("crypto: caam - add support for RSA key form 3")Assisted-by LLMSigned-off-by Jérémy Jean <[email protected]>--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
Sahil, could you please review this patch?
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Herbert Xu
maintainerQuoted 25 lines · Herbert Xu
Quoted 16 lines · Jérémy Jean
caam_read_rsa_crt()right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime.rsa_parse_priv_key()only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one-byte p. dstlen - nbytes then underflows andmemcpy()writes outside the allocation duringset_priv_key(). KASAN reports a slab-out-of-bounds write incaam_read_rsa_crt().Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in
set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
Quoted 7 lines
Fixes 4a651b122adb ("crypto: caam - add support for RSA key form 3")Assisted-by LLMSigned-off-by Jérémy Jean <[email protected]>--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
Quoted 1 line
Sahil, could you please review this patch?
Hi Sahil:
It's been two weeks and you've provided no feedback.
If there isn't going to be timely feedback to patches on this driver then it will be removed.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Hi Herbert,
Sorry for the delay.
I just reviewed the patch and in process of reviewing other pending patches also.
Regards,
Sahil Malhotra
NXP Confidential
Quoted 11 lines
-----Original Message-----
From: Herbert Xu <[email protected]>
Sent: 26 October 2026 10:13
To: Jérémy Jean <[email protected]>
Cc: Horia Geanta <[email protected]>; Pankaj Gupta <[email protected]>; Sahil Malhotra <[email protected]>; David S. Miller <[email protected]>; [email protected]; linux- [email protected]; [email protected]
Subject: [EXT] Re: [REPOST PATCH] crypto: caam - reject overlong RSA CRT parameters
Quoted 1 line
Caution: This is an external email. Please take care when clicking links
or
Quoted 32 lines
opening attachments. When in doubt, report the message using the 'Report this email' button
Quoted 27 lines · Herbert Xu
Quoted 25 lines · Jérémy Jean
caam_read_rsa_crt()right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime.rsa_parse_priv_key()only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one-byte p. dstlen - nbytes then underflows andmemcpy()writes outside the allocation duringset_priv_key(). KASAN reports a slab-out-of-bounds write incaam_read_rsa_crt().Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in
set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
Fixes 4a651b122adb ("crypto: caam - add support for RSA key form3")
--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
Quoted 7 lines
Quoted 1 line
Sahil, could you please review this patch?
Hi Sahil:
It's been two weeks and you've provided no feedback.
If there isn't going to be timely feedback to patches on this driver then
it will be
Quoted 21 lines
removed.
Thanks,
--
Email: Herbert Xu <[email protected]> Home Page:
https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgondo
r.apana.org.au%2F~herbert%2F&data=05%7C02%7Csahil.malhotra%40nxp.c om%7C8ae2201e6d304d4bca0708df331b9897%7C686ea1d3bc2b4c6fa92c d99c5c301635%7C0%7C0%7C639285865952622472%7CUnknown%7CTW FpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXa W4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=YP2 HDGxtmPHRqtU3%2F6lFqhjJwOUa8Czp6IV3QJI%2FaYc%3D&reserved=0 PGP Key:
https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgondo
r.apana.org.au%2F~herbert%2Fpubkey.txt&data=05%7C02%7Csahil.malhotr a%40nxp.com%7C8ae2201e6d304d4bca0708df331b9897%7C686ea1d3bc 2b4c6fa92cd99c5c301635%7C0%7C0%7C639285865952656160%7CUnkn own%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwM CIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C &sdata=9N5IuUc0ReEfh37OUvvVqfWMs1NJRxS6yDd32NmUu84%3D&reser ved=0
Hi Jeremy,
Sorry for the delayed response.
I am ok with this patch.
Regards,
Sahil Malhotra
NXP Confidential
Quoted 187 lines
-----Original Message-----
From: Jérémy Jean <[email protected]>
Sent: 08 October 2026 15:06
To: Horia Geanta <[email protected]>; Pankaj Gupta <[email protected]>; Sahil Malhotra <[email protected]>; Herbert Xu <[email protected]>; David S. Miller <[email protected]>; [email protected]; linux- [email protected]
Cc: Jérémy Jean <[email protected]>; [email protected]
Subject: [EXT] [REPOST PATCH] crypto: caam - reject overlong RSA CRT parametersCaution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
caam_read_rsa_crt()right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime.rsa_parse_priv_key()only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one- byte p. dstlen - nbytes then underflows andmemcpy()writes outside the allocation duringset_priv_key(). KASAN reports a slab-out-of-bounds write incaam_read_rsa_crt().Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in
set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
Fixes 4a651b122adb ("crypto: caam - add support for RSA key form 3")Assisted-by LLMSigned-off-by Jérémy Jean <[email protected]>--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)drivers/crypto/caam/caampkc.c +11
-11@@ -880,7 +880,7 @@ static void caam_rsa_free_key(struct caam_rsa_key *key)static void caam_rsa_drop_leading_zeros (const u8 **ptr,size_t *nbytes) { -while (!**ptr && *nbytes) { +while (*nbytes && !**ptr) { (*ptr)++; (*nbytes)--; }@@ -896,22 +896,22 @@ static void caam_rsa_drop_leading_zeros(const u8**ptr, size_t *nbytes) * @ptr : pointer to {dP, dQ, qInv} CRT member * @nbytes: length in bytes of {dP, dQ, qInv} CRT member * @dstlen: length in bytes of corresponding p or q prime factor +* @dst : pointer to the zero-padded output buffer */ -static u8 *caam_read_rsa_crt (const u8 *ptr,size_t nbytes,size_t dstlen) +static int caam_read_rsa_crt (const u8 *ptr,size_t nbytes,size_t dstlen, +u8 **dst) { -u8 *dst; -caam_rsa_drop_leading_zeros (&ptr, &nbytes); -if (!nbytes) -return NULL ; +if (!nbytes || nbytes > dstlen) +return -EINVAL ; - dst =kzalloc (dstlen,GFP_KERNEL ); -if (!dst) -return NULL ; + *dst =kzalloc (dstlen,GFP_KERNEL ); +if (!*dst) +return -ENOMEM ; -memcpy (dst + (dstlen - nbytes), ptr, nbytes); +memcpy (*dst + (dstlen - nbytes), ptr, nbytes); -return dst; +return 0 ; }/**
drivers/crypto/caam/caampkc.c +1
-0@@ -991,6 +991,7 @@ static int caam_rsa_set_priv_key_form(structcaam_rsa_ctx *ctx, size_t p_sz = raw_key->p_sz;size_t q_sz = raw_key->q_sz;unsigned aligned_size; +int ret; rsa_key->p =caam_read_raw_data (raw_key->p, &p_sz);if (!rsa_key->p)drivers/crypto/caam/caampkc.c +15
-27@@ -999,51 +1000,39 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, rsa_key->q =caam_read_raw_data (raw_key->q, &q_sz);if (!rsa_key->q) - goto free_p; +return -ENOMEM ; rsa_key->q_sz = q_sz; aligned_size =ALIGN (raw_key->p_sz,dma_get_cache_alignment ()); rsa_key->tmp1 =kzalloc (aligned_size,GFP_KERNEL );if (!rsa_key->tmp1) - goto free_q; +return -ENOMEM ; aligned_size =ALIGN (raw_key->q_sz,dma_get_cache_alignment ()); rsa_key->tmp2 =kzalloc (aligned_size,GFP_KERNEL );if (!rsa_key->tmp2) - goto free_tmp1; +return -ENOMEM ; rsa_key->priv_form =FORM2 ; - rsa_key->dp =caam_read_rsa_crt (raw_key->dp, raw_key->dp_sz, p_sz); -if (!rsa_key->dp) - goto free_tmp2; + ret =caam_read_rsa_crt (raw_key->dp, raw_key->dp_sz, p_sz, + &rsa_key->dp); +if (ret) +return ret; - rsa_key->dq =caam_read_rsa_crt (raw_key->dq, raw_key->dq_sz, q_sz); -if (!rsa_key->dq) - goto free_dp; + ret =caam_read_rsa_crt (raw_key->dq, raw_key->dq_sz, q_sz, + &rsa_key->dq); +if (ret) +return ret; - rsa_key->qinv =caam_read_rsa_crt (raw_key->qinv, raw_key->qinv_sz, - q_sz); -if (!rsa_key->qinv) - goto free_dq; + ret =caam_read_rsa_crt (raw_key->qinv, raw_key->qinv_sz, p_sz, + &rsa_key->qinv); +if (ret) +return ret; rsa_key->priv_form =FORM3 ;return 0 ; - -free_dq: -kfree_sensitive (rsa_key->dq); -free_dp: -kfree_sensitive (rsa_key->dp); -free_tmp2: -kfree_sensitive (rsa_key->tmp2); -free_tmp1: -kfree_sensitive (rsa_key->tmp1); -free_q: -kfree_sensitive (rsa_key->q); -free_p: -kfree_sensitive (rsa_key->p); -return -ENOMEM ; }static int caam_rsa_set_priv_key(struct
crypto_akcipher*tfm, const void *key,drivers/crypto/caam/caampkc.c +2
-0@@ -1061,6 +1050,8 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, if (ret) return ret; + ret = -ENOMEM ; +/* Copy key in DMA zone */ rsa_key->d =kmemdup (raw_key.d, raw_key.d_sz,GFP_KERNEL );if (!rsa_key->d)drivers/crypto/caam/caampkc.c +1
-1@@ -1097,7 +1088,7 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, err:caam_rsa_free_key (rsa_key ); -return -ENOMEM ; +return ret; }static unsigned int
caam_rsa_max_size(struct crypto_akcipher *tfm)
--
2.47.3
Herbert Xu
maintainerQuoted 16 lines · Jérémy Jean
caam_read_rsa_crt()right-aligns dP, dQ, and qInv in buffers sized from the corresponding prime.rsa_parse_priv_key()only bounds these integers against n, so a malformed key can provide, for example, a two-byte dP with a one-byte p. dstlen - nbytes then underflows andmemcpy()writes outside the allocation duringset_priv_key(). KASAN reports a slab-out-of-bounds write incaam_read_rsa_crt().Reject empty or overlong CRT parameters after stripping leading zeros. qInv is consumed by CAAM as a p-sized value, so size it from p rather than q to match the DMA mapping in
set_rsa_priv_f3_pdb(). Let the top-level key cleanup handle partial form-3 allocations and return the specific error to the caller.Also test nbytes before dereferencing it while stripping zeros, so an all-zero integer does not read one byte beyond its input.
Quoted 7 lines
Fixes 4a651b122adb ("crypto: caam - add support for RSA key form 3")Assisted-by LLMSigned-off-by Jérémy Jean <[email protected]>--- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
Patch applied. Thanks.
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt