From: sashiko-bot@kernel.org
To: "Saravanakrishnan Krishnamoorthy" <skrishnamoorthy@rambus.com>
Cc: robh@kernel.org, devicetree@vger.kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v2 16/19] crypto: cmh - add SLH-DSA/LMS/XMSS (HCQ)
Date: Thu, 09 Jul 2026 21:02:18 +0000 [thread overview]
Message-ID: <20260709210220.8832D1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260709203037.1884436-17-skrishnamoorthy@rambus.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] The SLH-DSA, LMS, and XMSS verification and signing functions unconditionally unmap and free DMA-mapped buffers on timeout, leading to potential use-after-free and memory corruption by the hardware.
- [High] LMS and XMSS algorithms fail to implement the `.max_size` callback in their `struct sig_alg` definitions.
- [High] SLH-DSA, LMS, and XMSS algorithms fail to implement the `.digest_size` callback in their `struct sig_alg` definitions.
- [Medium] The PQC signature algorithms incorrectly reject 0-length messages, preventing empty message signing and verification.
--
--- Patch [16]: [PATCH v2 16/19] crypto: cmh - add SLH-DSA/LMS/XMSS (HCQ) ---
commit aa5a6d3ad22af27c0421ed22c5126da35c7caa5b
Author: Alex Ousherovitch <aousherovitch@rambus.com>
crypto: cmh - add SLH-DSA/LMS/XMSS (HCQ)
Register SLH-DSA, LMS, LMS-HSS, XMSS, and XMSS-MT algorithms
using the CMH HCQ core (core ID 0x08). SLH-DSA is registered as a
sig algorithm with sign and verify support.
> --- a/drivers/crypto/cmh/cmh_pqc_slhdsa.c
> +++ b/drivers/crypto/cmh/cmh_pqc_slhdsa.c
> @@ -54,23 +54,342 @@ static inline struct cmh_slhdsa_tfm_ctx *cmh_slhdsa_ctx(struct crypto_sig *tfm)
> static int cmh_slhdsa_sign(struct crypto_sig *tfm,
> const void *src, unsigned int slen,
> void *dst, unsigned int dlen)
> {
[ ... ]
> if (ctx->key.mode == CMH_KEY_NONE)
> return -EINVAL;
> if (dlen < sig_sz)
> return -EINVAL;
> if (!slen || slen > SLHDSA_MAX_MSG_LEN)
> return -EINVAL;
[Severity: Medium]
Does this incorrectly reject valid 0-length messages? Empty strings are valid
inputs for SLH-DSA, but this returns -EINVAL when slen is 0. Is this intended
to prevent a ZERO_SIZE_PTR allocation from kmemdup()?
> m_buf = kmemdup(src, slen, GFP_KERNEL);
[ ... ]
> ret = cmh_tm_submit_sync_tmo(vcq, vcq_count, 1, d.mbx_idx,
> cmh_tm_slow_op_timeout_jiffies());
>
> if (!ret) {
> /* Sync bounce buffer so CPU sees the DMA-written signature */
> cmh_dma_sync_for_cpu(sig_dma, sig_sz, DMA_FROM_DEVICE);
> memcpy(dst, sig_buf, sig_sz);
> ret = sig_sz;
> }
>
> out_unmap:
> if (sk_buf) {
> if (!cmh_dma_map_error(sk_dma))
> cmh_dma_unmap_single(sk_dma, sk_sz, DMA_TO_DEVICE);
> kfree_sensitive(sk_buf);
> }
> if (!cmh_dma_map_error(sig_dma))
> cmh_dma_unmap_single(sig_dma, sig_sz, DMA_FROM_DEVICE);
> if (!cmh_dma_map_error(m_dma))
> cmh_dma_unmap_single(m_dma, slen, DMA_TO_DEVICE);
>
> out_free:
> kfree(sig_buf);
> kfree(m_buf);
> return ret;
> }
[Severity: Critical]
Are these buffers safely unmapped and freed if the transaction times out?
If cmh_tm_submit_sync_tmo() returns -ETIMEDOUT, the documentation in the TM
subsystem notes that the hardware abort might fail, leaving the hardware actively
writing to the DMA buffers. Because kfree() is called unconditionally on
sk_buf, sig_buf, and m_buf here, could this allow the hardware to corrupt
whatever data is subsequently allocated in those physical pages?
> @@ -165,22 +165,58 @@ static int cmh_slhdsa_verify(struct crypto_sig *tfm,
> const void *src, unsigned int slen,
> const void *digest, unsigned int dlen)
> {
[ ... ]
> if (!dlen || dlen > SLHDSA_MAX_MSG_LEN)
> return -EINVAL;
[Severity: Medium]
Similar to the sign function, does this prevent verifying 0-length messages
which are otherwise mathematically valid for SLH-DSA?
> sig_buf = kmemdup(src, slen, GFP_KERNEL);
[ ... ]
> /* SLH-DSA verify recomputes hyper-tree hashes -- inherently slow */
> ret = cmh_tm_submit_sync_tmo(vcq, HCQ_VCQ_CMDS_MIN, 1, d.mbx_idx,
> cmh_tm_slow_op_timeout_jiffies());
>
> out_unmap:
> if (!cmh_dma_map_error(pk_dma))
> cmh_dma_unmap_single(pk_dma, pk_sz, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(m_dma))
> cmh_dma_unmap_single(m_dma, dlen, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(sig_dma))
> cmh_dma_unmap_single(sig_dma, sig_sz, DMA_TO_DEVICE);
>
> out_free:
> kfree(pk_buf);
> kfree(m_buf);
> kfree(sig_buf);
> return ret;
> }
[Severity: Critical]
Are pk_buf, m_buf, and sig_buf safe to free here on a timeout?
For the same reasons as above, if cmh_tm_submit_sync_tmo() returns -ETIMEDOUT,
does unconditionally freeing these buffers risk memory corruption by the
hardware?
> @@ -313,24 +313,64 @@ SLHDSA_INIT(HCQ_SLHDSA_SHA2_256F)
> #define SLHDSA_ALG(name, drv, ps_val) { \
> .sign = cmh_slhdsa_sign, \
> .verify = cmh_slhdsa_verify, \
> .set_pub_key = cmh_slhdsa_set_pub_key, \
> .set_priv_key = cmh_slhdsa_set_priv_key, \
> .key_size = cmh_slhdsa_key_size, \
> .max_size = cmh_slhdsa_max_size, \
> .init = cmh_slhdsa_init_##ps_val, \
> .exit = cmh_slhdsa_exit, \
> .base = { \
[Severity: High]
Is the .digest_size callback missing from this algorithm definition?
When .digest_size is not provided, crypto_sig_digestsize() falls back to the
public key size. For SLH-DSA, could this cause valid sign/verify operations to
be prematurely rejected with -EINVAL by the asymmetric_keys subsystem if the
payload is larger than the small public key?
> --- a/drivers/crypto/cmh/cmh_pqc_lms.c
> +++ b/drivers/crypto/cmh/cmh_pqc_lms.c
> @@ -49,20 +49,60 @@ static int cmh_lms_verify(struct crypto_sig *tfm,
> const void *src, unsigned int slen,
> const void *digest, unsigned int dlen)
> {
[ ... ]
> if (!dlen || dlen > LMS_MAX_MSG_LEN)
> return -EINVAL;
[Severity: Medium]
Does this incorrectly reject valid 0-length messages for LMS?
> sig_buf = kmemdup(src, slen, GFP_KERNEL);
[ ... ]
> /* LMS verify traverses Merkle hash chains -- inherently slow */
> ret = cmh_tm_submit_sync_tmo(vcq, LMS_VCQ_CMDS, 1, d.mbx_idx,
> cmh_tm_slow_op_timeout_jiffies());
>
> out_unmap:
> if (!cmh_dma_map_error(pk_dma))
> cmh_dma_unmap_single(pk_dma, ctx->pub_key_len, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(m_dma))
> cmh_dma_unmap_single(m_dma, dlen, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(sig_dma))
> cmh_dma_unmap_single(sig_dma, slen, DMA_TO_DEVICE);
>
> out_free:
> kfree(pk_buf);
> kfree(m_buf);
> kfree(sig_buf);
> return ret;
> }
[Severity: Critical]
Does unconditionally freeing pk_buf, m_buf, and sig_buf on a timeout risk
use-after-free and memory corruption by the hardware?
> @@ -164,36 +164,36 @@ static void cmh_lms_exit(struct crypto_sig *tfm)
> static struct sig_alg cmh_lms_algs[] = {
> {
> .verify = cmh_lms_verify,
> .set_pub_key = cmh_lms_set_pub_key,
> .key_size = cmh_lms_key_size,
> .init = cmh_lms_init,
> .exit = cmh_lms_exit,
> .base = {
[Severity: High]
Are both the .max_size and .digest_size callbacks missing here?
Without .max_size, crypto_sig_maxsize() defaults to the public key size.
Because LMS signatures are much larger than their public keys, won't this
cause standard verification requests to fail with -EINVAL?
Similarly, missing .digest_size may cause operations to be rejected when the
message size exceeds the public key size.
> --- a/drivers/crypto/cmh/cmh_pqc_xmss.c
> +++ b/drivers/crypto/cmh/cmh_pqc_xmss.c
> @@ -49,20 +49,60 @@ static int cmh_xmss_verify(struct crypto_sig *tfm,
> const void *src, unsigned int slen,
> const void *digest, unsigned int dlen)
> {
[ ... ]
> if (!dlen || dlen > XMSS_MAX_MSG_LEN)
> return -EINVAL;
[Severity: Medium]
Does this incorrectly reject valid 0-length messages for XMSS?
> sig_buf = kmemdup(src, slen, GFP_KERNEL);
[ ... ]
> /* XMSS verify traverses Merkle hash chains -- inherently slow */
> ret = cmh_tm_submit_sync_tmo(vcq, XMSS_VCQ_CMDS, 1, d.mbx_idx,
> cmh_tm_slow_op_timeout_jiffies());
>
> out_unmap:
> if (!cmh_dma_map_error(pk_dma))
> cmh_dma_unmap_single(pk_dma, ctx->pub_key_len, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(m_dma))
> cmh_dma_unmap_single(m_dma, dlen, DMA_TO_DEVICE);
> if (!cmh_dma_map_error(sig_dma))
> cmh_dma_unmap_single(sig_dma, slen, DMA_TO_DEVICE);
>
> out_free:
> kfree(pk_buf);
> kfree(m_buf);
> kfree(sig_buf);
> return ret;
> }
[Severity: Critical]
Does unconditionally freeing pk_buf, m_buf, and sig_buf on a timeout risk
use-after-free and memory corruption by the hardware?
> @@ -164,36 +164,36 @@ static void cmh_xmss_exit(struct crypto_sig *tfm)
> static struct sig_alg cmh_xmss_algs[] = {
> {
> .verify = cmh_xmss_verify,
> .set_pub_key = cmh_xmss_set_pub_key,
> .key_size = cmh_xmss_key_size,
> .init = cmh_xmss_init,
> .exit = cmh_xmss_exit,
> .base = {
[Severity: High]
Are both the .max_size and .digest_size callbacks missing here?
As with LMS, missing .max_size means crypto_sig_maxsize() defaults to the
public key size, preventing validation of XMSS signatures because they are
larger than their public keys. Missing .digest_size may also break validation
for any payload larger than the public key.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260709203037.1884436-1-skrishnamoorthy@rambus.com?part=16
next prev parent reply other threads:[~2026-07-09 21:02 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 20:30 [PATCH v2 00/19] crypto: cmh - add CRI CryptoManager Hub driver Saravanakrishnan Krishnamoorthy
2026-07-09 20:30 ` [PATCH v2 01/19] dt-bindings: crypto: add Rambus CryptoManager Hub Saravanakrishnan Krishnamoorthy
2026-07-09 20:38 ` sashiko-bot
2026-07-10 8:58 ` Conor Dooley
2026-07-10 23:14 ` Ousherovitch, Alex
2026-07-09 20:30 ` [PATCH v2 02/19] crypto: cmh - add core platform driver Saravanakrishnan Krishnamoorthy
2026-07-09 20:49 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 03/19] crypto: cmh - add key provisioning and management Saravanakrishnan Krishnamoorthy
2026-07-09 20:49 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 04/19] crypto: cmh - add SHA-2/SHA-3/SHAKE ahash Saravanakrishnan Krishnamoorthy
2026-07-09 20:45 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 05/19] crypto: cmh - add HMAC ahash Saravanakrishnan Krishnamoorthy
2026-07-09 20:42 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 06/19] crypto: cmh - add CSHAKE/KMAC ahash Saravanakrishnan Krishnamoorthy
2026-07-09 20:47 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 07/19] crypto: cmh - add SM3 ahash Saravanakrishnan Krishnamoorthy
2026-07-09 20:47 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 08/19] crypto: cmh - add AES skcipher/aead/cmac Saravanakrishnan Krishnamoorthy
2026-07-09 20:47 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 09/19] crypto: cmh - add SM4 skcipher/aead/cmac/xcbc Saravanakrishnan Krishnamoorthy
2026-07-09 20:49 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 10/19] crypto: cmh - add ChaCha20-Poly1305 Saravanakrishnan Krishnamoorthy
2026-07-09 20:46 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 11/19] crypto: cmh - add DRBG hwrng Saravanakrishnan Krishnamoorthy
2026-07-09 20:54 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 12/19] crypto: cmh - add RSA akcipher Saravanakrishnan Krishnamoorthy
2026-07-09 20:57 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 13/19] crypto: cmh - add ECDSA/SM2 sig Saravanakrishnan Krishnamoorthy
2026-07-09 21:04 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 14/19] crypto: cmh - add ECDH/X25519 kpp Saravanakrishnan Krishnamoorthy
2026-07-09 21:08 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 15/19] crypto: cmh - add ML-KEM/ML-DSA (QSE) Saravanakrishnan Krishnamoorthy
2026-07-09 21:03 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 16/19] crypto: cmh - add SLH-DSA/LMS/XMSS (HCQ) Saravanakrishnan Krishnamoorthy
2026-07-09 21:02 ` sashiko-bot [this message]
2026-07-09 20:30 ` [PATCH v2 17/19] Documentation: ioctl: add CMH ioctl documentation and register 'J' Saravanakrishnan Krishnamoorthy
2026-07-09 20:54 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 18/19] selftests: crypto: cmh - add kselftest for management ioctl Saravanakrishnan Krishnamoorthy
2026-07-09 20:54 ` sashiko-bot
2026-07-09 20:30 ` [PATCH v2 19/19] MAINTAINERS: add Rambus CryptoManager Hub (CMH) Saravanakrishnan Krishnamoorthy
2026-07-10 1:04 ` Randy Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260709210220.8832D1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=skrishnamoorthy@rambus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox