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"); 202