diff options
author | tb <> | 2024-10-14 12:50:18 +0000 |
---|---|---|
committer | tb <> | 2024-10-14 12:50:18 +0000 |
commit | eed149b404574c0b530d9a1504778f70e207eb9e (patch) | |
tree | 1776acd39512a7f602594853b647fccf38b8be8b /src | |
parent | 232952b737a80765ddc649d2c2f57e620853cf92 (diff) | |
download | openbsd-eed149b404574c0b530d9a1504778f70e207eb9e.tar.gz openbsd-eed149b404574c0b530d9a1504778f70e207eb9e.tar.bz2 openbsd-eed149b404574c0b530d9a1504778f70e207eb9e.zip |
Fix field element encoding for elliptic curve coefficients
SEC 1, section 2.3.5, is explicit that the encoding of an element of the
field of definition for an elliptic curve needs to be a zero-padded octet
string whose length matches the byte size of the field's degree. So use
BN_bn2binpad() to fix this. Factor things into a simple helper to avoid
copy-pasting.
This gets rid of some of the most grotesque code in this file.
ok jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index acab513748..8d0f032907 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_asn1.c,v 1.70 2024/10/14 12:42:52 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1.c,v 1.71 2024/10/14 12:50:18 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -602,13 +602,39 @@ ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) | |||
602 | } | 602 | } |
603 | 603 | ||
604 | static int | 604 | static int |
605 | ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn, | ||
606 | ASN1_OCTET_STRING *os) | ||
607 | { | ||
608 | unsigned char *buf; | ||
609 | int len; | ||
610 | int ret = 0; | ||
611 | |||
612 | /* Zero-pad field element per SEC 1, section 2.3.5. */ | ||
613 | len = (EC_GROUP_get_degree(group) + 7) / 8; | ||
614 | |||
615 | /* One extra byte for historic NUL termination of ASN1_STRINGs. */ | ||
616 | if ((buf = calloc(1, len + 1)) == NULL) | ||
617 | goto err; | ||
618 | |||
619 | if (BN_bn2binpad(bn, buf, len) != len) | ||
620 | goto err; | ||
621 | |||
622 | ASN1_STRING_set0(os, buf, len); | ||
623 | buf = NULL; | ||
624 | len = 0; | ||
625 | |||
626 | ret = 1; | ||
627 | |||
628 | err: | ||
629 | freezero(buf, len); | ||
630 | |||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | static int | ||
605 | ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) | 635 | ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) |
606 | { | 636 | { |
607 | BIGNUM *a = NULL, *b = NULL; | 637 | BIGNUM *a = NULL, *b = NULL; |
608 | unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL, | ||
609 | *b_buf = NULL; | ||
610 | size_t len_1, len_2; | ||
611 | unsigned char char_zero = 0; | ||
612 | int ret = 0; | 638 | int ret = 0; |
613 | 639 | ||
614 | if (!group || !curve || !curve->a || !curve->b) | 640 | if (!group || !curve || !curve->a || !curve->b) |
@@ -619,50 +645,17 @@ ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) | |||
619 | goto err; | 645 | goto err; |
620 | } | 646 | } |
621 | 647 | ||
622 | /* get a and b */ | ||
623 | if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) { | 648 | if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) { |
624 | ECerror(ERR_R_EC_LIB); | 649 | ECerror(ERR_R_EC_LIB); |
625 | goto err; | 650 | goto err; |
626 | } | 651 | } |
627 | len_1 = (size_t) BN_num_bytes(a); | ||
628 | len_2 = (size_t) BN_num_bytes(b); | ||
629 | |||
630 | if (len_1 == 0) { | ||
631 | /* len_1 == 0 => a == 0 */ | ||
632 | a_buf = &char_zero; | ||
633 | len_1 = 1; | ||
634 | } else { | ||
635 | if ((buffer_1 = malloc(len_1)) == NULL) { | ||
636 | ECerror(ERR_R_MALLOC_FAILURE); | ||
637 | goto err; | ||
638 | } | ||
639 | if ((len_1 = BN_bn2bin(a, buffer_1)) == 0) { | ||
640 | ECerror(ERR_R_BN_LIB); | ||
641 | goto err; | ||
642 | } | ||
643 | a_buf = buffer_1; | ||
644 | } | ||
645 | 652 | ||
646 | if (len_2 == 0) { | 653 | if (!ec_asn1_encode_field_element(group, a, curve->a)) { |
647 | /* len_2 == 0 => b == 0 */ | 654 | ECerror(ERR_R_EC_LIB); |
648 | b_buf = &char_zero; | 655 | goto err; |
649 | len_2 = 1; | ||
650 | } else { | ||
651 | if ((buffer_2 = malloc(len_2)) == NULL) { | ||
652 | ECerror(ERR_R_MALLOC_FAILURE); | ||
653 | goto err; | ||
654 | } | ||
655 | if ((len_2 = BN_bn2bin(b, buffer_2)) == 0) { | ||
656 | ECerror(ERR_R_BN_LIB); | ||
657 | goto err; | ||
658 | } | ||
659 | b_buf = buffer_2; | ||
660 | } | 656 | } |
661 | 657 | if (!ec_asn1_encode_field_element(group, b, curve->b)) { | |
662 | /* set a and b */ | 658 | ECerror(ERR_R_EC_LIB); |
663 | if (!ASN1_STRING_set(curve->a, a_buf, len_1) || | ||
664 | !ASN1_STRING_set(curve->b, b_buf, len_2)) { | ||
665 | ECerror(ERR_R_ASN1_LIB); | ||
666 | goto err; | 659 | goto err; |
667 | } | 660 | } |
668 | 661 | ||
@@ -688,8 +681,6 @@ ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) | |||
688 | ret = 1; | 681 | ret = 1; |
689 | 682 | ||
690 | err: | 683 | err: |
691 | free(buffer_1); | ||
692 | free(buffer_2); | ||
693 | BN_free(a); | 684 | BN_free(a); |
694 | BN_free(b); | 685 | BN_free(b); |
695 | 686 | ||