From nobody Tue Sep 29 08:26:40 2026 Received: from oss.cyber.gouv.fr (oss.cyber.gouv.fr [51.159.188.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D354C357A3E; Mon, 10 Aug 2026 15:40:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.159.188.251 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786376443; cv=none; b=dIKNpb51mmmDF4auQA8ZV5gfVXd4zi104qs17i68xjyZ6HDXKXSMur+RDerhDy/L7SScFP3Rgz55ZupvDxe+KpKfXjNTPbZMR2+Vv7MBsoPrTtsF190hUxdf3MF3a3dwVzcdfNtvCydTYpUB/+cJMx3qxzkOsLqtBdeyLmtrU9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786376443; c=relaxed/simple; bh=CPYYHQiFfTTpPJPyGQFKvPdzgOsZv7+YckMVDlGSqzY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=lU6u64YN84VkVBhGBXIHyCm6Wuslb2PtBey39gnVAP8MmbIFgTOs5C0xTeGAqsV9yBjGXlzNWwP+O26woPb9pdSCJlwIVi16JOPQ6Oc81kGOmVulEGhx9V3fThSbeFtN1PkujoRXQtor4U+siqwnHDq0F1nxotKTz1s0gdjV/hY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.cyber.gouv.fr; spf=pass smtp.mailfrom=oss.cyber.gouv.fr; dkim=pass (2048-bit key) header.d=oss.cyber.gouv.fr header.i=@oss.cyber.gouv.fr header.b=jHyGJUuj; arc=none smtp.client-ip=51.159.188.251 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.cyber.gouv.fr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.cyber.gouv.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oss.cyber.gouv.fr header.i=@oss.cyber.gouv.fr header.b="jHyGJUuj" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=oss.cyber.gouv.fr; s=default; h=Content-Transfer-Encoding:Content-Type: MIME-Version:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Hn3hhAhC5GGD9rNvx7O3kiOrCeNMaN93esUQBw7vIXU=; b=jHyGJUujOkcgGrqBzeNuJTcUzi WMrqTiARKhKmARned2iymPDBOVKGnl6GjaZf8E5oNFAWepkRb7c/Tq2jgPiwOKm4phwlR3ob3Qsom b5RWT9vT+c98bP/hR+P9MVhixyWr2+pFG3EszOUlL1Wuw59L06qU37YeZ2n+HnLMJWTzko6POn1Ih nXgk6vSzVOWYcEXrzBSvwk9AzyWgGlWqkqkx3fKTmuFkxKE2nhgAd+4ml/D3EuczEMJxFQlpPwd2q Z57G4IvL2SZd0UimVnbV+uUaOuiFZ5b5g8YGPpG1WWLBt6hj9/8nOQ4o5/qbjaa751f1p/sHiVi39 Y0Kzcjsw==; Received: from [151.115.150.205] (port=40820 helo=gepetto..) by pf-012.whm.fr-par.scw.cloud with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.99.5) (envelope-from ) id 1wtS7B-0000000Evsp-36F4; Mon, 10 Aug 2026 17:40:37 +0200 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Jean?= To: horia.geanta@nxp.com, pankaj.gupta@nxp.com, gaurav.jain@nxp.com, herbert@gondor.apana.org.au, davem@davemloft.net Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, =?UTF-8?q?J=C3=A9r=C3=A9my=20Jean?= Subject: [PATCH] crypto: caam - reject overlong RSA CRT parameters Date: Mon, 10 Aug 2026 15:40:24 +0000 Message-ID: <20260810154024.3178145-1-Jeremy.Jean@oss.cyber.gouv.fr> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - pf-012.whm.fr-par.scw.cloud X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - oss.cyber.gouv.fr X-Get-Message-Sender-Via: pf-012.whm.fr-par.scw.cloud: authenticated_id: jeremy.jean@oss.cyber.gouv.fr X-Authenticated-Sender: pf-012.whm.fr-par.scw.cloud: jeremy.jean@oss.cyber.gouv.fr X-Source: X-Source-Args: X-Source-Dir: 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. Fixes: 4a651b122adb ("crypto: caam - add support for RSA key form 3") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: J=C3=A9r=C3=A9my Jean --- drivers/crypto/caam/caampkc.c | 69 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index cb001aa1de66..2082adaae585 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c @@ -880,7 +880,7 @@ static void caam_rsa_free_key(struct caam_rsa_key *key) =20 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 **pt= r, 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; =20 - dst =3D kzalloc(dstlen, GFP_KERNEL); - if (!dst) - return NULL; + *dst =3D kzalloc(dstlen, GFP_KERNEL); + if (!*dst) + return -ENOMEM; =20 - memcpy(dst + (dstlen - nbytes), ptr, nbytes); + memcpy(*dst + (dstlen - nbytes), ptr, nbytes); =20 - return dst; + return 0; } =20 /** @@ -991,6 +991,7 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_c= tx *ctx, size_t p_sz =3D raw_key->p_sz; size_t q_sz =3D raw_key->q_sz; unsigned aligned_size; + int ret; =20 rsa_key->p =3D 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_rs= a_ctx *ctx, =20 rsa_key->q =3D caam_read_raw_data(raw_key->q, &q_sz); if (!rsa_key->q) - goto free_p; + return -ENOMEM; rsa_key->q_sz =3D q_sz; =20 aligned_size =3D ALIGN(raw_key->p_sz, dma_get_cache_alignment()); rsa_key->tmp1 =3D kzalloc(aligned_size, GFP_KERNEL); if (!rsa_key->tmp1) - goto free_q; + return -ENOMEM; =20 aligned_size =3D ALIGN(raw_key->q_sz, dma_get_cache_alignment()); rsa_key->tmp2 =3D kzalloc(aligned_size, GFP_KERNEL); if (!rsa_key->tmp2) - goto free_tmp1; + return -ENOMEM; =20 rsa_key->priv_form =3D FORM2; =20 - rsa_key->dp =3D caam_read_rsa_crt(raw_key->dp, raw_key->dp_sz, p_sz); - if (!rsa_key->dp) - goto free_tmp2; + ret =3D caam_read_rsa_crt(raw_key->dp, raw_key->dp_sz, p_sz, + &rsa_key->dp); + if (ret) + return ret; =20 - rsa_key->dq =3D caam_read_rsa_crt(raw_key->dq, raw_key->dq_sz, q_sz); - if (!rsa_key->dq) - goto free_dp; + ret =3D caam_read_rsa_crt(raw_key->dq, raw_key->dq_sz, q_sz, + &rsa_key->dq); + if (ret) + return ret; =20 - rsa_key->qinv =3D caam_read_rsa_crt(raw_key->qinv, raw_key->qinv_sz, - q_sz); - if (!rsa_key->qinv) - goto free_dq; + ret =3D caam_read_rsa_crt(raw_key->qinv, raw_key->qinv_sz, p_sz, + &rsa_key->qinv); + if (ret) + return ret; =20 rsa_key->priv_form =3D FORM3; =20 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; } =20 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_akciph= er *tfm, const void *key, if (ret) return ret; =20 + ret =3D -ENOMEM; + /* Copy key in DMA zone */ rsa_key->d =3D 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_akciph= er *tfm, const void *key, =20 err: caam_rsa_free_key(rsa_key); - return -ENOMEM; + return ret; } =20 static unsigned int caam_rsa_max_size(struct crypto_akcipher *tfm) --=20 2.47.3