Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: Add ML-DSA crypto_sig support

Add verify-only public key crypto support for ML-DSA so that the
X.509/PKCS#7 signature verification code, as used by module signing,
amongst other things, can make use of it through the common crypto_sig API.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: 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

+212
+9
crypto/Kconfig
··· 344 344 One of the Russian cryptographic standard algorithms (called GOST 345 345 algorithms). Only signature verification is implemented. 346 346 347 + config CRYPTO_MLDSA 348 + tristate "ML-DSA (Module-Lattice-Based Digital Signature Algorithm)" 349 + select CRYPTO_SIG 350 + select CRYPTO_LIB_MLDSA 351 + help 352 + ML-DSA (Module-Lattice-Based Digital Signature Algorithm) (FIPS-204). 353 + 354 + Only signature verification is implemented. 355 + 347 356 endmenu 348 357 349 358 menu "Block ciphers"
+2
crypto/Makefile
··· 60 60 ecdsa_generic-y += ecdsasignature.asn1.o 61 61 obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o 62 62 63 + obj-$(CONFIG_CRYPTO_MLDSA) += mldsa.o 64 + 63 65 crypto_acompress-y := acompress.o 64 66 crypto_acompress-y += scompress.o 65 67 obj-$(CONFIG_CRYPTO_ACOMP2) += crypto_acompress.o
+201
crypto/mldsa.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * crypto_sig wrapper around ML-DSA library. 4 + */ 5 + #include <linux/init.h> 6 + #include <linux/module.h> 7 + #include <crypto/internal/sig.h> 8 + #include <crypto/mldsa.h> 9 + 10 + struct crypto_mldsa_ctx { 11 + u8 pk[MAX(MAX(MLDSA44_PUBLIC_KEY_SIZE, 12 + MLDSA65_PUBLIC_KEY_SIZE), 13 + MLDSA87_PUBLIC_KEY_SIZE)]; 14 + unsigned int pk_len; 15 + enum mldsa_alg strength; 16 + bool key_set; 17 + }; 18 + 19 + static int crypto_mldsa_sign(struct crypto_sig *tfm, 20 + const void *msg, unsigned int msg_len, 21 + void *sig, unsigned int sig_len) 22 + { 23 + return -EOPNOTSUPP; 24 + } 25 + 26 + static int crypto_mldsa_verify(struct crypto_sig *tfm, 27 + const void *sig, unsigned int sig_len, 28 + const void *msg, unsigned int msg_len) 29 + { 30 + const struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 31 + 32 + if (unlikely(!ctx->key_set)) 33 + return -EINVAL; 34 + 35 + return mldsa_verify(ctx->strength, sig, sig_len, msg, msg_len, 36 + ctx->pk, ctx->pk_len); 37 + } 38 + 39 + static unsigned int crypto_mldsa_key_size(struct crypto_sig *tfm) 40 + { 41 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 42 + 43 + switch (ctx->strength) { 44 + case MLDSA44: 45 + return MLDSA44_PUBLIC_KEY_SIZE; 46 + case MLDSA65: 47 + return MLDSA65_PUBLIC_KEY_SIZE; 48 + case MLDSA87: 49 + return MLDSA87_PUBLIC_KEY_SIZE; 50 + default: 51 + WARN_ON_ONCE(1); 52 + return 0; 53 + } 54 + } 55 + 56 + static int crypto_mldsa_set_pub_key(struct crypto_sig *tfm, 57 + const void *key, unsigned int keylen) 58 + { 59 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 60 + unsigned int expected_len = crypto_mldsa_key_size(tfm); 61 + 62 + if (keylen != expected_len) 63 + return -EINVAL; 64 + 65 + ctx->pk_len = keylen; 66 + memcpy(ctx->pk, key, keylen); 67 + ctx->key_set = true; 68 + return 0; 69 + } 70 + 71 + static int crypto_mldsa_set_priv_key(struct crypto_sig *tfm, 72 + const void *key, unsigned int keylen) 73 + { 74 + return -EOPNOTSUPP; 75 + } 76 + 77 + static unsigned int crypto_mldsa_max_size(struct crypto_sig *tfm) 78 + { 79 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 80 + 81 + switch (ctx->strength) { 82 + case MLDSA44: 83 + return MLDSA44_SIGNATURE_SIZE; 84 + case MLDSA65: 85 + return MLDSA65_SIGNATURE_SIZE; 86 + case MLDSA87: 87 + return MLDSA87_SIGNATURE_SIZE; 88 + default: 89 + WARN_ON_ONCE(1); 90 + return 0; 91 + } 92 + } 93 + 94 + static int crypto_mldsa44_alg_init(struct crypto_sig *tfm) 95 + { 96 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 97 + 98 + ctx->strength = MLDSA44; 99 + ctx->key_set = false; 100 + return 0; 101 + } 102 + 103 + static int crypto_mldsa65_alg_init(struct crypto_sig *tfm) 104 + { 105 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 106 + 107 + ctx->strength = MLDSA65; 108 + ctx->key_set = false; 109 + return 0; 110 + } 111 + 112 + static int crypto_mldsa87_alg_init(struct crypto_sig *tfm) 113 + { 114 + struct crypto_mldsa_ctx *ctx = crypto_sig_ctx(tfm); 115 + 116 + ctx->strength = MLDSA87; 117 + ctx->key_set = false; 118 + return 0; 119 + } 120 + 121 + static void crypto_mldsa_alg_exit(struct crypto_sig *tfm) 122 + { 123 + } 124 + 125 + static struct sig_alg crypto_mldsa_algs[] = { 126 + { 127 + .sign = crypto_mldsa_sign, 128 + .verify = crypto_mldsa_verify, 129 + .set_pub_key = crypto_mldsa_set_pub_key, 130 + .set_priv_key = crypto_mldsa_set_priv_key, 131 + .key_size = crypto_mldsa_key_size, 132 + .max_size = crypto_mldsa_max_size, 133 + .init = crypto_mldsa44_alg_init, 134 + .exit = crypto_mldsa_alg_exit, 135 + .base.cra_name = "mldsa44", 136 + .base.cra_driver_name = "mldsa44-lib", 137 + .base.cra_ctxsize = sizeof(struct crypto_mldsa_ctx), 138 + .base.cra_module = THIS_MODULE, 139 + .base.cra_priority = 5000, 140 + }, { 141 + .sign = crypto_mldsa_sign, 142 + .verify = crypto_mldsa_verify, 143 + .set_pub_key = crypto_mldsa_set_pub_key, 144 + .set_priv_key = crypto_mldsa_set_priv_key, 145 + .key_size = crypto_mldsa_key_size, 146 + .max_size = crypto_mldsa_max_size, 147 + .init = crypto_mldsa65_alg_init, 148 + .exit = crypto_mldsa_alg_exit, 149 + .base.cra_name = "mldsa65", 150 + .base.cra_driver_name = "mldsa65-lib", 151 + .base.cra_ctxsize = sizeof(struct crypto_mldsa_ctx), 152 + .base.cra_module = THIS_MODULE, 153 + .base.cra_priority = 5000, 154 + }, { 155 + .sign = crypto_mldsa_sign, 156 + .verify = crypto_mldsa_verify, 157 + .set_pub_key = crypto_mldsa_set_pub_key, 158 + .set_priv_key = crypto_mldsa_set_priv_key, 159 + .key_size = crypto_mldsa_key_size, 160 + .max_size = crypto_mldsa_max_size, 161 + .init = crypto_mldsa87_alg_init, 162 + .exit = crypto_mldsa_alg_exit, 163 + .base.cra_name = "mldsa87", 164 + .base.cra_driver_name = "mldsa87-lib", 165 + .base.cra_ctxsize = sizeof(struct crypto_mldsa_ctx), 166 + .base.cra_module = THIS_MODULE, 167 + .base.cra_priority = 5000, 168 + }, 169 + }; 170 + 171 + static int __init mldsa_init(void) 172 + { 173 + int ret, i; 174 + 175 + for (i = 0; i < ARRAY_SIZE(crypto_mldsa_algs); i++) { 176 + ret = crypto_register_sig(&crypto_mldsa_algs[i]); 177 + if (ret < 0) 178 + goto error; 179 + } 180 + return 0; 181 + 182 + error: 183 + pr_err("Failed to register (%d)\n", ret); 184 + for (i--; i >= 0; i--) 185 + crypto_unregister_sig(&crypto_mldsa_algs[i]); 186 + return ret; 187 + } 188 + module_init(mldsa_init); 189 + 190 + static void mldsa_exit(void) 191 + { 192 + for (int i = 0; i < ARRAY_SIZE(crypto_mldsa_algs); i++) 193 + crypto_unregister_sig(&crypto_mldsa_algs[i]); 194 + } 195 + module_exit(mldsa_exit); 196 + 197 + MODULE_LICENSE("GPL"); 198 + MODULE_DESCRIPTION("Crypto API support for ML-DSA signature verification"); 199 + MODULE_ALIAS_CRYPTO("mldsa44"); 200 + MODULE_ALIAS_CRYPTO("mldsa65"); 201 + MODULE_ALIAS_CRYPTO("mldsa87");