From febe6bb727082b07a6ffbf64b3b1b0dd871ec000 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 15 Jun 2020 14:29:37 +0100 Subject: [PATCH] Ensure creating an EC public key uses the libctx Creating an EC public key from the private key uses random numbers internally, which require use of the proper libtx. Therefore we make sure the libctx is used during this operation. Fixes #12150 Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/12159) --- crypto/ec/ec_ameth.c | 39 ++++++++++++++++++++++++--------------- crypto/ec/ec_key.c | 7 ++++++- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index 757c568ca8..761f697850 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -97,17 +97,24 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 0; } -static EC_KEY *eckey_type2param(int ptype, const void *pval) +static EC_KEY *eckey_type2param(int ptype, const void *pval, + OPENSSL_CTX *libctx, const char *propq) { EC_KEY *eckey = NULL; EC_GROUP *group = NULL; + if ((eckey = EC_KEY_new_with_libctx(libctx, propq)) == NULL) { + ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + if (ptype == V_ASN1_SEQUENCE) { const ASN1_STRING *pstr = pval; const unsigned char *pm = pstr->data; int pmlen = pstr->length; - if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) { + + if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) { ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); goto ecerr; } @@ -117,11 +124,9 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval) /* * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */ - if ((eckey = EC_KEY_new()) == NULL) { - ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); - goto ecerr; - } - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); + + group = EC_GROUP_new_by_curve_name_with_libctx(libctx, propq, + OBJ_obj2nid(poid)); if (group == NULL) goto ecerr; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); @@ -153,7 +158,7 @@ static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); - eckey = eckey_type2param(ptype, pval); + eckey = eckey_type2param(ptype, pval, NULL, NULL); if (!eckey) { ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); @@ -190,7 +195,10 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } -static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +static int eckey_priv_decode_with_libctx(EVP_PKEY *pkey, + const PKCS8_PRIV_KEY_INFO *p8, + OPENSSL_CTX *libctx, + const char *propq) { const unsigned char *p = NULL; const void *pval; @@ -202,14 +210,14 @@ static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); - eckey = eckey_type2param(ptype, pval); + eckey = eckey_type2param(ptype, pval, libctx, propq); if (eckey == NULL) goto ecliberr; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { - ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); + ECerr(0, EC_R_DECODE_ERROR); goto ecerr; } @@ -217,7 +225,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) return 1; ecliberr: - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + ECerr(0, ERR_R_EC_LIB); ecerr: EC_KEY_free(eckey); return 0; @@ -791,7 +799,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { eckey_pub_cmp, eckey_pub_print, - eckey_priv_decode, + NULL, eckey_priv_encode, eckey_priv_print, @@ -825,7 +833,8 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { ec_pkey_dirty_cnt, ec_pkey_export_to, - ec_pkey_import_from + ec_pkey_import_from, + eckey_priv_decode_with_libctx }; #if !defined(OPENSSL_NO_SM2) @@ -879,7 +888,7 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, if (!EC_KEY_set_group(ecpeer, grp)) goto err; } else { - ecpeer = eckey_type2param(atype, aval); + ecpeer = eckey_type2param(atype, aval, pctx->libctx, pctx->propquery); if (!ecpeer) goto err; } diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 359e034ed9..84ce095693 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -349,14 +349,19 @@ int ec_key_simple_generate_key(EC_KEY *eckey) int ec_key_simple_generate_public_key(EC_KEY *eckey) { int ret; + BN_CTX *ctx = BN_CTX_new_ex(eckey->libctx); + + if (ctx == NULL) + return 0; /* * See SP800-56AR3 5.6.1.2.2: Step (8) * pub_key = priv_key * G (where G is a point on the curve) */ ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL, - NULL, NULL); + NULL, ctx); + BN_CTX_free(ctx); if (ret == 1) eckey->dirty_cnt++; -- 2.25.1