From: David Howells <dhowells@redhat.com>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: David Howells <dhowells@redhat.com>,
Eric Biggers <ebiggers@kernel.org>,
Luis Chamberlain <mcgrof@kernel.org>,
Petr Pavlu <petr.pavlu@suse.com>,
Daniel Gomez <da.gomez@kernel.org>,
Sami Tolvanen <samitolvanen@google.com>,
"Jason A . Donenfeld" <Jason@zx2c4.com>,
Ard Biesheuvel <ardb@kernel.org>,
Stephan Mueller <smueller@chronox.de>,
Lukas Wunner <lukas@wunner.de>,
Ignat Korchagin <ignat@cloudflare.com>,
linux-crypto@vger.kernel.org, keyrings@vger.kernel.org,
linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v10 6/8] pkcs7: Allow the signing algo to calculate the digest itself
Date: Thu, 20 Nov 2025 10:44:33 +0000 [thread overview]
Message-ID: <20251120104439.2620205-7-dhowells@redhat.com> (raw)
In-Reply-To: <20251120104439.2620205-1-dhowells@redhat.com>
The ML-DSA public key algorithm really wants to calculate the message
digest itself, rather than having the digest precalculated and fed to it
separately as RSA does[*]. The kernel's PKCS#7 parser, however, is
designed around the latter approach.
[*] ML-DSA does allow for an "external mu", but CMS doesn't yet have that
standardised.
Fix this by noting in the public_key_signature struct when the signing
algorithm is going to want this and then, rather than doing the digest of
the authenticatedAttributes ourselves and overwriting the sig->digest with
that, replace sig->digest with a copy of the contents of the
authenticatedAttributes section and adjust the digest length to match.
This will then be fed to the public key algorithm as normal which can do
what it wants with the data.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
---
crypto/asymmetric_keys/pkcs7_parser.c | 4 +--
crypto/asymmetric_keys/pkcs7_verify.c | 48 ++++++++++++++++++---------
include/crypto/public_key.h | 1 +
3 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 423d13c47545..3cdbab3b9f50 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -599,8 +599,8 @@ int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
}
/* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
- sinfo->authattrs = value - (hdrlen - 1);
- sinfo->authattrs_len = vlen + (hdrlen - 1);
+ sinfo->authattrs = value - hdrlen;
+ sinfo->authattrs_len = vlen + hdrlen;
return 0;
}
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 6d6475e3a9bf..0f9f515b784d 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -70,8 +70,6 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
* digest we just calculated.
*/
if (sinfo->authattrs) {
- u8 tag;
-
if (!sinfo->msgdigest) {
pr_warn("Sig %u: No messageDigest\n", sinfo->index);
ret = -EKEYREJECTED;
@@ -97,20 +95,40 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
* as the contents of the digest instead. Note that we need to
* convert the attributes from a CONT.0 into a SET before we
* hash it.
+ *
+ * However, for certain algorithms, such as ML-DSA, the digest
+ * is integrated into the signing algorithm. In such a case,
+ * we copy the authattrs, modifying the tag type, and set that
+ * as the digest.
*/
- memset(sig->digest, 0, sig->digest_size);
-
- ret = crypto_shash_init(desc);
- if (ret < 0)
- goto error;
- tag = ASN1_CONS_BIT | ASN1_SET;
- ret = crypto_shash_update(desc, &tag, 1);
- if (ret < 0)
- goto error;
- ret = crypto_shash_finup(desc, sinfo->authattrs,
- sinfo->authattrs_len, sig->digest);
- if (ret < 0)
- goto error;
+ if (sig->algo_does_hash) {
+ kfree(sig->digest);
+
+ ret = -ENOMEM;
+ sig->digest = kmalloc(umax(sinfo->authattrs_len, sig->digest_size),
+ GFP_KERNEL);
+ if (!sig->digest)
+ goto error_no_desc;
+
+ sig->digest_size = sinfo->authattrs_len;
+ memcpy(sig->digest, sinfo->authattrs, sinfo->authattrs_len);
+ ((u8 *)sig->digest)[0] = ASN1_CONS_BIT | ASN1_SET;
+ ret = 0;
+ } else {
+ u8 tag = ASN1_CONS_BIT | ASN1_SET;
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error;
+ ret = crypto_shash_update(desc, &tag, 1);
+ if (ret < 0)
+ goto error;
+ ret = crypto_shash_finup(desc, sinfo->authattrs + 1,
+ sinfo->authattrs_len - 1,
+ sig->digest);
+ if (ret < 0)
+ goto error;
+ }
pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
}
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 81098e00c08f..e4ec8003a3a4 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -46,6 +46,7 @@ struct public_key_signature {
u8 *digest;
u32 s_size; /* Number of bytes in signature */
u32 digest_size; /* Number of bytes in digest */
+ bool algo_does_hash; /* Public key algo does its own hashing */
const char *pkey_algo;
const char *hash_algo;
const char *encoding;
next prev parent reply other threads:[~2025-11-20 10:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-20 10:44 [PATCH v10 0/8] lib/crypto: Add ML-DSA signing [WIP] David Howells
2025-11-20 10:44 ` [PATCH v10 1/8] lib/crypto: Add ML-DSA verification support David Howells
2025-11-20 10:44 ` [PATCH v10 2/8] lib/crypto: tests: Add KUnit tests for ML-DSA David Howells
2025-11-20 10:44 ` [PATCH v10 3/8] lib/crypto: tests: Add ML-DSA-65 test cases David Howells
2025-11-20 10:44 ` [PATCH v10 4/8] lib/crypto: tests: Add ML-DSA-87 " David Howells
2025-11-20 10:44 ` [PATCH v10 5/8] crypto: Add ML-DSA crypto_sig support David Howells
2025-11-20 10:44 ` David Howells [this message]
2025-11-20 10:44 ` [PATCH v10 7/8] pkcs7, x509: Add ML-DSA support David Howells
2025-11-20 10:44 ` [PATCH v10 8/8] modsign: Enable ML-DSA module signing David Howells
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=20251120104439.2620205-7-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=Jason@zx2c4.com \
--cc=ardb@kernel.org \
--cc=da.gomez@kernel.org \
--cc=ebiggers@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=ignat@cloudflare.com \
--cc=keyrings@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=mcgrof@kernel.org \
--cc=petr.pavlu@suse.com \
--cc=samitolvanen@google.com \
--cc=smueller@chronox.de \
/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;
as well as URLs for NNTP newsgroup(s).