Skip to contentSkip to conversation

crypto: rsassa-pkcs1 - Allocate the RSA buffer separately

PATCH New [email protected] 1 participant 1 message Nov 11

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 crypto: rsassa-pkcs1 - Allocate the RSA buffer separately

From: Efe Can Icoz <[email protected]>

rsassa_pkcs1_verify() allocates the akcipher request, its private context, and the RSA input/output buffer in a single allocation. The buffer starts immediately after the request context, whose size is not necessarily a multiple of ARCH_DMA_MINALIGN.

Although kmalloc() aligns the allocation itself, this does not guarantee suitable alignment of the interior buffer. On systems with non-coherent DMA, the buffer can therefore share cache lines with CPU-accessed request state. Updates to that state after DMA mapping can interfere with the device-written result during cache maintenance.

This is reproducible on i.MX7D with rsa-caam, whose request context is 48 bytes while the kernel DMA alignment is 64 bytes. CAAM reports successful completion, but the recovered output retains the original signature prefix and PKCS#1 verification fails. This prevents the shipped X.509 certificates and regulatory database signature from being verified.

Allocate the RSA buffer separately with kmemdup() so that it benefits from kmalloc's DMA alignment guarantees and does not share cache lines with the request context. Keep a separate pointer to the allocation base for sensitive cleanup, since verification may advance out_buf past the leading zero byte.

Fixes 1e562deacecc ("crypto: rsassa-pkcs1 - Migrate to sig_alg backend")

---
Tested on a custom board with i.MX7D and i.MX8QXP, running Linux 6.18.37 with:

     CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
     CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
     CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y

During diagnosis, the selected signature driver was pkcs1(rsa-caam,sha256), with a 256-byte RSA buffer and a 48-byte child request context.

Before the change, hardware completion returned success, but verification rejected the recovered output because it lacked the expected leading zero byte. Its prefix matched the input signature.

After the change, the sforshee and wens certificates load successfully and regulatory database signature verification succeeds.

The cache-line interference described above is supported by the allocation layout and the runtime comparison; the exact corruption sequence has not been directly traced.

 crypto/rsassa-pkcs1.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
crypto/rsassa-pkcs1.c +6 -4
index 39137476ce81..87243458eb5b 100644
@@ -237,13 +237,15 @@ static int rsassa_pkcs1_verify(struct crypto_sig *tfm,
 		return -EINVAL;
 
 	/* RFC 8017 sec 8.2.2 step 2 - RSA verification */
-	child_req = kmalloc(sizeof(*child_req) + child_reqsize + ctx->key_size,
-			    GFP_KERNEL);
+	child_req = kmalloc(sizeof(*child_req) + child_reqsize, GFP_KERNEL);
 	if (!child_req)
 		return -ENOMEM;
 
-	out_buf = (u8 *)(child_req + 1) + child_reqsize;
-	memcpy(out_buf, src, slen);
+	u8 *rsa_buf __free(kfree_sensitive) = kmemdup(src, slen, GFP_KERNEL);
+
+	if (!rsa_buf)
+		return -ENOMEM;
+	out_buf = rsa_buf;
 
 	crypto_init_wait(&cwait);
 	sg_init_one(&sg, out_buf, slen);
Signature · 1 line
2.43.0