On Mon, Jan 05, 2026 at 03:21:28PM +0000, David Howells wrote:
> Add support for ML-DSA keys and signatures to the PKCS#7 and X.509
> implementations.
>
> Signed-off-by: David Howells <[email protected]>
> cc: Lukas Wunner <[email protected]>
> cc: Ignat Korchagin <[email protected]>
> cc: Stephan Mueller <[email protected]>
> cc: Eric Biggers <[email protected]>
> cc: Herbert Xu <[email protected]>
> cc: [email protected]
> cc: [email protected]
> ---
> crypto/asymmetric_keys/pkcs7_parser.c | 15 ++++++++++++++
> crypto/asymmetric_keys/public_key.c | 7 +++++++
> crypto/asymmetric_keys/x509_cert_parser.c | 24 +++++++++++++++++++++++
> include/linux/oid_registry.h | 5 +++++
> 4 files changed, 51 insertions(+)
This "PKCS#7" (really CMS -- the kernel misleadingly uses the old name)
stuff is really hard to understand. I'm trying to understand what
message you're actually passing to mldsa_verify(). That's kind of the
whole point, after all.
The message comes from the byte array public_key_signature::digest
(which is misleadingly named, as it's not always a digest). In turn,
that comes from the following:
1.) If the CMS object doesn't include signed attributes, then it's a
digest of the real message the caller provided.
2.) If the CMS object includes signed attributes, then the message is
the signed attributes as a byte array. The signed attributes are
required to include a message digest attribute whose value matches a
digest of the real message the caller provided.
In either (1) or (2), the digest algorithm used comes from the CMS
object itself, from SignerInfo::digestAlgorithm. The kernel allows
SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SM3, Streebog-256,
Streebog-512, SHA3-256, SHA3-384, and SHA3-512.
So, a couple issues. First, case (1) isn't actually compatible with
RFC 9882 (https://datatracker.ietf.org/doc/rfc9882/) which is the
specification for ML-DSA support in CMS. RFC 9882 is clear that if
there are no signed attributes, then the ML-DSA signature is computed
directly over the signed-data, not over a digest of it.
That needs to either be implemented correctly, or not at all. (If only
(2) is actually needed, then "not at all" probably would be preferable.)
Second, because the digest algorithm comes from the untrusted signature
object and the kernel is allowing different many digest algorithms,
attackers are free to search for preimages across algorithms. For
example, if an attacker can find a Streebog-512 digest that matches a
particular SHA-512 digest that was used in a valid signature, they could
forge signatures. This would only require a weakness in Streebog-512.
While the root cause of this seems to be a flaw in CMS itself, it can be
mitigated by more strictly limiting the allowed digest algorithms. The
kernel already does this for the existing signature algorithms.
For simplicity and to avoid this issue entirely, I suggest just allowing
SHA-512 only. That's the only one that RFC 9882 says MUST be supported
with ML-DSA.
- Eric