xref: /linux/crypto/ecdsa.c (revision 221f00418e726237dbe38ba627ce08b22d3667f7)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2021 IBM Corporation
4  */
5 
6 #include <linux/module.h>
7 #include <crypto/internal/ecc.h>
8 #include <crypto/internal/sig.h>
9 #include <crypto/ecdh.h>
10 #include <crypto/sig.h>
11 
12 struct ecc_ctx {
13 	unsigned int curve_id;
14 	const struct ecc_curve *curve;
15 
16 	bool pub_key_set;
17 	u64 x[ECC_MAX_DIGITS]; /* pub key x and y coordinates */
18 	u64 y[ECC_MAX_DIGITS];
19 	struct ecc_point pub_key;
20 };
21 
22 static int _ecdsa_verify(struct ecc_ctx *ctx, const u64 *hash, const u64 *r, const u64 *s)
23 {
24 	const struct ecc_curve *curve = ctx->curve;
25 	unsigned int ndigits = curve->g.ndigits;
26 	u64 s1[ECC_MAX_DIGITS];
27 	u64 u1[ECC_MAX_DIGITS];
28 	u64 u2[ECC_MAX_DIGITS];
29 	u64 x1[ECC_MAX_DIGITS];
30 	u64 y1[ECC_MAX_DIGITS];
31 	struct ecc_point res = ECC_POINT_INIT(x1, y1, ndigits);
32 
33 	/* 0 < r < n  and 0 < s < n */
34 	if (vli_is_zero(r, ndigits) || vli_cmp(r, curve->n, ndigits) >= 0 ||
35 	    vli_is_zero(s, ndigits) || vli_cmp(s, curve->n, ndigits) >= 0)
36 		return -EBADMSG;
37 
38 	/* hash is given */
39 	pr_devel("hash : %016llx %016llx ... %016llx\n",
40 		 hash[ndigits - 1], hash[ndigits - 2], hash[0]);
41 
42 	/* s1 = (s^-1) mod n */
43 	vli_mod_inv(s1, s, curve->n, ndigits);
44 	/* u1 = (hash * s1) mod n */
45 	vli_mod_mult_slow(u1, hash, s1, curve->n, ndigits);
46 	/* u2 = (r * s1) mod n */
47 	vli_mod_mult_slow(u2, r, s1, curve->n, ndigits);
48 	/* res = u1*G + u2 * pub_key */
49 	ecc_point_mult_shamir(&res, u1, &curve->g, u2, &ctx->pub_key, curve);
50 
51 	/* res.x = res.x mod n (if res.x > order) */
52 	if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1))
53 		/* faster alternative for NIST p521, p384, p256 & p192 */
54 		vli_sub(res.x, res.x, curve->n, ndigits);
55 
56 	if (!vli_cmp(res.x, r, ndigits))
57 		return 0;
58 
59 	return -EKEYREJECTED;
60 }
61 
62 /*
63  * Verify an ECDSA signature.
64  */
65 static int ecdsa_verify(struct crypto_sig *tfm,
66 			const void *src, unsigned int slen,
67 			const void *digest, unsigned int dlen)
68 {
69 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
70 	size_t bufsize = ctx->curve->g.ndigits * sizeof(u64);
71 	const struct ecdsa_raw_sig *sig = src;
72 	u64 hash[ECC_MAX_DIGITS];
73 
74 	if (unlikely(!ctx->pub_key_set))
75 		return -EINVAL;
76 
77 	if (slen != sizeof(*sig))
78 		return -EINVAL;
79 
80 	if (bufsize > dlen)
81 		bufsize = dlen;
82 
83 	ecc_digits_from_bytes(digest, bufsize, hash, ctx->curve->g.ndigits);
84 
85 	return _ecdsa_verify(ctx, hash, sig->r, sig->s);
86 }
87 
88 static int ecdsa_ecc_ctx_init(struct ecc_ctx *ctx, unsigned int curve_id)
89 {
90 	ctx->curve_id = curve_id;
91 	ctx->curve = ecc_get_curve(curve_id);
92 	if (!ctx->curve)
93 		return -EINVAL;
94 
95 	return 0;
96 }
97 
98 
99 static void ecdsa_ecc_ctx_deinit(struct ecc_ctx *ctx)
100 {
101 	ctx->pub_key_set = false;
102 }
103 
104 static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx)
105 {
106 	unsigned int curve_id = ctx->curve_id;
107 	int ret;
108 
109 	ecdsa_ecc_ctx_deinit(ctx);
110 	ret = ecdsa_ecc_ctx_init(ctx, curve_id);
111 	if (ret == 0)
112 		ctx->pub_key = ECC_POINT_INIT(ctx->x, ctx->y,
113 					      ctx->curve->g.ndigits);
114 	return ret;
115 }
116 
117 /*
118  * Set the public ECC key as defined by RFC5480 section 2.2 "Subject Public
119  * Key". Only the uncompressed format is supported.
120  */
121 static int ecdsa_set_pub_key(struct crypto_sig *tfm, const void *key,
122 			     unsigned int keylen)
123 {
124 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
125 	unsigned int digitlen, ndigits;
126 	const unsigned char *d = key;
127 	int ret;
128 
129 	ret = ecdsa_ecc_ctx_reset(ctx);
130 	if (ret < 0)
131 		return ret;
132 
133 	if (keylen < 1 || ((keylen - 1) & 1) != 0)
134 		return -EINVAL;
135 	/* we only accept uncompressed format indicated by '4' */
136 	if (d[0] != 4)
137 		return -EINVAL;
138 
139 	keylen--;
140 	digitlen = keylen >> 1;
141 
142 	ndigits = DIV_ROUND_UP(digitlen, sizeof(u64));
143 	if (ndigits != ctx->curve->g.ndigits)
144 		return -EINVAL;
145 
146 	d++;
147 
148 	ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits);
149 	ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits);
150 
151 	ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
152 
153 	ctx->pub_key_set = ret == 0;
154 
155 	return ret;
156 }
157 
158 static void ecdsa_exit_tfm(struct crypto_sig *tfm)
159 {
160 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
161 
162 	ecdsa_ecc_ctx_deinit(ctx);
163 }
164 
165 static unsigned int ecdsa_key_size(struct crypto_sig *tfm)
166 {
167 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
168 
169 	return DIV_ROUND_UP(ctx->curve->nbits, 8);
170 }
171 
172 static int ecdsa_nist_p521_init_tfm(struct crypto_sig *tfm)
173 {
174 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
175 
176 	return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P521);
177 }
178 
179 static struct sig_alg ecdsa_nist_p521 = {
180 	.verify = ecdsa_verify,
181 	.set_pub_key = ecdsa_set_pub_key,
182 	.key_size = ecdsa_key_size,
183 	.init = ecdsa_nist_p521_init_tfm,
184 	.exit = ecdsa_exit_tfm,
185 	.base = {
186 		.cra_name = "ecdsa-nist-p521",
187 		.cra_driver_name = "ecdsa-nist-p521-generic",
188 		.cra_priority = 100,
189 		.cra_module = THIS_MODULE,
190 		.cra_ctxsize = sizeof(struct ecc_ctx),
191 	},
192 };
193 
194 static int ecdsa_nist_p384_init_tfm(struct crypto_sig *tfm)
195 {
196 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
197 
198 	return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P384);
199 }
200 
201 static struct sig_alg ecdsa_nist_p384 = {
202 	.verify = ecdsa_verify,
203 	.set_pub_key = ecdsa_set_pub_key,
204 	.key_size = ecdsa_key_size,
205 	.init = ecdsa_nist_p384_init_tfm,
206 	.exit = ecdsa_exit_tfm,
207 	.base = {
208 		.cra_name = "ecdsa-nist-p384",
209 		.cra_driver_name = "ecdsa-nist-p384-generic",
210 		.cra_priority = 100,
211 		.cra_module = THIS_MODULE,
212 		.cra_ctxsize = sizeof(struct ecc_ctx),
213 	},
214 };
215 
216 static int ecdsa_nist_p256_init_tfm(struct crypto_sig *tfm)
217 {
218 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
219 
220 	return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P256);
221 }
222 
223 static struct sig_alg ecdsa_nist_p256 = {
224 	.verify = ecdsa_verify,
225 	.set_pub_key = ecdsa_set_pub_key,
226 	.key_size = ecdsa_key_size,
227 	.init = ecdsa_nist_p256_init_tfm,
228 	.exit = ecdsa_exit_tfm,
229 	.base = {
230 		.cra_name = "ecdsa-nist-p256",
231 		.cra_driver_name = "ecdsa-nist-p256-generic",
232 		.cra_priority = 100,
233 		.cra_module = THIS_MODULE,
234 		.cra_ctxsize = sizeof(struct ecc_ctx),
235 	},
236 };
237 
238 static int ecdsa_nist_p192_init_tfm(struct crypto_sig *tfm)
239 {
240 	struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
241 
242 	return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P192);
243 }
244 
245 static struct sig_alg ecdsa_nist_p192 = {
246 	.verify = ecdsa_verify,
247 	.set_pub_key = ecdsa_set_pub_key,
248 	.key_size = ecdsa_key_size,
249 	.init = ecdsa_nist_p192_init_tfm,
250 	.exit = ecdsa_exit_tfm,
251 	.base = {
252 		.cra_name = "ecdsa-nist-p192",
253 		.cra_driver_name = "ecdsa-nist-p192-generic",
254 		.cra_priority = 100,
255 		.cra_module = THIS_MODULE,
256 		.cra_ctxsize = sizeof(struct ecc_ctx),
257 	},
258 };
259 static bool ecdsa_nist_p192_registered;
260 
261 static int __init ecdsa_init(void)
262 {
263 	int ret;
264 
265 	/* NIST p192 may not be available in FIPS mode */
266 	ret = crypto_register_sig(&ecdsa_nist_p192);
267 	ecdsa_nist_p192_registered = ret == 0;
268 
269 	ret = crypto_register_sig(&ecdsa_nist_p256);
270 	if (ret)
271 		goto nist_p256_error;
272 
273 	ret = crypto_register_sig(&ecdsa_nist_p384);
274 	if (ret)
275 		goto nist_p384_error;
276 
277 	ret = crypto_register_sig(&ecdsa_nist_p521);
278 	if (ret)
279 		goto nist_p521_error;
280 
281 	ret = crypto_register_template(&ecdsa_x962_tmpl);
282 	if (ret)
283 		goto x962_tmpl_error;
284 
285 	return 0;
286 
287 x962_tmpl_error:
288 	crypto_unregister_sig(&ecdsa_nist_p521);
289 
290 nist_p521_error:
291 	crypto_unregister_sig(&ecdsa_nist_p384);
292 
293 nist_p384_error:
294 	crypto_unregister_sig(&ecdsa_nist_p256);
295 
296 nist_p256_error:
297 	if (ecdsa_nist_p192_registered)
298 		crypto_unregister_sig(&ecdsa_nist_p192);
299 	return ret;
300 }
301 
302 static void __exit ecdsa_exit(void)
303 {
304 	crypto_unregister_template(&ecdsa_x962_tmpl);
305 
306 	if (ecdsa_nist_p192_registered)
307 		crypto_unregister_sig(&ecdsa_nist_p192);
308 	crypto_unregister_sig(&ecdsa_nist_p256);
309 	crypto_unregister_sig(&ecdsa_nist_p384);
310 	crypto_unregister_sig(&ecdsa_nist_p521);
311 }
312 
313 subsys_initcall(ecdsa_init);
314 module_exit(ecdsa_exit);
315 
316 MODULE_LICENSE("GPL");
317 MODULE_AUTHOR("Stefan Berger <stefanb@linux.ibm.com>");
318 MODULE_DESCRIPTION("ECDSA generic algorithm");
319 MODULE_ALIAS_CRYPTO("ecdsa-nist-p192");
320 MODULE_ALIAS_CRYPTO("ecdsa-nist-p256");
321 MODULE_ALIAS_CRYPTO("ecdsa-nist-p384");
322 MODULE_ALIAS_CRYPTO("ecdsa-nist-p521");
323 MODULE_ALIAS_CRYPTO("ecdsa-generic");
324