1
0
mirror of https://github.com/openbsd/src.git synced 2026-04-26 23:26:11 +00:00

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
This commit is contained in:
tb
2024-10-14 12:50:18 +00:00
parent 5909419fb4
commit 22b55b0b9c

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ec_asn1.c,v 1.70 2024/10/14 12:42:52 tb Exp $ */
/* $OpenBSD: ec_asn1.c,v 1.71 2024/10/14 12:50:18 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
@@ -601,14 +601,40 @@ ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
return ret;
}
static int
ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
ASN1_OCTET_STRING *os)
{
unsigned char *buf;
int len;
int ret = 0;
/* Zero-pad field element per SEC 1, section 2.3.5. */
len = (EC_GROUP_get_degree(group) + 7) / 8;
/* One extra byte for historic NUL termination of ASN1_STRINGs. */
if ((buf = calloc(1, len + 1)) == NULL)
goto err;
if (BN_bn2binpad(bn, buf, len) != len)
goto err;
ASN1_STRING_set0(os, buf, len);
buf = NULL;
len = 0;
ret = 1;
err:
freezero(buf, len);
return ret;
}
static int
ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
{
BIGNUM *a = NULL, *b = NULL;
unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL,
*b_buf = NULL;
size_t len_1, len_2;
unsigned char char_zero = 0;
int ret = 0;
if (!group || !curve || !curve->a || !curve->b)
@@ -619,50 +645,17 @@ ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
goto err;
}
/* get a and b */
if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) {
ECerror(ERR_R_EC_LIB);
goto err;
}
len_1 = (size_t) BN_num_bytes(a);
len_2 = (size_t) BN_num_bytes(b);
if (len_1 == 0) {
/* len_1 == 0 => a == 0 */
a_buf = &char_zero;
len_1 = 1;
} else {
if ((buffer_1 = malloc(len_1)) == NULL) {
ECerror(ERR_R_MALLOC_FAILURE);
goto err;
}
if ((len_1 = BN_bn2bin(a, buffer_1)) == 0) {
ECerror(ERR_R_BN_LIB);
goto err;
}
a_buf = buffer_1;
if (!ec_asn1_encode_field_element(group, a, curve->a)) {
ECerror(ERR_R_EC_LIB);
goto err;
}
if (len_2 == 0) {
/* len_2 == 0 => b == 0 */
b_buf = &char_zero;
len_2 = 1;
} else {
if ((buffer_2 = malloc(len_2)) == NULL) {
ECerror(ERR_R_MALLOC_FAILURE);
goto err;
}
if ((len_2 = BN_bn2bin(b, buffer_2)) == 0) {
ECerror(ERR_R_BN_LIB);
goto err;
}
b_buf = buffer_2;
}
/* set a and b */
if (!ASN1_STRING_set(curve->a, a_buf, len_1) ||
!ASN1_STRING_set(curve->b, b_buf, len_2)) {
ECerror(ERR_R_ASN1_LIB);
if (!ec_asn1_encode_field_element(group, b, curve->b)) {
ECerror(ERR_R_EC_LIB);
goto err;
}
@@ -688,8 +681,6 @@ ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
ret = 1;
err:
free(buffer_1);
free(buffer_2);
BN_free(a);
BN_free(b);