xref: /openbsd-src/lib/libcrypto/ecdsa/ecdsa.c (revision 91b97d2016d6c03d4aa3ce04e0826f9ab7be649d)
1 /* $OpenBSD: ecdsa.c,v 1.16 2023/07/28 09:18:10 tb Exp $ */
2 /* ====================================================================
3  * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    licensing@OpenSSL.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  *
54  */
55 
56 #include <stddef.h>
57 #include <stdlib.h>
58 #include <string.h>
59 
60 #include <openssl/asn1.h>
61 #include <openssl/asn1t.h>
62 #include <openssl/bn.h>
63 #include <openssl/ec.h>
64 #include <openssl/err.h>
65 
66 #include "bn_local.h"
67 #include "ec_local.h"
68 #include "ecdsa_local.h"
69 
70 static const ASN1_TEMPLATE ECDSA_SIG_seq_tt[] = {
71 	{
72 		.flags = 0,
73 		.tag = 0,
74 		.offset = offsetof(ECDSA_SIG, r),
75 		.field_name = "r",
76 		.item = &BIGNUM_it,
77 	},
78 	{
79 		.flags = 0,
80 		.tag = 0,
81 		.offset = offsetof(ECDSA_SIG, s),
82 		.field_name = "s",
83 		.item = &BIGNUM_it,
84 	},
85 };
86 
87 const ASN1_ITEM ECDSA_SIG_it = {
88 	.itype = ASN1_ITYPE_SEQUENCE,
89 	.utype = V_ASN1_SEQUENCE,
90 	.templates = ECDSA_SIG_seq_tt,
91 	.tcount = sizeof(ECDSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
92 	.funcs = NULL,
93 	.size = sizeof(ECDSA_SIG),
94 	.sname = "ECDSA_SIG",
95 };
96 
97 ECDSA_SIG *
98 d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len)
99 {
100 	return (ECDSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
101 	    &ECDSA_SIG_it);
102 }
103 LCRYPTO_ALIAS(d2i_ECDSA_SIG);
104 
105 int
106 i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out)
107 {
108 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECDSA_SIG_it);
109 }
110 LCRYPTO_ALIAS(i2d_ECDSA_SIG);
111 
112 ECDSA_SIG *
113 ECDSA_SIG_new(void)
114 {
115 	return (ECDSA_SIG *)ASN1_item_new(&ECDSA_SIG_it);
116 }
117 LCRYPTO_ALIAS(ECDSA_SIG_new);
118 
119 void
120 ECDSA_SIG_free(ECDSA_SIG *a)
121 {
122 	ASN1_item_free((ASN1_VALUE *)a, &ECDSA_SIG_it);
123 }
124 LCRYPTO_ALIAS(ECDSA_SIG_free);
125 
126 void
127 ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
128 {
129 	if (pr != NULL)
130 		*pr = sig->r;
131 	if (ps != NULL)
132 		*ps = sig->s;
133 }
134 LCRYPTO_ALIAS(ECDSA_SIG_get0);
135 
136 const BIGNUM *
137 ECDSA_SIG_get0_r(const ECDSA_SIG *sig)
138 {
139 	return sig->r;
140 }
141 LCRYPTO_ALIAS(ECDSA_SIG_get0_r);
142 
143 const BIGNUM *
144 ECDSA_SIG_get0_s(const ECDSA_SIG *sig)
145 {
146 	return sig->s;
147 }
148 LCRYPTO_ALIAS(ECDSA_SIG_get0_s);
149 
150 int
151 ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
152 {
153 	if (r == NULL || s == NULL)
154 		return 0;
155 
156 	BN_free(sig->r);
157 	BN_free(sig->s);
158 	sig->r = r;
159 	sig->s = s;
160 	return 1;
161 }
162 LCRYPTO_ALIAS(ECDSA_SIG_set0);
163 
164 int
165 ECDSA_size(const EC_KEY *key)
166 {
167 	const EC_GROUP *group;
168 	const BIGNUM *order = NULL;
169 	ECDSA_SIG sig;
170 	int ret = 0;
171 
172 	if (key == NULL)
173 		goto err;
174 
175 	if ((group = EC_KEY_get0_group(key)) == NULL)
176 		goto err;
177 
178 	if ((order = EC_GROUP_get0_order(group)) == NULL)
179 		goto err;
180 
181 	sig.r = (BIGNUM *)order;
182 	sig.s = (BIGNUM *)order;
183 
184 	if ((ret = i2d_ECDSA_SIG(&sig, NULL)) < 0)
185 		ret = 0;
186 
187  err:
188 	return ret;
189 }
190 LCRYPTO_ALIAS(ECDSA_size);
191 
192 /*
193  * FIPS 186-5, section 6.4.1, step 2: convert hashed message into an integer.
194  * Use the order_bits leftmost bits if it exceeds the group order.
195  */
196 static int
197 ecdsa_prepare_digest(const unsigned char *digest, int digest_len,
198     const EC_KEY *key, BIGNUM *e)
199 {
200 	const EC_GROUP *group;
201 	int digest_bits, order_bits;
202 
203 	if (BN_bin2bn(digest, digest_len, e) == NULL) {
204 		ECerror(ERR_R_BN_LIB);
205 		return 0;
206 	}
207 
208 	if ((group = EC_KEY_get0_group(key)) == NULL)
209 		return 0;
210 	order_bits = EC_GROUP_order_bits(group);
211 
212 	digest_bits = 8 * digest_len;
213 	if (digest_bits <= order_bits)
214 		return 1;
215 
216 	return BN_rshift(e, e, digest_bits - order_bits);
217 }
218 
219 int
220 ecdsa_sign(int type, const unsigned char *digest, int digest_len,
221     unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv,
222     const BIGNUM *r, EC_KEY *key)
223 {
224 	ECDSA_SIG *sig = NULL;
225 	int out_len = 0;
226 	int ret = 0;
227 
228 	if (kinv != NULL || r != NULL) {
229 		ECerror(EC_R_NOT_IMPLEMENTED);
230 		goto err;
231 	}
232 
233 	if ((sig = ECDSA_do_sign(digest, digest_len, key)) == NULL)
234 		goto err;
235 
236 	if ((out_len = i2d_ECDSA_SIG(sig, &signature)) < 0) {
237 		out_len = 0;
238 		goto err;
239 	}
240 
241 	ret = 1;
242 
243  err:
244 	*signature_len = out_len;
245 	ECDSA_SIG_free(sig);
246 
247 	return ret;
248 }
249 
250 int
251 ECDSA_sign(int type, const unsigned char *digest, int digest_len,
252     unsigned char *signature, unsigned int *signature_len, EC_KEY *key)
253 {
254 	if (key->meth->sign == NULL) {
255 		ECerror(EC_R_NOT_IMPLEMENTED);
256 		return 0;
257 	}
258 	return key->meth->sign(type, digest, digest_len, signature,
259 	    signature_len, NULL, NULL, key);
260 }
261 LCRYPTO_ALIAS(ECDSA_sign);
262 
263 /*
264  * FIPS 186-5, section 6.4.1, steps 3-8 and 11: Generate k, calculate r and
265  * kinv. If r == 0, try again with a new random k.
266  */
267 
268 int
269 ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, BIGNUM **out_r)
270 {
271 	const EC_GROUP *group;
272 	EC_POINT *point = NULL;
273 	BN_CTX *ctx = NULL;
274 	BIGNUM *k = NULL, *r = NULL;
275 	const BIGNUM *order;
276 	BIGNUM *x;
277 	int order_bits;
278 	int ret = 0;
279 
280 	BN_free(*out_kinv);
281 	*out_kinv = NULL;
282 
283 	BN_free(*out_r);
284 	*out_r = NULL;
285 
286 	if (key == NULL) {
287 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
288 		goto err;
289 	}
290 	if ((group = EC_KEY_get0_group(key)) == NULL) {
291 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
292 		goto err;
293 	}
294 
295 	if ((k = BN_new()) == NULL)
296 		goto err;
297 	if ((r = BN_new()) == NULL)
298 		goto err;
299 
300 	if ((ctx = in_ctx) == NULL)
301 		ctx = BN_CTX_new();
302 	if (ctx == NULL) {
303 		ECerror(ERR_R_MALLOC_FAILURE);
304 		goto err;
305 	}
306 
307 	BN_CTX_start(ctx);
308 
309 	if ((x = BN_CTX_get(ctx)) == NULL)
310 		goto err;
311 
312 	if ((point = EC_POINT_new(group)) == NULL) {
313 		ECerror(ERR_R_EC_LIB);
314 		goto err;
315 	}
316 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
317 		ECerror(ERR_R_EC_LIB);
318 		goto err;
319 	}
320 
321 	if (BN_cmp(order, BN_value_one()) <= 0) {
322 		ECerror(EC_R_INVALID_GROUP_ORDER);
323 		goto err;
324 	}
325 
326 	/* Reject curves with an order that is smaller than 80 bits. */
327 	if ((order_bits = BN_num_bits(order)) < 80) {
328 		ECerror(EC_R_INVALID_GROUP_ORDER);
329 		goto err;
330 	}
331 
332 	/* Preallocate space. */
333 	if (!BN_set_bit(k, order_bits) ||
334 	    !BN_set_bit(r, order_bits) ||
335 	    !BN_set_bit(x, order_bits))
336 		goto err;
337 
338 	/* Step 11: repeat until r != 0. */
339 	do {
340 		/* Step 3: generate random k. */
341 		if (!bn_rand_interval(k, BN_value_one(), order))
342 			goto err;
343 
344 		/*
345 		 * We do not want timing information to leak the length of k,
346 		 * so we compute G * k using an equivalent scalar of fixed
347 		 * bit-length.
348 		 *
349 		 * We unconditionally perform both of these additions to prevent
350 		 * a small timing information leakage.  We then choose the sum
351 		 * that is one bit longer than the order.  This guarantees the
352 		 * code path used in the constant time implementations
353 		 * elsewhere.
354 		 *
355 		 * TODO: revisit the bn_copy aiming for a memory access agnostic
356 		 * conditional copy.
357 		 */
358 		if (!BN_add(r, k, order) ||
359 		    !BN_add(x, r, order) ||
360 		    !bn_copy(k, BN_num_bits(r) > order_bits ? r : x))
361 			goto err;
362 
363 		BN_set_flags(k, BN_FLG_CONSTTIME);
364 
365 		/* Step 5: P = k * G. */
366 		if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) {
367 			ECerror(ERR_R_EC_LIB);
368 			goto err;
369 		}
370 		/* Steps 6 (and 7): from P = (x, y) retain the x-coordinate. */
371 		if (!EC_POINT_get_affine_coordinates(group, point, x, NULL,
372 		    ctx)) {
373 			ECerror(ERR_R_EC_LIB);
374 			goto err;
375 		}
376 		/* Step 8: r = x (mod order). */
377 		if (!BN_nnmod(r, x, order, ctx)) {
378 			ECerror(ERR_R_BN_LIB);
379 			goto err;
380 		}
381 	} while (BN_is_zero(r));
382 
383 	/* Step 4: calculate kinv. */
384 	if (BN_mod_inverse_ct(k, k, order, ctx) == NULL) {
385 		ECerror(ERR_R_BN_LIB);
386 		goto err;
387 	}
388 
389 	*out_kinv = k;
390 	k = NULL;
391 
392 	*out_r = r;
393 	r = NULL;
394 
395 	ret = 1;
396 
397  err:
398 	BN_CTX_end(ctx);
399 	if (ctx != in_ctx)
400 		BN_CTX_free(ctx);
401 	BN_free(k);
402 	BN_free(r);
403 	EC_POINT_free(point);
404 
405 	return ret;
406 }
407 
408 static int
409 ECDSA_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv,
410     BIGNUM **out_r)
411 {
412 	if (key->meth->sign_setup == NULL) {
413 		ECerror(EC_R_NOT_IMPLEMENTED);
414 		return 0;
415 	}
416 	return key->meth->sign_setup(key, in_ctx, out_kinv, out_r);
417 }
418 
419 /*
420  * FIPS 186-5, section 6.4.1, step 9: compute s = inv(k)(e + xr) mod order.
421  * In order to reduce the possibility of a side-channel attack, the following
422  * is calculated using a random blinding value b in [1, order):
423  * s = inv(b)(be + bxr)inv(k) mod order.
424  */
425 
426 static int
427 ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *e, const BIGNUM *kinv,
428     const BIGNUM *r, const EC_KEY *key, BN_CTX *ctx)
429 {
430 	const EC_GROUP *group;
431 	const BIGNUM *order, *priv_key;
432 	BIGNUM *b, *binv, *be, *bxr;
433 	BIGNUM *s = NULL;
434 	int ret = 0;
435 
436 	*out_s = NULL;
437 
438 	BN_CTX_start(ctx);
439 
440 	if ((group = EC_KEY_get0_group(key)) == NULL) {
441 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
442 		goto err;
443 	}
444 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
445 		ECerror(ERR_R_EC_LIB);
446 		goto err;
447 	}
448 	if ((priv_key = EC_KEY_get0_private_key(key)) == NULL) {
449 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
450 		goto err;
451 	}
452 
453 	if ((b = BN_CTX_get(ctx)) == NULL)
454 		goto err;
455 	if ((binv = BN_CTX_get(ctx)) == NULL)
456 		goto err;
457 	if ((be = BN_CTX_get(ctx)) == NULL)
458 		goto err;
459 	if ((bxr = BN_CTX_get(ctx)) == NULL)
460 		goto err;
461 
462 	if ((s = BN_new()) == NULL)
463 		goto err;
464 
465 	/*
466 	 * In a valid ECDSA signature, r must be in [1, order). Since r can be
467 	 * caller provided - either directly or by replacing sign_setup() - we
468 	 * can't rely on this being the case.
469 	 */
470 	if (BN_cmp(r, BN_value_one()) < 0 || BN_cmp(r, order) >= 0) {
471 		ECerror(EC_R_BAD_SIGNATURE);
472 		goto err;
473 	}
474 
475 	if (!bn_rand_interval(b, BN_value_one(), order)) {
476 		ECerror(ERR_R_BN_LIB);
477 		goto err;
478 	}
479 
480 	if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) {
481 		ECerror(ERR_R_BN_LIB);
482 		goto err;
483 	}
484 
485 	if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) {
486 		ECerror(ERR_R_BN_LIB);
487 		goto err;
488 	}
489 	if (!BN_mod_mul(bxr, bxr, r, order, ctx)) {
490 		ECerror(ERR_R_BN_LIB);
491 		goto err;
492 	}
493 	if (!BN_mod_mul(be, b, e, order, ctx)) {
494 		ECerror(ERR_R_BN_LIB);
495 		goto err;
496 	}
497 	if (!BN_mod_add(s, be, bxr, order, ctx)) {
498 		ECerror(ERR_R_BN_LIB);
499 		goto err;
500 	}
501 	/* s = b(e + xr)k^-1 */
502 	if (!BN_mod_mul(s, s, kinv, order, ctx)) {
503 		ECerror(ERR_R_BN_LIB);
504 		goto err;
505 	}
506 	/* s = (e + xr)k^-1 */
507 	if (!BN_mod_mul(s, s, binv, order, ctx)) {
508 		ECerror(ERR_R_BN_LIB);
509 		goto err;
510 	}
511 
512 	/* Step 11: if s == 0 start over. */
513 	if (!BN_is_zero(s)) {
514 		*out_s = s;
515 		s = NULL;
516 	}
517 
518 	ret = 1;
519 
520  err:
521 	BN_CTX_end(ctx);
522 	BN_free(s);
523 
524 	return ret;
525 }
526 
527 /*
528  * It is too expensive to check curve parameters on every sign operation.
529  * Instead, cap the number of retries. A single retry is very unlikely, so
530  * allowing 32 retries is amply enough.
531  */
532 #define ECDSA_MAX_SIGN_ITERATIONS		32
533 
534 /*
535  * FIPS 186-5: Section 6.4.1: ECDSA signature generation, steps 2-12.
536  * The caller provides the hash of the message, thus performs step 1.
537  * Step 10, zeroing k and kinv, is done by BN_free().
538  */
539 
540 ECDSA_SIG *
541 ecdsa_sign_sig(const unsigned char *digest, int digest_len,
542     const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *key)
543 {
544 	BN_CTX *ctx = NULL;
545 	BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
546 	BIGNUM *e;
547 	int attempts = 0;
548 	ECDSA_SIG *sig = NULL;
549 
550 	if (in_kinv != NULL || in_r != NULL) {
551 		ECerror(EC_R_NOT_IMPLEMENTED);
552 		goto err;
553 	}
554 
555 	if ((ctx = BN_CTX_new()) == NULL) {
556 		ECerror(ERR_R_MALLOC_FAILURE);
557 		goto err;
558 	}
559 
560 	BN_CTX_start(ctx);
561 
562 	if ((e = BN_CTX_get(ctx)) == NULL)
563 		goto err;
564 
565 	/* Step 2: convert hash into an integer. */
566 	if (!ecdsa_prepare_digest(digest, digest_len, key, e))
567 		goto err;
568 
569 	do {
570 		/* Steps 3-8: calculate kinv and r. */
571 		if (!ECDSA_sign_setup(key, ctx, &kinv, &r)) {
572 			ECerror(ERR_R_EC_LIB);
573 			goto err;
574 		}
575 
576 		/*
577 		 * Steps 9 and 11: if s is non-NULL, we have a valid signature.
578 		 */
579 		if (!ecdsa_compute_s(&s, e, kinv, r, key, ctx))
580 			goto err;
581 		if (s != NULL)
582 			break;
583 
584 		if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) {
585 			ECerror(EC_R_WRONG_CURVE_PARAMETERS);
586 			goto err;
587 		}
588 	} while (1);
589 
590 	/* Step 12: output (r, s). */
591 	if ((sig = ECDSA_SIG_new()) == NULL) {
592 		ECerror(ERR_R_MALLOC_FAILURE);
593 		goto err;
594 	}
595 	if (!ECDSA_SIG_set0(sig, r, s)) {
596 		ECDSA_SIG_free(sig);
597 		goto err;
598 	}
599 	r = NULL;
600 	s = NULL;
601 
602  err:
603 	BN_CTX_end(ctx);
604 	BN_CTX_free(ctx);
605 	BN_free(kinv);
606 	BN_free(r);
607 	BN_free(s);
608 
609 	return sig;
610 }
611 
612 ECDSA_SIG *
613 ECDSA_do_sign(const unsigned char *digest, int digest_len, EC_KEY *key)
614 {
615 	if (key->meth->sign_sig == NULL) {
616 		ECerror(EC_R_NOT_IMPLEMENTED);
617 		return 0;
618 	}
619 	return key->meth->sign_sig(digest, digest_len, NULL, NULL, key);
620 }
621 LCRYPTO_ALIAS(ECDSA_do_sign);
622 
623 int
624 ecdsa_verify(int type, const unsigned char *digest, int digest_len,
625     const unsigned char *sigbuf, int sig_len, EC_KEY *key)
626 {
627 	ECDSA_SIG *s;
628 	unsigned char *der = NULL;
629 	const unsigned char *p;
630 	int der_len = 0;
631 	int ret = -1;
632 
633 	if ((s = ECDSA_SIG_new()) == NULL)
634 		goto err;
635 
636 	p = sigbuf;
637 	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
638 		goto err;
639 
640 	/* Ensure signature uses DER and doesn't have trailing garbage. */
641 	if ((der_len = i2d_ECDSA_SIG(s, &der)) != sig_len)
642 		goto err;
643 	if (timingsafe_memcmp(sigbuf, der, der_len))
644 		goto err;
645 
646 	ret = ECDSA_do_verify(digest, digest_len, s, key);
647 
648  err:
649 	freezero(der, der_len);
650 	ECDSA_SIG_free(s);
651 
652 	return ret;
653 }
654 
655 int
656 ECDSA_verify(int type, const unsigned char *digest, int digest_len,
657     const unsigned char *sigbuf, int sig_len, EC_KEY *key)
658 {
659 	if (key->meth->verify == NULL) {
660 		ECerror(EC_R_NOT_IMPLEMENTED);
661 		return 0;
662 	}
663 	return key->meth->verify(type, digest, digest_len, sigbuf, sig_len, key);
664 }
665 LCRYPTO_ALIAS(ECDSA_verify);
666 
667 /*
668  * FIPS 186-5, section 6.4.2: ECDSA signature verification.
669  * The caller provides us with the hash of the message, so has performed step 2.
670  */
671 
672 int
673 ecdsa_verify_sig(const unsigned char *digest, int digest_len,
674     const ECDSA_SIG *sig, EC_KEY *key)
675 {
676 	const EC_GROUP *group;
677 	const EC_POINT *pub_key;
678 	EC_POINT *point = NULL;
679 	const BIGNUM *order;
680 	BN_CTX *ctx = NULL;
681 	BIGNUM *e, *sinv, *u, *v, *x;
682 	int ret = -1;
683 
684 	if (key == NULL || sig == NULL) {
685 		ECerror(EC_R_MISSING_PARAMETERS);
686 		goto err;
687 	}
688 	if ((group = EC_KEY_get0_group(key)) == NULL) {
689 		ECerror(EC_R_MISSING_PARAMETERS);
690 		goto err;
691 	}
692 	if ((pub_key = EC_KEY_get0_public_key(key)) == NULL) {
693 		ECerror(EC_R_MISSING_PARAMETERS);
694 		goto err;
695 	}
696 
697 	if ((ctx = BN_CTX_new()) == NULL) {
698 		ECerror(ERR_R_MALLOC_FAILURE);
699 		goto err;
700 	}
701 
702 	BN_CTX_start(ctx);
703 
704 	if ((e = BN_CTX_get(ctx)) == NULL)
705 		goto err;
706 	if ((sinv = BN_CTX_get(ctx)) == NULL)
707 		goto err;
708 	if ((u = BN_CTX_get(ctx)) == NULL)
709 		goto err;
710 	if ((v = BN_CTX_get(ctx)) == NULL)
711 		goto err;
712 	if ((x = BN_CTX_get(ctx)) == NULL)
713 		goto err;
714 
715 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
716 		ECerror(ERR_R_EC_LIB);
717 		goto err;
718 	}
719 
720 	/* Step 1: verify that r and s are in the range [1, order). */
721 	if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) {
722 		ECerror(EC_R_BAD_SIGNATURE);
723 		ret = 0;
724 		goto err;
725 	}
726 	if (BN_cmp(sig->s, BN_value_one()) < 0 || BN_cmp(sig->s, order) >= 0) {
727 		ECerror(EC_R_BAD_SIGNATURE);
728 		ret = 0;
729 		goto err;
730 	}
731 
732 	/* Step 3: convert the hash into an integer. */
733 	if (!ecdsa_prepare_digest(digest, digest_len, key, e))
734 		goto err;
735 
736 	/* Step 4: compute the inverse of s modulo order. */
737 	if (BN_mod_inverse_ct(sinv, sig->s, order, ctx) == NULL) {
738 		ECerror(ERR_R_BN_LIB);
739 		goto err;
740 	}
741 	/* Step 5: compute u = s^-1 * e and v = s^-1 * r (modulo order). */
742 	if (!BN_mod_mul(u, e, sinv, order, ctx)) {
743 		ECerror(ERR_R_BN_LIB);
744 		goto err;
745 	}
746 	if (!BN_mod_mul(v, sig->r, sinv, order, ctx)) {
747 		ECerror(ERR_R_BN_LIB);
748 		goto err;
749 	}
750 
751 	/*
752 	 * Steps 6 and 7: compute R = G * u + pub_key * v = (x, y). Reject if
753 	 * it's the point at infinity - getting affine coordinates fails. Keep
754 	 * the x coordinate.
755 	 */
756 	if ((point = EC_POINT_new(group)) == NULL) {
757 		ECerror(ERR_R_MALLOC_FAILURE);
758 		goto err;
759 	}
760 	if (!EC_POINT_mul(group, point, u, pub_key, v, ctx)) {
761 		ECerror(ERR_R_EC_LIB);
762 		goto err;
763 	}
764 	if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, ctx)) {
765 		ECerror(ERR_R_EC_LIB);
766 		goto err;
767 	}
768 	/* Step 8: convert x to a number in [0, order). */
769 	if (!BN_nnmod(x, x, order, ctx)) {
770 		ECerror(ERR_R_BN_LIB);
771 		goto err;
772 	}
773 
774 	/* Step 9: the signature is valid iff the x-coordinate is equal to r. */
775 	ret = (BN_cmp(x, sig->r) == 0);
776 
777  err:
778 	BN_CTX_end(ctx);
779 	BN_CTX_free(ctx);
780 	EC_POINT_free(point);
781 
782 	return ret;
783 }
784 
785 int
786 ECDSA_do_verify(const unsigned char *digest, int digest_len,
787     const ECDSA_SIG *sig, EC_KEY *key)
788 {
789 	if (key->meth->verify_sig == NULL) {
790 		ECerror(EC_R_NOT_IMPLEMENTED);
791 		return 0;
792 	}
793 	return key->meth->verify_sig(digest, digest_len, sig, key);
794 }
795 LCRYPTO_ALIAS(ECDSA_do_verify);
796