diff options
author | tb <> | 2023-07-04 14:59:32 +0000 |
---|---|---|
committer | tb <> | 2023-07-04 14:59:32 +0000 |
commit | c6e12a51459163768f29eb01b0356016f3f5b793 (patch) | |
tree | cab8a358a80130c18566b00e2392af599047d40b | |
parent | 1f34fd05738e4ace8b7be84c9441adc6f601d5f8 (diff) | |
download | openbsd-c6e12a51459163768f29eb01b0356016f3f5b793.tar.gz openbsd-c6e12a51459163768f29eb01b0356016f3f5b793.tar.bz2 openbsd-c6e12a51459163768f29eb01b0356016f3f5b793.zip |
Clean up ECDSA verification
Use variable names that correspond more closely to the standard. Use an
additional variable for s^-1 for readability. Annotate the code with
the corresponding steps from FIPS 186-5.
ok jsing
-rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 685ba6e6c7..de51d3aa4a 100644 --- a/src/lib/libcrypto/ecdsa/ecs_ossl.c +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ecs_ossl.c,v 1.69 2023/07/04 14:57:05 tb Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.70 2023/07/04 14:59:32 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project |
4 | */ | 4 | */ |
@@ -506,6 +506,11 @@ ossl_ecdsa_verify(int type, const unsigned char *digest, int digest_len, | |||
506 | return ret; | 506 | return ret; |
507 | } | 507 | } |
508 | 508 | ||
509 | /* | ||
510 | * FIPS 186-5, section 6.4.2: ECDSA signature verification. | ||
511 | * The caller provides us with the hash of the message, so has performed step 2. | ||
512 | */ | ||
513 | |||
509 | int | 514 | int |
510 | ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | 515 | ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, |
511 | const ECDSA_SIG *sig, EC_KEY *key) | 516 | const ECDSA_SIG *sig, EC_KEY *key) |
@@ -515,7 +520,7 @@ ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | |||
515 | EC_POINT *point = NULL; | 520 | EC_POINT *point = NULL; |
516 | const BIGNUM *order; | 521 | const BIGNUM *order; |
517 | BN_CTX *ctx = NULL; | 522 | BN_CTX *ctx = NULL; |
518 | BIGNUM *u1, *u2, *e, *x; | 523 | BIGNUM *e, *sinv, *u, *v, *x; |
519 | int ret = -1; | 524 | int ret = -1; |
520 | 525 | ||
521 | if (key == NULL || sig == NULL) { | 526 | if (key == NULL || sig == NULL) { |
@@ -538,11 +543,13 @@ ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | |||
538 | 543 | ||
539 | BN_CTX_start(ctx); | 544 | BN_CTX_start(ctx); |
540 | 545 | ||
541 | if ((u1 = BN_CTX_get(ctx)) == NULL) | 546 | if ((e = BN_CTX_get(ctx)) == NULL) |
542 | goto err; | 547 | goto err; |
543 | if ((u2 = BN_CTX_get(ctx)) == NULL) | 548 | if ((sinv = BN_CTX_get(ctx)) == NULL) |
544 | goto err; | 549 | goto err; |
545 | if ((e = BN_CTX_get(ctx)) == NULL) | 550 | if ((u = BN_CTX_get(ctx)) == NULL) |
551 | goto err; | ||
552 | if ((v = BN_CTX_get(ctx)) == NULL) | ||
546 | goto err; | 553 | goto err; |
547 | if ((x = BN_CTX_get(ctx)) == NULL) | 554 | if ((x = BN_CTX_get(ctx)) == NULL) |
548 | goto err; | 555 | goto err; |
@@ -552,7 +559,7 @@ ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | |||
552 | goto err; | 559 | goto err; |
553 | } | 560 | } |
554 | 561 | ||
555 | /* Verify that r and s are in the range [1, order). */ | 562 | /* Step 1: verify that r and s are in the range [1, order). */ |
556 | if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) { | 563 | if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) { |
557 | ECDSAerror(ECDSA_R_BAD_SIGNATURE); | 564 | ECDSAerror(ECDSA_R_BAD_SIGNATURE); |
558 | ret = 0; | 565 | ret = 0; |
@@ -564,28 +571,35 @@ ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | |||
564 | goto err; | 571 | goto err; |
565 | } | 572 | } |
566 | 573 | ||
574 | /* Step 3: convert the hash into an integer. */ | ||
567 | if (!ecdsa_prepare_digest(digest, digest_len, key, e)) | 575 | if (!ecdsa_prepare_digest(digest, digest_len, key, e)) |
568 | goto err; | 576 | goto err; |
569 | 577 | ||
570 | if (BN_mod_inverse_ct(u2, sig->s, order, ctx) == NULL) { /* w = inv(s) */ | 578 | /* Step 4: compute the inverse of s modulo order. */ |
579 | if (BN_mod_inverse_ct(sinv, sig->s, order, ctx) == NULL) { | ||
571 | ECDSAerror(ERR_R_BN_LIB); | 580 | ECDSAerror(ERR_R_BN_LIB); |
572 | goto err; | 581 | goto err; |
573 | } | 582 | } |
574 | if (!BN_mod_mul(u1, e, u2, order, ctx)) { /* u1 = ew */ | 583 | /* Step 5: compute u = s^-1 * e and v = s^-1 * r (modulo order). */ |
584 | if (!BN_mod_mul(u, e, sinv, order, ctx)) { | ||
575 | ECDSAerror(ERR_R_BN_LIB); | 585 | ECDSAerror(ERR_R_BN_LIB); |
576 | goto err; | 586 | goto err; |
577 | } | 587 | } |
578 | if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { /* u2 = rw */ | 588 | if (!BN_mod_mul(v, sig->r, sinv, order, ctx)) { |
579 | ECDSAerror(ERR_R_BN_LIB); | 589 | ECDSAerror(ERR_R_BN_LIB); |
580 | goto err; | 590 | goto err; |
581 | } | 591 | } |
582 | 592 | ||
583 | /* Compute the x-coordinate of G * u1 + pub_key * u2. */ | 593 | /* |
594 | * Steps 6 and 7: compute R = G * u + pub_key * v = (x, y). Reject if | ||
595 | * it's the point at infinity - getting affine coordinates fails. Keep | ||
596 | * the x coordinate. | ||
597 | */ | ||
584 | if ((point = EC_POINT_new(group)) == NULL) { | 598 | if ((point = EC_POINT_new(group)) == NULL) { |
585 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 599 | ECDSAerror(ERR_R_MALLOC_FAILURE); |
586 | goto err; | 600 | goto err; |
587 | } | 601 | } |
588 | if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { | 602 | if (!EC_POINT_mul(group, point, u, pub_key, v, ctx)) { |
589 | ECDSAerror(ERR_R_EC_LIB); | 603 | ECDSAerror(ERR_R_EC_LIB); |
590 | goto err; | 604 | goto err; |
591 | } | 605 | } |
@@ -593,13 +607,14 @@ ossl_ecdsa_verify_sig(const unsigned char *digest, int digest_len, | |||
593 | ECDSAerror(ERR_R_EC_LIB); | 607 | ECDSAerror(ERR_R_EC_LIB); |
594 | goto err; | 608 | goto err; |
595 | } | 609 | } |
596 | if (!BN_nnmod(u1, x, order, ctx)) { | 610 | /* Step 8: convert x to a number in [0, order). */ |
611 | if (!BN_nnmod(x, x, order, ctx)) { | ||
597 | ECDSAerror(ERR_R_BN_LIB); | 612 | ECDSAerror(ERR_R_BN_LIB); |
598 | goto err; | 613 | goto err; |
599 | } | 614 | } |
600 | 615 | ||
601 | /* If the signature is correct, the x-coordinate is equal to sig->r. */ | 616 | /* Step 9: the signature is valid iff the x-coordinate is equal to r. */ |
602 | ret = (BN_cmp(u1, sig->r) == 0); | 617 | ret = (BN_cmp(x, sig->r) == 0); |
603 | 618 | ||
604 | err: | 619 | err: |
605 | BN_CTX_end(ctx); | 620 | BN_CTX_end(ctx); |