xref: /linux/crypto/sig.c (revision 65c4c93caaf1a9fca2855942e338530967162d25)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Public Key Signature Algorithm
4  *
5  * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au>
6  */
7 
8 #include <crypto/akcipher.h>
9 #include <crypto/internal/sig.h>
10 #include <linux/cryptouser.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/scatterlist.h>
14 #include <linux/seq_file.h>
15 #include <linux/string.h>
16 #include <net/netlink.h>
17 
18 #include "internal.h"
19 
20 #define CRYPTO_ALG_TYPE_SIG_MASK	0x0000000e
21 
22 static const struct crypto_type crypto_sig_type;
23 
24 static void crypto_sig_exit_tfm(struct crypto_tfm *tfm)
25 {
26 	struct crypto_sig *sig = __crypto_sig_tfm(tfm);
27 	struct sig_alg *alg = crypto_sig_alg(sig);
28 
29 	alg->exit(sig);
30 }
31 
32 static int crypto_sig_init_tfm(struct crypto_tfm *tfm)
33 {
34 	if (tfm->__crt_alg->cra_type != &crypto_sig_type)
35 		return crypto_init_akcipher_ops_sig(tfm);
36 
37 	struct crypto_sig *sig = __crypto_sig_tfm(tfm);
38 	struct sig_alg *alg = crypto_sig_alg(sig);
39 
40 	if (alg->exit)
41 		sig->base.exit = crypto_sig_exit_tfm;
42 
43 	if (alg->init)
44 		return alg->init(sig);
45 
46 	return 0;
47 }
48 
49 static void crypto_sig_free_instance(struct crypto_instance *inst)
50 {
51 	struct sig_instance *sig = sig_instance(inst);
52 
53 	sig->free(sig);
54 }
55 
56 static void __maybe_unused crypto_sig_show(struct seq_file *m,
57 					   struct crypto_alg *alg)
58 {
59 	seq_puts(m, "type         : sig\n");
60 }
61 
62 static int __maybe_unused crypto_sig_report(struct sk_buff *skb,
63 					    struct crypto_alg *alg)
64 {
65 	struct crypto_report_sig rsig = {};
66 
67 	strscpy(rsig.type, "sig", sizeof(rsig.type));
68 
69 	return nla_put(skb, CRYPTOCFGA_REPORT_SIG, sizeof(rsig), &rsig);
70 }
71 
72 static const struct crypto_type crypto_sig_type = {
73 	.extsize = crypto_alg_extsize,
74 	.init_tfm = crypto_sig_init_tfm,
75 	.free = crypto_sig_free_instance,
76 #ifdef CONFIG_PROC_FS
77 	.show = crypto_sig_show,
78 #endif
79 #if IS_ENABLED(CONFIG_CRYPTO_USER)
80 	.report = crypto_sig_report,
81 #endif
82 	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
83 	.maskset = CRYPTO_ALG_TYPE_SIG_MASK,
84 	.type = CRYPTO_ALG_TYPE_SIG,
85 	.tfmsize = offsetof(struct crypto_sig, base),
86 };
87 
88 struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask)
89 {
90 	return crypto_alloc_tfm(alg_name, &crypto_sig_type, type, mask);
91 }
92 EXPORT_SYMBOL_GPL(crypto_alloc_sig);
93 
94 int crypto_sig_maxsize(struct crypto_sig *tfm)
95 {
96 	if (crypto_sig_tfm(tfm)->__crt_alg->cra_type != &crypto_sig_type)
97 		goto akcipher;
98 
99 	struct sig_alg *alg = crypto_sig_alg(tfm);
100 
101 	return alg->max_size(tfm);
102 
103 akcipher:
104 	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);
105 
106 	return crypto_akcipher_maxsize(*ctx);
107 }
108 EXPORT_SYMBOL_GPL(crypto_sig_maxsize);
109 
110 int crypto_sig_sign(struct crypto_sig *tfm,
111 		    const void *src, unsigned int slen,
112 		    void *dst, unsigned int dlen)
113 {
114 	if (crypto_sig_tfm(tfm)->__crt_alg->cra_type != &crypto_sig_type)
115 		goto akcipher;
116 
117 	struct sig_alg *alg = crypto_sig_alg(tfm);
118 
119 	return alg->sign(tfm, src, slen, dst, dlen);
120 
121 akcipher:
122 	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);
123 	struct crypto_akcipher_sync_data data = {
124 		.tfm = *ctx,
125 		.src = src,
126 		.dst = dst,
127 		.slen = slen,
128 		.dlen = dlen,
129 	};
130 
131 	return crypto_akcipher_sync_prep(&data) ?:
132 	       crypto_akcipher_sync_post(&data,
133 					 crypto_akcipher_sign(data.req));
134 }
135 EXPORT_SYMBOL_GPL(crypto_sig_sign);
136 
137 int crypto_sig_verify(struct crypto_sig *tfm,
138 		      const void *src, unsigned int slen,
139 		      const void *digest, unsigned int dlen)
140 {
141 	if (crypto_sig_tfm(tfm)->__crt_alg->cra_type != &crypto_sig_type)
142 		goto akcipher;
143 
144 	struct sig_alg *alg = crypto_sig_alg(tfm);
145 
146 	return alg->verify(tfm, src, slen, digest, dlen);
147 
148 akcipher:
149 	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);
150 	struct crypto_akcipher_sync_data data = {
151 		.tfm = *ctx,
152 		.src = src,
153 		.slen = slen,
154 		.dlen = dlen,
155 	};
156 	int err;
157 
158 	err = crypto_akcipher_sync_prep(&data);
159 	if (err)
160 		return err;
161 
162 	memcpy(data.buf + slen, digest, dlen);
163 
164 	return crypto_akcipher_sync_post(&data,
165 					 crypto_akcipher_verify(data.req));
166 }
167 EXPORT_SYMBOL_GPL(crypto_sig_verify);
168 
169 int crypto_sig_set_pubkey(struct crypto_sig *tfm,
170 			  const void *key, unsigned int keylen)
171 {
172 	if (crypto_sig_tfm(tfm)->__crt_alg->cra_type != &crypto_sig_type)
173 		goto akcipher;
174 
175 	struct sig_alg *alg = crypto_sig_alg(tfm);
176 
177 	return alg->set_pub_key(tfm, key, keylen);
178 
179 akcipher:
180 	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);
181 
182 	return crypto_akcipher_set_pub_key(*ctx, key, keylen);
183 }
184 EXPORT_SYMBOL_GPL(crypto_sig_set_pubkey);
185 
186 int crypto_sig_set_privkey(struct crypto_sig *tfm,
187 			  const void *key, unsigned int keylen)
188 {
189 	if (crypto_sig_tfm(tfm)->__crt_alg->cra_type != &crypto_sig_type)
190 		goto akcipher;
191 
192 	struct sig_alg *alg = crypto_sig_alg(tfm);
193 
194 	return alg->set_priv_key(tfm, key, keylen);
195 
196 akcipher:
197 	struct crypto_akcipher **ctx = crypto_sig_ctx(tfm);
198 
199 	return crypto_akcipher_set_priv_key(*ctx, key, keylen);
200 }
201 EXPORT_SYMBOL_GPL(crypto_sig_set_privkey);
202 
203 static void sig_prepare_alg(struct sig_alg *alg)
204 {
205 	struct crypto_alg *base = &alg->base;
206 
207 	base->cra_type = &crypto_sig_type;
208 	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
209 	base->cra_flags |= CRYPTO_ALG_TYPE_SIG;
210 }
211 
212 static int sig_default_sign(struct crypto_sig *tfm,
213 			    const void *src, unsigned int slen,
214 			    void *dst, unsigned int dlen)
215 {
216 	return -ENOSYS;
217 }
218 
219 static int sig_default_verify(struct crypto_sig *tfm,
220 			      const void *src, unsigned int slen,
221 			      const void *dst, unsigned int dlen)
222 {
223 	return -ENOSYS;
224 }
225 
226 static int sig_default_set_key(struct crypto_sig *tfm,
227 			       const void *key, unsigned int keylen)
228 {
229 	return -ENOSYS;
230 }
231 
232 int crypto_register_sig(struct sig_alg *alg)
233 {
234 	struct crypto_alg *base = &alg->base;
235 
236 	if (!alg->sign)
237 		alg->sign = sig_default_sign;
238 	if (!alg->verify)
239 		alg->verify = sig_default_verify;
240 	if (!alg->set_priv_key)
241 		alg->set_priv_key = sig_default_set_key;
242 	if (!alg->set_pub_key)
243 		return -EINVAL;
244 	if (!alg->max_size)
245 		return -EINVAL;
246 
247 	sig_prepare_alg(alg);
248 	return crypto_register_alg(base);
249 }
250 EXPORT_SYMBOL_GPL(crypto_register_sig);
251 
252 void crypto_unregister_sig(struct sig_alg *alg)
253 {
254 	crypto_unregister_alg(&alg->base);
255 }
256 EXPORT_SYMBOL_GPL(crypto_unregister_sig);
257 
258 int sig_register_instance(struct crypto_template *tmpl,
259 			  struct sig_instance *inst)
260 {
261 	if (WARN_ON(!inst->free))
262 		return -EINVAL;
263 	sig_prepare_alg(&inst->alg);
264 	return crypto_register_instance(tmpl, sig_crypto_instance(inst));
265 }
266 EXPORT_SYMBOL_GPL(sig_register_instance);
267 
268 int crypto_grab_sig(struct crypto_sig_spawn *spawn,
269 		    struct crypto_instance *inst,
270 		    const char *name, u32 type, u32 mask)
271 {
272 	spawn->base.frontend = &crypto_sig_type;
273 	return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
274 }
275 EXPORT_SYMBOL_GPL(crypto_grab_sig);
276 
277 MODULE_LICENSE("GPL");
278 MODULE_DESCRIPTION("Public Key Signature Algorithms");
279