Skip to content

Commit 70b2ca8

Browse files
dhowellsdagomez137
authored andcommitted
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.5.1, support the use of CMS_NOATTR with ML-DSA, so the prohibition against using authenticatedAttributes 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 ML-DSA algorithm uses its own internal choice of digest (SHAKE256) without regard to what's specified in the CMS message. This is, in theory, configurable, but there's currently no hook in the crypto_sig API to do that, though possibly it could be done by parameterising the name of the algorithm, e.g. ("ml-dsa87(sha512)"). 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
1 parent 2c756db commit 70b2ca8

6 files changed

Lines changed: 58 additions & 19 deletions

File tree

Documentation/admin-guide/module-signing.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ 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 (Dilithium) public key signing standards (though it is
33+
pluggable 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 uses SHAKE256.
3536

3637

3738
==========================
@@ -146,9 +147,9 @@ into vmlinux) using parameters in the::
146147

147148
file (which is also generated if it does not already exist).
148149

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.
150+
One can select between RSA (``MODULE_SIG_KEY_TYPE_RSA``), ECDSA
151+
(``MODULE_SIG_KEY_TYPE_ECDSA``) and ML-DSA (``MODULE_SIG_KEY_TYPE_ML_DSA``) to
152+
generate an RSA 4k, a NIST P-384 keypair or an ML-DSA keypair.
152153

153154
It is strongly recommended that you provide your own x509.genkey file.
154155

certs/Kconfig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,30 @@ 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_ML_DSA_44
43+
bool "ML-DSA (Dilithium) 44"
44+
select CRYPTO_ML_DSA
45+
select LIB_SHA3
46+
help
47+
Use an ML-DSA (Dilithium) 87 key (NIST FIPS 204) for module signing
48+
with a SHAKE256 'hash' of the message.
49+
50+
config MODULE_SIG_KEY_TYPE_ML_DSA_65
51+
bool "ML-DSA (Dilithium) 65"
52+
select CRYPTO_ML_DSA
53+
select LIB_SHA3
54+
help
55+
Use an ML-DSA (Dilithium) 87 key (NIST FIPS 204) for module signing
56+
with a SHAKE256 'hash' of the message.
57+
58+
config MODULE_SIG_KEY_TYPE_ML_DSA_87
59+
bool "ML-DSA (Dilithium) 87"
60+
select CRYPTO_ML_DSA
61+
select LIB_SHA3
62+
help
63+
Use an ML-DSA (Dilithium) 87 key (NIST FIPS 204) for module signing
64+
with a SHAKE256 'hash' of the message.
65+
4266
endchoice
4367

4468
config SYSTEM_TRUSTED_KEYRING

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_ML_DSA_44) := -newkey ml-dsa-44
47+
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_ML_DSA_65) := -newkey ml-dsa-65
48+
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_ML_DSA_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 \

crypto/asymmetric_keys/pkcs7_verify.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
424424
pr_warn("Invalid module sig (not pkcs7-data)\n");
425425
return -EKEYREJECTED;
426426
}
427-
if (pkcs7->have_authattrs) {
428-
pr_warn("Invalid module sig (has authattrs)\n");
429-
return -EKEYREJECTED;
430-
}
431427
break;
432428
case VERIFYING_FIRMWARE_SIGNATURE:
433429
if (pkcs7->data_type != OID_data) {

kernel/module/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ config MODULE_SIG_SHA3_512
327327
bool "SHA3-512"
328328
select CRYPTO_SHA3
329329

330+
config MODULE_SIG_SHAKE256
331+
bool "SHAKE256"
332+
select CRYPTO_SHA3
333+
330334
endchoice
331335

332336
config MODULE_SIG_HASH
@@ -339,6 +343,7 @@ config MODULE_SIG_HASH
339343
default "sha3-256" if MODULE_SIG_SHA3_256
340344
default "sha3-384" if MODULE_SIG_SHA3_384
341345
default "sha3-512" if MODULE_SIG_SHA3_512
346+
default "shake256" if MODULE_SIG_SHAKE256
342347

343348
config MODULE_COMPRESS
344349
bool "Module compression"

scripts/sign-file.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,18 +315,28 @@ 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+
CMS_NO_SIGNING_TIME |
327+
use_keyid;
328+
if (!EVP_PKEY_is_a(private_key, "ML-DSA-44") &&
329+
!EVP_PKEY_is_a(private_key, "ML-DSA-65") &&
330+
!EVP_PKEY_is_a(private_key, "ML-DSA-87"))
331+
flags |= use_signed_attrs;
332+
318333
/* 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);
334+
cms = CMS_sign(NULL, NULL, NULL, NULL, flags);
322335
ERR(!cms, "CMS_sign");
323336

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),
337+
ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo, flags),
328338
"CMS_add1_signer");
329-
ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1,
339+
ERR(CMS_final(cms, bm, NULL, flags) != 1,
330340
"CMS_final");
331341

332342
#else

0 commit comments

Comments
 (0)