Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
10struct 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
19static 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
26static 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
39static 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
56static 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
71static int crypto_mldsa_set_priv_key(struct crypto_sig *tfm,
72 const void *key, unsigned int keylen)
73{
74 return -EOPNOTSUPP;
75}
76
77static 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
94static 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
103static 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
112static 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
121static void crypto_mldsa_alg_exit(struct crypto_sig *tfm)
122{
123}
124
125static 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
171static 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
182error:
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}
188module_init(mldsa_init);
189
190static 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}
195module_exit(mldsa_exit);
196
197MODULE_LICENSE("GPL");
198MODULE_DESCRIPTION("Crypto API support for ML-DSA signature verification");
199MODULE_ALIAS_CRYPTO("mldsa44");
200MODULE_ALIAS_CRYPTO("mldsa65");
201MODULE_ALIAS_CRYPTO("mldsa87");