summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2024-10-28 18:15:53 +0000
committertb <>2024-10-28 18:15:53 +0000
commitc006a5c026da894898b8764743a88da9ed591769 (patch)
tree51d722ec88c22fc4d594e194da21676431b2a72a /src/lib
parentd5d0119ed0fce70c04b0e4f6e89e9f2a1e6b0137 (diff)
downloadopenbsd-c006a5c026da894898b8764743a88da9ed591769.tar.gz
openbsd-c006a5c026da894898b8764743a88da9ed591769.tar.bz2
openbsd-c006a5c026da894898b8764743a88da9ed591769.zip
Fix private key encoding in i2d_ECPrivateKey()
The private key is a random integer between 1 and order - 1. As such it requires at most as many bytes as the order to encode. SEC 1, Section C.4 is very explicit about padding it to this length: The component privateKey is the private key defined to be the octet string of length [ceil(log_2 n/8)] (where n is the order of the curve) obtained from the unsigned integer via the encoding of Section 2.3.7. Fix this by generalizing a similar fix for field elements. ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c71
1 files changed, 40 insertions, 31 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
index d6af3bdec5..45806174d3 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.92 2024/10/28 18:03:34 tb Exp $ */ 1/* $OpenBSD: ec_asn1.c,v 1.93 2024/10/28 18:15:53 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -606,16 +606,12 @@ ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
606} 606}
607 607
608static int 608static int
609ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn, 609ec_asn1_encode_bn(const EC_GROUP *group, const BIGNUM *bn, int len,
610 ASN1_OCTET_STRING *os) 610 ASN1_OCTET_STRING *os)
611{ 611{
612 unsigned char *buf; 612 unsigned char *buf;
613 int len;
614 int ret = 0; 613 int ret = 0;
615 614
616 /* Zero-pad field element per SEC 1, section 2.3.5. */
617 len = (EC_GROUP_get_degree(group) + 7) / 8;
618
619 /* One extra byte for historic NUL termination of ASN1_STRINGs. */ 615 /* One extra byte for historic NUL termination of ASN1_STRINGs. */
620 if ((buf = calloc(1, len + 1)) == NULL) 616 if ((buf = calloc(1, len + 1)) == NULL)
621 goto err; 617 goto err;
@@ -636,6 +632,32 @@ ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
636} 632}
637 633
638static int 634static int
635ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
636 ASN1_OCTET_STRING *os)
637{
638 int len;
639
640 /* Zero-pad field element to byte length of p per SEC 1, 2.3.5. */
641 len = (EC_GROUP_get_degree(group) + 7) / 8;
642 return ec_asn1_encode_bn(group, bn, len, os);
643}
644
645static int
646ec_asn1_encode_private_key(const EC_GROUP *group, const BIGNUM *bn,
647 ASN1_OCTET_STRING *os)
648{
649 const BIGNUM *order;
650
651 if ((order = EC_GROUP_get0_order(group)) == NULL) {
652 ECerror(EC_R_INVALID_GROUP_ORDER);
653 return 0;
654 }
655
656 /* Zero-pad private key to byte length of order per SEC 1, C.4. */
657 return ec_asn1_encode_bn(group, bn, BN_num_bytes(order), os);
658}
659
660static int
639ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 661ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
640{ 662{
641 BIGNUM *a = NULL, *b = NULL; 663 BIGNUM *a = NULL, *b = NULL;
@@ -1227,7 +1249,7 @@ i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1227{ 1249{
1228 int ret = 0, ok = 0; 1250 int ret = 0, ok = 0;
1229 unsigned char *buffer = NULL; 1251 unsigned char *buffer = NULL;
1230 size_t buf_len = 0, tmp_len; 1252 size_t buf_len = 0;
1231 EC_PRIVATEKEY *ec_privatekey = NULL; 1253 EC_PRIVATEKEY *ec_privatekey = NULL;
1232 1254
1233 if (ec_key == NULL || ec_key->group == NULL || ec_key->priv_key == NULL || 1255 if (ec_key == NULL || ec_key->group == NULL || ec_key->priv_key == NULL ||
@@ -1241,20 +1263,9 @@ i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1241 } 1263 }
1242 ec_privatekey->version = ec_key->version; 1264 ec_privatekey->version = ec_key->version;
1243 1265
1244 buf_len = (size_t) BN_num_bytes(ec_key->priv_key); 1266 if (!ec_asn1_encode_private_key(ec_key->group, ec_key->priv_key,
1245 buffer = malloc(buf_len); 1267 ec_privatekey->privateKey))
1246 if (buffer == NULL) {
1247 ECerror(ERR_R_MALLOC_FAILURE);
1248 goto err;
1249 }
1250 if (!BN_bn2bin(ec_key->priv_key, buffer)) {
1251 ECerror(ERR_R_BN_LIB);
1252 goto err;
1253 }
1254 if (!ASN1_STRING_set(ec_privatekey->privateKey, buffer, buf_len)) {
1255 ECerror(ERR_R_ASN1_LIB);
1256 goto err; 1268 goto err;
1257 }
1258 if (!(ec_key->enc_flag & EC_PKEY_NO_PARAMETERS)) { 1269 if (!(ec_key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1259 ECPKPARAMETERS *parameters; 1270 ECPKPARAMETERS *parameters;
1260 1271
@@ -1270,17 +1281,15 @@ i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1270 ECerror(ERR_R_MALLOC_FAILURE); 1281 ECerror(ERR_R_MALLOC_FAILURE);
1271 goto err; 1282 goto err;
1272 } 1283 }
1273 tmp_len = EC_POINT_point2oct(ec_key->group, ec_key->pub_key, 1284 if ((buf_len = EC_POINT_point2oct(ec_key->group, ec_key->pub_key,
1274 ec_key->conv_form, NULL, 0, NULL); 1285 ec_key->conv_form, NULL, 0, NULL)) == 0) {
1275 1286 ECerror(ERR_R_EC_LIB);
1276 if (tmp_len > buf_len) { 1287 goto err;
1277 unsigned char *tmp_buffer = realloc(buffer, tmp_len); 1288 }
1278 if (!tmp_buffer) { 1289
1279 ECerror(ERR_R_MALLOC_FAILURE); 1290 if ((buffer = calloc(1, buf_len)) == NULL) {
1280 goto err; 1291 ECerror(ERR_R_MALLOC_FAILURE);
1281 } 1292 goto err;
1282 buffer = tmp_buffer;
1283 buf_len = tmp_len;
1284 } 1293 }
1285 if (!EC_POINT_point2oct(ec_key->group, ec_key->pub_key, 1294 if (!EC_POINT_point2oct(ec_key->group, ec_key->pub_key,
1286 ec_key->conv_form, buffer, buf_len, NULL)) { 1295 ec_key->conv_form, buffer, buf_len, NULL)) {