Skip to content

Commit 0ad9a71

Browse files
committed
modsign: Enable ML-DSA module signing
Allow ML-DSA module signing to be enabled. Note that OpenSSL's CMS_*() function suite does not, as of OpenSSL-3.6, support the use of CMS_NOATTR with ML-DSA, so the prohibition against using signedAttrs with module signing has to be removed. The selected digest then applies only to the algorithm used to calculate the digest stored in the messageDigest attribute. The OpenSSL development branch has patches applied that fix this[1], but it appears that that will only be available in OpenSSL-4. [1] openssl/openssl#28923 sign-file won't set CMS_NOATTR if openssl is earlier than v4, resulting in the use of signed attributes. The ML-DSA algorithm takes the raw data to be signed without regard to what digest algorithm is specified in the CMS message. The CMS specified digest algorithm is ignored unless signedAttrs are used; in such a case, only SHA512 is permitted. Signed-off-by: David Howells <dhowells@redhat.com> cc: Jarkko Sakkinen <jarkko@kernel.org> cc: Eric Biggers <ebiggers@kernel.org> cc: Lukas Wunner <lukas@wunner.de> cc: Ignat Korchagin <ignat@cloudflare.com> cc: Stephan Mueller <smueller@chronox.de> cc: Herbert Xu <herbert@gondor.apana.org.au> cc: keyrings@vger.kernel.org cc: linux-crypto@vger.kernel.org
1 parent 8bbdeb7 commit 0ad9a71

4 files changed

Lines changed: 82 additions & 16 deletions

File tree

Documentation/admin-guide/module-signing.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ trusted userspace bits.
2828

2929
This facility uses X.509 ITU-T standard certificates to encode the public keys
3030
involved. The signatures are not themselves encoded in any industrial standard
31-
type. The built-in facility currently only supports the RSA & NIST P-384 ECDSA
32-
public key signing standard (though it is pluggable and permits others to be
33-
used). The possible hash algorithms that can be used are SHA-2 and SHA-3 of
34-
sizes 256, 384, and 512 (the algorithm is selected by data in the signature).
31+
type. The built-in facility currently only supports the RSA, NIST P-384 ECDSA
32+
and NIST FIPS-204 ML-DSA public key signing standards (though it is pluggable
33+
and permits others to be used). For RSA and ECDSA, the possible hash
34+
algorithms that can be used are SHA-2 and SHA-3 of sizes 256, 384, and 512 (the
35+
algorithm is selected by data in the signature); ML-DSA does its own hashing,
36+
but is allowed to be used with a SHA512 hash for signed attributes.
3537

3638

3739
==========================
@@ -146,9 +148,9 @@ into vmlinux) using parameters in the::
146148

147149
file (which is also generated if it does not already exist).
148150

149-
One can select between RSA (``MODULE_SIG_KEY_TYPE_RSA``) and ECDSA
150-
(``MODULE_SIG_KEY_TYPE_ECDSA``) to generate either RSA 4k or NIST
151-
P-384 keypair.
151+
One can select between RSA (``MODULE_SIG_KEY_TYPE_RSA``), ECDSA
152+
(``MODULE_SIG_KEY_TYPE_ECDSA``) and ML-DSA (``MODULE_SIG_KEY_TYPE_MLDSA_*``) to
153+
generate an RSA 4k, a NIST P-384 keypair or an ML-DSA 44, 65 or 87 keypair.
152154

153155
It is strongly recommended that you provide your own x509.genkey file.
154156

certs/Kconfig

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,39 @@ config MODULE_SIG_KEY_TYPE_ECDSA
3939
Note: Remove all ECDSA signing keys, e.g. certs/signing_key.pem,
4040
when falling back to building Linux 5.14 and older kernels.
4141

