summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2024-10-14 12:50:18 +0000
committertb <>2024-10-14 12:50:18 +0000
commiteed149b404574c0b530d9a1504778f70e207eb9e (patch)
tree1776acd39512a7f602594853b647fccf38b8be8b /src
parent232952b737a80765ddc649d2c2f57e620853cf92 (diff)
downloadopenbsd-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.c81
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
604static int 604static int
605ec_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
634static int
605ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 635ec_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