Devicetree
 help / color / mirror / Atom feed
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

  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