42+
config MODULE_SIG_KEY_TYPE_MLDSA_44
43+
bool "ML-DSA-44"
44+
select CRYPTO_MLDSA
45+
depends on OPENSSL_SUPPORTS_ML_DSA
46+
help
47+
Use an ML-DSA-44 key (NIST FIPS 204) for module signing. ML-DSA
48+
support requires OpenSSL-3.5 minimum; preferably OpenSSL-4+. With
49+
the latter, the entire module body will be signed; with the former,
50+
signedAttrs will be used as it lacks support for CMS_NOATTR with
51+
ML-DSA.
52+
53+
config MODULE_SIG_KEY_TYPE_MLDSA_65
54+
bool "ML-DSA-65"
55+
select CRYPTO_MLDSA
56+
depends on OPENSSL_SUPPORTS_ML_DSA
57+
help
58+
Use an ML-DSA-65 key (NIST FIPS 204) for module signing. ML-DSA
59+
support requires OpenSSL-3.5 minimum; preferably OpenSSL-4+. With
60+
the latter, the entire module body will be signed; with the former,
61+
signedAttrs will be used as it lacks support for CMS_NOATTR with
62+
ML-DSA.
63+
64+
config MODULE_SIG_KEY_TYPE_MLDSA_87
65+
bool "ML-DSA-87"
66+
select CRYPTO_MLDSA
67+
depends on OPENSSL_SUPPORTS_ML_DSA
68+
help
69+
Use an ML-DSA-87 key (NIST FIPS 204) for module signing. ML-DSA
70+
support requires OpenSSL-3.5 minimum; preferably OpenSSL-4+. With
71+
the latter, the entire module body will be signed; with the former,
72+
signedAttrs will be used as it lacks support for CMS_NOATTR with
73+
ML-DSA.
74+
4275
endchoice
4376

4477
config SYSTEM_TRUSTED_KEYRING
@@ -154,4 +187,11 @@ config SYSTEM_BLACKLIST_AUTH_UPDATE
154187
keyring. The PKCS#7 signature of the description is set in the key
155188
payload. Blacklist keys cannot be removed.
156189

190+
config OPENSSL_SUPPORTS_ML_DSA
191+
def_bool $(success, openssl list -key-managers | grep -q ML-DSA-87)
192+
help
193+
Support for ML-DSA-44/65/87 was added in openssl-3.5, so as long
194+
as older versions are supported, the key types may only be
195+
set after testing the installed binary for support.
196+
157197
endmenu

certs/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ targets += x509_certificate_list
4343
ifeq ($(CONFIG_MODULE_SIG_KEY),certs/signing_key.pem)
4444

4545
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_ECDSA) := -newkey ec -pkeyopt ec_paramgen_curve:secp384r1
46+
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_44) := -newkey ml-dsa-44
47+
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_65) := -newkey ml-dsa-65
48+
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_87) := -newkey ml-dsa-87
4649

4750
quiet_cmd_gen_key = GENKEY $@
4851
cmd_gen_key = openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \

scripts/sign-file.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <openssl/evp.h>
2828
#include <openssl/pem.h>
2929
#include <openssl/err.h>
30-
#if OPENSSL_VERSION_MAJOR >= 3
30+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
3131
# define USE_PKCS11_PROVIDER
3232
# include <openssl/provider.h>
3333
# include <openssl/store.h>
@@ -315,18 +315,39 @@ int main(int argc, char **argv)
315315
ERR(!digest_algo, "EVP_get_digestbyname");
316316

317317
#ifndef USE_PKCS7
318+
319+
unsigned int flags =
320+
CMS_NOCERTS |
321+
CMS_PARTIAL |
322+
CMS_BINARY |
323+
CMS_DETACHED |
324+
CMS_STREAM |
325+
CMS_NOSMIMECAP |
326+
#ifdef CMS_NO_SIGNING_TIME
327+
CMS_NO_SIGNING_TIME |
328+
#endif
329+
use_keyid;
330+
331+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_VERSION_NUMBER < 0x40000000L
332+
if (EVP_PKEY_is_a(private_key, "ML-DSA-44") ||
333+
EVP_PKEY_is_a(private_key, "ML-DSA-65") ||
334+
EVP_PKEY_is_a(private_key, "ML-DSA-87")) {
335+
/* ML-DSA + CMS_NOATTR is not supported in openssl-3.5
336+
* and before.
337+
*/
338+
use_signed_attrs = 0;
339+
}
340+
#endif
341+
342+
flags |= use_signed_attrs;
343+
318344
/* Load the signature message from the digest buffer. */
319-
cms = CMS_sign(NULL, NULL, NULL, NULL,
320-
CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
321-
CMS_DETACHED | CMS_STREAM);
345+
cms = CMS_sign(NULL, NULL, NULL, NULL, flags);
322346
ERR(!cms, "CMS_sign");
323347

324-
ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
325-
CMS_NOCERTS | CMS_BINARY |
326-
CMS_NOSMIMECAP | use_keyid |
327-
use_signed_attrs),
348+
ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo, flags),
328349
"CMS_add1_signer");
329-
ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1,
350+
ERR(CMS_final(cms, bm, NULL, flags) != 1,
330351
"CMS_final");
331352

332353
#else

0 commit comments

Comments
 (0)