summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ecdsa/ecdsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ecdsa/ecdsa.c')
-rw-r--r--src/lib/libcrypto/ecdsa/ecdsa.c821
1 files changed, 821 insertions, 0 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecdsa.c b/src/lib/libcrypto/ecdsa/ecdsa.c
new file mode 100644
index 0000000000..c831e9f716
--- /dev/null
+++ b/src/lib/libcrypto/ecdsa/ecdsa.c
@@ -0,0 +1,821 @@
1/* $OpenBSD: ecdsa.c,v 1.1 2023/07/05 12:18:21 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 <string.h>
57
58#include <openssl/opensslconf.h>
59
60#include <openssl/asn1t.h>
61#include <openssl/bn.h>
62#include <openssl/err.h>
63#include <openssl/evp.h>
64#include <openssl/objects.h>
65
66#include "bn_local.h"
67#include "ec_local.h"
68#include "ecdsa_local.h"
69
70static 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
87const 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
97ECDSA_SIG *ECDSA_SIG_new(void);
98void ECDSA_SIG_free(ECDSA_SIG *a);
99ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len);
100int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out);
101
102ECDSA_SIG *
103d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len)
104{
105 return (ECDSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
106 &ECDSA_SIG_it);
107}
108
109int
110i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out)
111{
112 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECDSA_SIG_it);
113}
114
115ECDSA_SIG *
116ECDSA_SIG_new(void)
117{
118 return (ECDSA_SIG *)ASN1_item_new(&ECDSA_SIG_it);
119}
120
121void
122ECDSA_SIG_free(ECDSA_SIG *a)
123{
124 ASN1_item_free((ASN1_VALUE *)a, &ECDSA_SIG_it);
125}
126
127void
128ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
129{
130 if (pr != NULL)
131 *pr = sig->r;
132 if (ps != NULL)
133 *ps = sig->s;
134}
135
136const BIGNUM *
137ECDSA_SIG_get0_r(const ECDSA_SIG *sig)
138{
139 return sig->r;
140}
141
142const BIGNUM *
143ECDSA_SIG_get0_s(const ECDSA_SIG *sig)
144{
145 return sig->s;
146}
147
148int
149ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
150{
151 if (r == NULL || s == NULL)
152 return 0;
153
154 BN_free(sig->r);
155 BN_free(sig->s);
156 sig->r = r;
157 sig->s = s;
158 return 1;
159}
160
161/*
162 * FIPS 186-5, section 6.4.1, step 2: convert hashed message into an integer.
163 * Use the order_bits leftmost bits if it exceeds the group order.
164 */
165static int
166ecdsa_prepare_digest(const unsigned char *digest, int digest_len,
167 const EC_KEY *key, BIGNUM *e)
168{
169 const EC_GROUP *group;
170 int digest_bits, order_bits;
171
172 if (!BN_bin2bn(digest, digest_len, e)) {
173 ECDSAerror(ERR_R_BN_LIB);
174 return 0;
175 }
176
177 if ((group = EC_KEY_get0_group(key)) == NULL)
178 return 0;
179 order_bits = EC_GROUP_order_bits(group);
180
181 digest_bits = 8 * digest_len;
182 if (digest_bits <= order_bits)
183 return 1;
184
185 return BN_rshift(e, e, digest_bits - order_bits);
186}
187
188int
189ecdsa_sign(int type, const unsigned char *digest, int digest_len,
190 unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv,
191 const BIGNUM *r, EC_KEY *key)
192{
193 ECDSA_SIG *sig;
194 int out_len = 0;
195 int ret = 0;
196
197 if ((sig = ECDSA_do_sign_ex(digest, digest_len, kinv, r, key)) == NULL)
198 goto err;
199
200 if ((out_len = i2d_ECDSA_SIG(sig, &signature)) < 0) {
201 out_len = 0;
202 goto err;
203 }
204
205 ret = 1;
206
207 err:
208 *signature_len = out_len;
209 ECDSA_SIG_free(sig);
210
211 return ret;
212}
213
214/*
215 * FIPS 186-5, section 6.4.1, steps 3-8 and 11: Generate k, calculate r and
216 * kinv, and clear it. If r == 0, try again with a new random k.
217 */
218
219int
220ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, BIGNUM **out_r)
221{
222 const EC_GROUP *group;
223 EC_POINT *point = NULL;
224 BN_CTX *ctx = NULL;
225 BIGNUM *k = NULL, *r = NULL;
226 const BIGNUM *order;
227 BIGNUM *x;
228 int order_bits;
229 int ret = 0;
230
231 BN_free(*out_kinv);
232 *out_kinv = NULL;
233
234 BN_free(*out_r);
235 *out_r = NULL;
236
237 if (key == NULL) {
238 ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
239 goto err;
240 }
241 if ((group = EC_KEY_get0_group(key)) == NULL) {
242 ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
243 goto err;
244 }
245
246 if ((k = BN_new()) == NULL)
247 goto err;
248 if ((r = BN_new()) == NULL)
249 goto err;
250
251 if ((ctx = in_ctx) == NULL)
252 ctx = BN_CTX_new();
253 if (ctx == NULL) {
254 ECDSAerror(ERR_R_MALLOC_FAILURE);
255 goto err;
256 }
257
258 BN_CTX_start(ctx);
259
260 if ((x = BN_CTX_get(ctx)) == NULL)
261 goto err;
262
263 if ((point = EC_POINT_new(group)) == NULL) {
264 ECDSAerror(ERR_R_EC_LIB);
265 goto err;
266 }
267 if ((order = EC_GROUP_get0_order(group)) == NULL) {
268 ECDSAerror(ERR_R_EC_LIB);
269 goto err;
270 }
271
272 if (BN_cmp(order, BN_value_one()) <= 0) {
273 ECDSAerror(EC_R_INVALID_GROUP_ORDER);
274 goto err;
275 }
276
277 /* Reject curves with an order that is smaller than 80 bits. */
278 if ((order_bits = BN_num_bits(order)) < 80) {
279 ECDSAerror(EC_R_INVALID_GROUP_ORDER);
280 goto err;
281 }
282
283 /* Preallocate space. */
284 if (!BN_set_bit(k, order_bits) ||
285 !BN_set_bit(r, order_bits) ||
286 !BN_set_bit(x, order_bits))
287 goto err;
288
289 /* Step 11: repeat until r != 0. */
290 do {
291 /* Step 3: generate random k. */
292 if (!bn_rand_interval(k, BN_value_one(), order)) {
293 ECDSAerror(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
294 goto err;
295 }
296
297 /*
298 * We do not want timing information to leak the length of k,
299 * so we compute G * k using an equivalent scalar of fixed
300 * bit-length.
301 *
302 * We unconditionally perform both of these additions to prevent
303 * a small timing information leakage. We then choose the sum
304 * that is one bit longer than the order. This guarantees the
305 * code path used in the constant time implementations
306 * elsewhere.
307 *
308 * TODO: revisit the bn_copy aiming for a memory access agnostic
309 * conditional copy.
310 */
311 if (!BN_add(r, k, order) ||
312 !BN_add(x, r, order) ||
313 !bn_copy(k, BN_num_bits(r) > order_bits ? r : x))
314 goto err;
315
316 BN_set_flags(k, BN_FLG_CONSTTIME);
317
318 /* Step 5: P = k * G. */
319 if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) {
320 ECDSAerror(ERR_R_EC_LIB);
321 goto err;
322 }
323 /* Steps 6 (and 7): from P = (x, y) retain the x-coordinate. */
324 if (!EC_POINT_get_affine_coordinates(group, point, x, NULL,
325 ctx)) {
326 ECDSAerror(ERR_R_EC_LIB);
327 goto err;
328 }
329 /* Step 8: r = x (mod order). */
330 if (!BN_nnmod(r, x, order, ctx)) {
331 ECDSAerror(ERR_R_BN_LIB);
332 goto err;
333 }
334 } while (BN_is_zero(r));
335
336 /* Step 4: calculate kinv. */
337 if (BN_mod_inverse_ct(k, k, order, ctx) == NULL) {
338 ECDSAerror(ERR_R_BN_LIB);
339 goto err;
340 }
341
342 *out_kinv = k;
343 k = NULL;
344
345 *out_r = r;
346 r = NULL;
347
348 ret = 1;
349
350 err:
351 BN_CTX_end(ctx);
352 if (ctx != in_ctx)
353 BN_CTX_free(ctx);
354 BN_free(k);
355 BN_free(r);
356 EC_POINT_free(point);
357
358 return ret;
359}
360
361/*
362 * FIPS 186-5, section 6.4.1, step 9: compute s = inv(k)(e + xr) mod order.
363 * In order to reduce the possibility of a side-channel attack, the following
364 * is calculated using a random blinding value b in [1, order):
365 * s = inv(b)(be + bxr)inv(k) mod order.
366 */
367
368static int
369ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *e, const BIGNUM *kinv,
370 const BIGNUM *r, const EC_KEY *key, BN_CTX *ctx)
371{
372 const EC_GROUP *group;
373 const BIGNUM *order, *priv_key;
374 BIGNUM *b, *binv, *be, *bxr;
375 BIGNUM *s = NULL;
376 int ret = 0;
377
378 *out_s = NULL;
379
380 BN_CTX_start(ctx);
381
382 if ((group = EC_KEY_get0_group(key)) == NULL) {
383 ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
384 goto err;
385 }
386 if ((order = EC_GROUP_get0_order(group)) == NULL) {
387 ECDSAerror(ERR_R_EC_LIB);
388 goto err;
389 }
390 if ((priv_key = EC_KEY_get0_private_key(key)) == NULL) {
391 ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
392 goto err;
393 }
394
395 if ((b = BN_CTX_get(ctx)) == NULL)
396 goto err;
397 if ((binv = BN_CTX_get(ctx)) == NULL)
398 goto err;
399 if ((be = BN_CTX_get(ctx)) == NULL)
400 goto err;
401 if ((bxr = BN_CTX_get(ctx)) == NULL)
402 goto err;
403
404 if ((s = BN_new()) == NULL)
405 goto err;
406
407 /*
408 * In a valid ECDSA signature, r must be in [1, order). Since r can be
409 * caller provided - either directly or by replacing sign_setup() - we
410 * can't rely on this being the case.
411 */
412 if (BN_cmp(r, BN_value_one()) < 0 || BN_cmp(r, order) >= 0) {
413 ECDSAerror(ECDSA_R_BAD_SIGNATURE);
414 goto err;
415 }
416
417 if (!bn_rand_interval(b, BN_value_one(), order)) {
418 ECDSAerror(ERR_R_BN_LIB);
419 goto err;
420 }
421
422 if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) {
423 ECDSAerror(ERR_R_BN_LIB);
424 goto err;
425 }
426
427 if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) {
428 ECDSAerror(ERR_R_BN_LIB);
429 goto err;
430 }
431 if (!BN_mod_mul(bxr, bxr, r, order, ctx)) {
432 ECDSAerror(ERR_R_BN_LIB);
433 goto err;
434 }
435 if (!BN_mod_mul(be, b, e, order, ctx)) {
436 ECDSAerror(ERR_R_BN_LIB);
437 goto err;
438 }
439 if (!BN_mod_add(s, be, bxr, order, ctx)) {
440 ECDSAerror(ERR_R_BN_LIB);
441 goto err;
442 }
443 /* s = b(e + xr)k^-1 */
444 if (!BN_mod_mul(s, s, kinv, order, ctx)) {
445 ECDSAerror(ERR_R_BN_LIB);
446 goto err;
447 }
448 /* s = (e + xr)k^-1 */
449 if (!BN_mod_mul(s, s, binv, order, ctx)) {
450 ECDSAerror(ERR_R_BN_LIB);
451 goto err;
452 }
453
454 /* Step 11: if s == 0 start over. */
455 if (!BN_is_zero(s)) {
456 *out_s = s;
457 s = NULL;
458 }
459
460 ret = 1;
461
462 err:
463 BN_CTX_end(ctx);
464 BN_free(s);
465
466 return ret;
467}
468
469/*
470 * It is too expensive to check curve parameters on every sign operation.
471 * Instead, cap the number of retries. A single retry is very unlikely, so
472 * allowing 32 retries is amply enough.
473 */
474#define ECDSA_MAX_SIGN_ITERATIONS 32
475
476/*
477 * FIPS 186-5: Section 6.4.1: ECDSA signature generation, steps 2-12.
478 * The caller provides the hash of the message, thus performs step 1.
479 * Step 10, zeroing k and kinv, is done by BN_free().
480 */
481
482ECDSA_SIG *
483ecdsa_sign_sig(const unsigned char *digest, int digest_len,
484 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *key)
485{
486 BN_CTX *ctx = NULL;
487 BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
488 BIGNUM *e;
489 int caller_supplied_values = 0;
490 int attempts = 0;
491 ECDSA_SIG *sig = NULL;
492
493 if ((ctx = BN_CTX_new()) == NULL) {
494 ECDSAerror(ERR_R_MALLOC_FAILURE);
495 goto err;
496 }
497
498 BN_CTX_start(ctx);
499
500 if ((e = BN_CTX_get(ctx)) == NULL)
501 goto err;
502
503 /* Step 2: convert hash into an integer. */
504 if (!ecdsa_prepare_digest(digest, digest_len, key, e))
505 goto err;
506
507 if (in_kinv != NULL && in_r != NULL) {
508 /*
509 * Use the caller's kinv and r. Don't call ECDSA_sign_setup().
510 * If we're unable to compute a valid signature, the caller
511 * must provide new values.
512 */
513 caller_supplied_values = 1;
514
515 if ((kinv = BN_dup(in_kinv)) == NULL) {
516 ECDSAerror(ERR_R_MALLOC_FAILURE);
517 goto err;
518 }
519 if ((r = BN_dup(in_r)) == NULL) {
520 ECDSAerror(ERR_R_MALLOC_FAILURE);
521 goto err;
522 }
523 }
524
525 do {
526 /* Steps 3-8: calculate kinv and r. */
527 if (!caller_supplied_values) {
528 if (!ECDSA_sign_setup(key, ctx, &kinv, &r)) {
529 ECDSAerror(ERR_R_ECDSA_LIB);
530 goto err;
531 }
532 }
533
534 /*
535 * Steps 9 and 11: if s is non-NULL, we have a valid signature.
536 */
537 if (!ecdsa_compute_s(&s, e, kinv, r, key, ctx))
538 goto err;
539 if (s != NULL)
540 break;
541
542 if (caller_supplied_values) {
543 ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES);
544 goto err;
545 }
546
547 if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) {
548 ECDSAerror(EC_R_WRONG_CURVE_PARAMETERS);
549 goto err;
550 }
551 } while (1);
552
553 /* Step 12: output (r, s). */
554 if ((sig = ECDSA_SIG_new()) == NULL) {
555 ECDSAerror(ERR_R_MALLOC_FAILURE);
556 goto err;
557 }
558 if (!ECDSA_SIG_set0(sig, r, s)) {
559 ECDSA_SIG_free(sig);
560 goto err;
561 }
562 r = NULL;
563 s = NULL;
564
565 err:
566 BN_CTX_end(ctx);
567 BN_CTX_free(ctx);
568 BN_free(kinv);
569 BN_free(r);
570 BN_free(s);
571
572 return sig;
573}
574
575int
576ecdsa_verify(int type, const unsigned char *digest, int digest_len,
577 const unsigned char *sigbuf, int sig_len, EC_KEY *key)
578{
579 ECDSA_SIG *s;
580 unsigned char *der = NULL;
581 const unsigned char *p;
582 int der_len = 0;
583 int ret = -1;
584
585 if ((s = ECDSA_SIG_new()) == NULL)
586 goto err;
587
588 p = sigbuf;
589 if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
590 goto err;
591
592 /* Ensure signature uses DER and doesn't have trailing garbage */
593 if ((der_len = i2d_ECDSA_SIG(s, &der)) != sig_len)
594 goto err;
595 if (timingsafe_memcmp(sigbuf, der, der_len))
596 goto err;
597
598 ret = ECDSA_do_verify(digest, digest_len, s, key);
599
600 err:
601 freezero(der, der_len);
602 ECDSA_SIG_free(s);
603
604 return ret;
605}
606
607/*
608 * FIPS 186-5, section 6.4.2: ECDSA signature verification.
609 * The caller provides us with the hash of the message, so has performed step 2.
610 */
611
612int
613ecdsa_verify_sig(const unsigned char *digest, int digest_len,
614 const ECDSA_SIG *sig, EC_KEY *key)
615{
616 const EC_GROUP *group;
617 const EC_POINT *pub_key;
618 EC_POINT *point = NULL;
619 const BIGNUM *order;
620 BN_CTX *ctx = NULL;
621 BIGNUM *e, *sinv, *u, *v, *x;
622 int ret = -1;
623
624 if (key == NULL || sig == NULL) {
625 ECDSAerror(ECDSA_R_MISSING_PARAMETERS);
626 goto err;
627 }
628 if ((group = EC_KEY_get0_group(key)) == NULL) {
629 ECDSAerror(ECDSA_R_MISSING_PARAMETERS);
630 goto err;
631 }
632 if ((pub_key = EC_KEY_get0_public_key(key)) == NULL) {
633 ECDSAerror(ECDSA_R_MISSING_PARAMETERS);
634 goto err;
635 }
636
637 if ((ctx = BN_CTX_new()) == NULL) {
638 ECDSAerror(ERR_R_MALLOC_FAILURE);
639 goto err;
640 }
641
642 BN_CTX_start(ctx);
643
644 if ((e = BN_CTX_get(ctx)) == NULL)
645 goto err;
646 if ((sinv = BN_CTX_get(ctx)) == NULL)
647 goto err;
648 if ((u = BN_CTX_get(ctx)) == NULL)
649 goto err;
650 if ((v = BN_CTX_get(ctx)) == NULL)
651 goto err;
652 if ((x = BN_CTX_get(ctx)) == NULL)
653 goto err;
654
655 if ((order = EC_GROUP_get0_order(group)) == NULL) {
656 ECDSAerror(ERR_R_EC_LIB);
657 goto err;
658 }
659
660 /* Step 1: verify that r and s are in the range [1, order). */
661 if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) {
662 ECDSAerror(ECDSA_R_BAD_SIGNATURE);
663 ret = 0;
664 goto err;
665 }
666 if (BN_cmp(sig->s, BN_value_one()) < 0 || BN_cmp(sig->s, order) >= 0) {
667 ECDSAerror(ECDSA_R_BAD_SIGNATURE);
668 ret = 0;
669 goto err;
670 }
671
672 /* Step 3: convert the hash into an integer. */
673 if (!ecdsa_prepare_digest(digest, digest_len, key, e))
674 goto err;
675
676 /* Step 4: compute the inverse of s modulo order. */
677 if (BN_mod_inverse_ct(sinv, sig->s, order, ctx) == NULL) {
678 ECDSAerror(ERR_R_BN_LIB);
679 goto err;
680 }
681 /* Step 5: compute u = s^-1 * e and v = s^-1 * r (modulo order). */
682 if (!BN_mod_mul(u, e, sinv, order, ctx)) {
683 ECDSAerror(ERR_R_BN_LIB);
684 goto err;
685 }
686 if (!BN_mod_mul(v, sig->r, sinv, order, ctx)) {
687 ECDSAerror(ERR_R_BN_LIB);
688 goto err;
689 }
690
691 /*
692 * Steps 6 and 7: compute R = G * u + pub_key * v = (x, y). Reject if
693 * it's the point at infinity - getting affine coordinates fails. Keep
694 * the x coordinate.
695 */
696 if ((point = EC_POINT_new(group)) == NULL) {
697 ECDSAerror(ERR_R_MALLOC_FAILURE);
698 goto err;
699 }
700 if (!EC_POINT_mul(group, point, u, pub_key, v, ctx)) {
701 ECDSAerror(ERR_R_EC_LIB);
702 goto err;
703 }
704 if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, ctx)) {
705 ECDSAerror(ERR_R_EC_LIB);
706 goto err;
707 }
708 /* Step 8: convert x to a number in [0, order). */
709 if (!BN_nnmod(x, x, order, ctx)) {
710 ECDSAerror(ERR_R_BN_LIB);
711 goto err;
712 }
713
714 /* Step 9: the signature is valid iff the x-coordinate is equal to r. */
715 ret = (BN_cmp(x, sig->r) == 0);
716
717 err:
718 BN_CTX_end(ctx);
719 BN_CTX_free(ctx);
720 EC_POINT_free(point);
721
722 return ret;
723}
724
725ECDSA_SIG *
726ECDSA_do_sign(const unsigned char *digest, int digest_len, EC_KEY *key)
727{
728 return ECDSA_do_sign_ex(digest, digest_len, NULL, NULL, key);
729}
730
731ECDSA_SIG *
732ECDSA_do_sign_ex(const unsigned char *digest, int digest_len,
733 const BIGNUM *kinv, const BIGNUM *out_r, EC_KEY *key)
734{
735 if (key->meth->sign_sig == NULL) {
736 ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
737 return 0;
738 }
739 return key->meth->sign_sig(digest, digest_len, kinv, out_r, key);
740}
741
742int
743ECDSA_sign(int type, const unsigned char *digest, int digest_len,
744 unsigned char *signature, unsigned int *signature_len, EC_KEY *key)
745{
746 return ECDSA_sign_ex(type, digest, digest_len, signature, signature_len,
747 NULL, NULL, key);
748}
749
750int
751ECDSA_sign_ex(int type, const unsigned char *digest, int digest_len,
752 unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv,
753 const BIGNUM *r, EC_KEY *key)
754{
755 if (key->meth->sign == NULL) {
756 ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
757 return 0;
758 }
759 return key->meth->sign(type, digest, digest_len, signature,
760 signature_len, kinv, r, key);
761}
762
763int
764ECDSA_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv,
765 BIGNUM **out_r)
766{
767 if (key->meth->sign_setup == NULL) {
768 ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
769 return 0;
770 }
771 return key->meth->sign_setup(key, in_ctx, out_kinv, out_r);
772}
773
774int
775ECDSA_do_verify(const unsigned char *digest, int digest_len,
776 const ECDSA_SIG *sig, EC_KEY *key)
777{
778 if (key->meth->verify_sig == NULL) {
779 ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
780 return 0;
781 }
782 return key->meth->verify_sig(digest, digest_len, sig, key);
783}
784
785int
786ECDSA_verify(int type, const unsigned char *digest, int digest_len,
787 const unsigned char *sigbuf, int sig_len, EC_KEY *key)
788{
789 if (key->meth->verify == NULL) {
790 ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
791 return 0;
792 }
793 return key->meth->verify(type, digest, digest_len, sigbuf, sig_len, key);
794}
795
796int
797ECDSA_size(const EC_KEY *r)
798{
799 const EC_GROUP *group;
800 const BIGNUM *order = NULL;
801 ECDSA_SIG sig;
802 int ret = 0;
803
804 if (r == NULL)
805 goto err;
806
807 if ((group = EC_KEY_get0_group(r)) == NULL)
808 goto err;
809
810 if ((order = EC_GROUP_get0_order(group)) == NULL)
811 goto err;
812
813 sig.r = (BIGNUM *)order;
814 sig.s = (BIGNUM *)order;
815
816 if ((ret = i2d_ECDSA_SIG(&sig, NULL)) < 0)
817 ret = 0;
818
819 err:
820 return ret;
821}