From 2da8d4eb2812e18cec5c8324a54a4c56b52563ed Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 15 Jun 2020 14:21:00 +0100 Subject: [PATCH] Add more complete support for libctx/propq in the EC code Renames some "new_ex" functions to "new_with_libctx" and ensures that we pass around the libctx AND the propq everywhere. Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/12159) --- crypto/ec/ec_ameth.c | 2 +- crypto/ec/ec_backend.c | 5 +- crypto/ec/ec_curve.c | 16 +++-- crypto/ec/ec_cvt.c | 4 +- crypto/ec/ec_key.c | 27 +++++--- crypto/ec/ec_kmeth.c | 15 +++-- crypto/ec/ec_lib.c | 22 ++++-- crypto/ec/ec_local.h | 9 ++- crypto/err/openssl.txt | 1 - doc/man3/EC_GROUP_new.pod | 53 ++++++++------- doc/man3/EC_KEY_new.pod | 70 +++++++++++--------- include/crypto/ec.h | 1 + include/openssl/ec.h | 25 ++++--- include/openssl/ecerr.h | 1 - providers/fips/fipsprov.c | 2 +- providers/implementations/keymgmt/ec_kmgmt.c | 6 +- util/libcrypto.num | 9 ++- 17 files changed, 158 insertions(+), 110 deletions(-) diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index bde8458274..757c568ca8 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -762,7 +762,7 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - EC_KEY *ec = EC_KEY_new_ex(pctx->libctx); + EC_KEY *ec = EC_KEY_new_with_libctx(pctx->libctx, pctx->propquery); if (ec == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index b12a9411d2..2277c2c724 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -190,8 +190,9 @@ int ec_key_domparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) || (curve_nid = ec_curve_name2nid(curve_name)) == NID_undef) goto err; - if ((ecg = EC_GROUP_new_by_curve_name_ex(ec_key_get_libctx(ec), - curve_nid)) == NULL) + if ((ecg = EC_GROUP_new_by_curve_name_with_libctx(ec_key_get_libctx(ec), + ec_key_get0_propq(ec), + curve_nid)) == NULL) goto err; } diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 3be62b3655..bf02c261f7 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -3180,6 +3180,7 @@ int ec_curve_name2nid(const char *name) } static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, + const char *propq, const ec_list_element curve) { EC_GROUP *group = NULL; @@ -3195,8 +3196,8 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, /* If no curve data curve method must handle everything */ if (curve.data == NULL) - return ec_group_new_ex(libctx, - curve.meth != NULL ? curve.meth() : NULL); + return ec_group_new_with_libctx(libctx, propq, + curve.meth != NULL ? curve.meth() : NULL); if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); @@ -3218,7 +3219,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, if (curve.meth != 0) { meth = curve.meth(); - if (((group = ec_group_new_ex(libctx, meth)) == NULL) || + if (((group = ec_group_new_with_libctx(libctx, propq, meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -3288,14 +3289,15 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, return group; } -EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid) +EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, + const char *propq, int nid) { EC_GROUP *ret = NULL; const ec_list_element *curve; if ((curve = ec_curve_nid2curve(nid)) == NULL - || (ret = ec_group_new_from_data(libctx, *curve)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX, EC_R_UNKNOWN_GROUP); + || (ret = ec_group_new_from_data(libctx, propq, *curve)) == NULL) { + ECerr(0, EC_R_UNKNOWN_GROUP); return NULL; } @@ -3305,7 +3307,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid) #ifndef FIPS_MODULE EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { - return EC_GROUP_new_by_curve_name_ex(NULL, nid); + return EC_GROUP_new_by_curve_name_with_libctx(NULL, NULL, nid); } #endif diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index a8ea6fe7fd..e5e6f10ce4 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, meth = EC_GFp_mont_method(); #endif - ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth); + ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth); if (ret == NULL) return NULL; @@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, meth = EC_GF2m_simple_method(); - ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth); + ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth); if (ret == NULL) return NULL; diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 47feede54b..359e034ed9 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -29,21 +29,22 @@ static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, #ifndef FIPS_MODULE EC_KEY *EC_KEY_new(void) { - return ec_key_new_method_int(NULL, NULL); + return ec_key_new_method_int(NULL, NULL, NULL); } #endif -EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx) +EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq) { - return ec_key_new_method_int(ctx, NULL); + return ec_key_new_method_int(ctx, propq, NULL); } -EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid) +EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, + const char *propq, int nid) { - EC_KEY *ret = EC_KEY_new_ex(ctx); + EC_KEY *ret = EC_KEY_new_with_libctx(ctx, propq); if (ret == NULL) return NULL; - ret->group = EC_GROUP_new_by_curve_name_ex(ctx, nid); + ret->group = EC_GROUP_new_by_curve_name_with_libctx(ctx, propq, nid); if (ret->group == NULL) { EC_KEY_free(ret); return NULL; @@ -59,7 +60,7 @@ EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid) #ifndef FIPS_MODULE EC_KEY *EC_KEY_new_by_curve_name(int nid) { - return EC_KEY_new_by_curve_name_ex(NULL, nid); + return EC_KEY_new_by_curve_name_with_libctx(NULL, NULL, nid); } #endif @@ -93,6 +94,7 @@ void EC_KEY_free(EC_KEY *r) EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); + OPENSSL_free(r->propq); OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); } @@ -119,7 +121,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) if (src->group != NULL) { /* clear the old group */ EC_GROUP_free(dest->group); - dest->group = ec_group_new_ex(src->libctx, src->group->meth); + dest->group = ec_group_new_with_libctx(src->libctx, src->propq, + src->group->meth); if (dest->group == NULL) return NULL; if (!EC_GROUP_copy(dest->group, src->group)) @@ -180,7 +183,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) { - EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->engine); + EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->propq, + ec_key->engine); if (ret == NULL) return NULL; @@ -631,6 +635,11 @@ OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *key) return key->libctx; } +const char *ec_key_get0_propq(const EC_KEY *key) +{ + return key->propq; +} + const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index 1f30571089..3fec8a4d81 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -76,7 +76,8 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) return 1; } -EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine) +EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq, + ENGINE *engine) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -86,13 +87,19 @@ EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine) } ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE); + goto err; + } + } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + goto err; } ret->meth = EC_KEY_get_default_method(); @@ -138,7 +145,7 @@ EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine) #ifndef FIPS_MODULE EC_KEY *EC_KEY_new_method(ENGINE *engine) { - return ec_key_new_method_int(NULL, engine); + return ec_key_new_method_int(NULL, NULL, engine); } #endif diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index f62eff5034..a0c007a13e 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -23,26 +23,34 @@ /* functions for EC_GROUP objects */ -EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) +EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, + const EC_METHOD *meth) { EC_GROUP *ret; if (meth == NULL) { - ECerr(EC_F_EC_GROUP_NEW_EX, EC_R_SLOT_FULL); + ECerr(0, EC_R_SLOT_FULL); return NULL; } if (meth->group_init == 0) { - ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ECerr(0, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return NULL; } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_MALLOC_FAILURE); + ECerr(0, ERR_R_MALLOC_FAILURE); return NULL; } ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + } ret->meth = meth; if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { ret->order = BN_new(); @@ -61,6 +69,7 @@ EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) err: BN_free(ret->order); BN_free(ret->cofactor); + OPENSSL_free(ret->propq); OPENSSL_free(ret); return NULL; } @@ -69,7 +78,7 @@ EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) # ifndef FIPS_MODULE EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) { - return ec_group_new_ex(NULL, meth); + return ec_group_new_with_libctx(NULL, NULL, meth); } # endif #endif @@ -121,6 +130,7 @@ void EC_GROUP_free(EC_GROUP *group) BN_free(group->order); BN_free(group->cofactor); OPENSSL_free(group->seed); + OPENSSL_free(group->propq); OPENSSL_free(group); } @@ -257,7 +267,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) if (a == NULL) return NULL; - if ((t = ec_group_new_ex(a->libctx, a->meth)) == NULL) + if ((t = ec_group_new_with_libctx(a->libctx, a->propq, a->meth)) == NULL) return NULL; if (!EC_GROUP_copy(t, a)) goto err; diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h index 7f9b61bc49..aa040b54d1 100644 --- a/crypto/ec/ec_local.h +++ b/crypto/ec/ec_local.h @@ -274,6 +274,7 @@ struct ec_group_st { } pre_comp; OPENSSL_CTX *libctx; + char *propq; }; #define SETPRECOMP(g, type, pre) \ @@ -297,6 +298,7 @@ struct ec_key_st { #endif CRYPTO_RWLOCK *lock; OPENSSL_CTX *libctx; + char *propq; /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ @@ -593,10 +595,12 @@ int ec_group_simple_order_bits(const EC_GROUP *group); * Creates a new EC_GROUP object * \param libctx The associated library context or NULL for the default * library context + * \param propq Any property query string * \param meth EC_METHOD to use * \return newly created EC_GROUP object or NULL in case of an error. */ -EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth); +EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, + const EC_METHOD *meth); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized @@ -651,7 +655,8 @@ struct ec_key_method_st { #define EC_KEY_METHOD_DYNAMIC 1 -EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine); +EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq, + ENGINE *engine); int ossl_ec_key_gen(EC_KEY *eckey); int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 515dfc3f11..a30b808a25 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -652,7 +652,6 @@ EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS:193:EC_GROUP_get_pentanomial_basis EC_F_EC_GROUP_GET_TRINOMIAL_BASIS:194:EC_GROUP_get_trinomial_basis EC_F_EC_GROUP_NEW:108:EC_GROUP_new EC_F_EC_GROUP_NEW_BY_CURVE_NAME:174:EC_GROUP_new_by_curve_name -EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX:301:EC_GROUP_new_by_curve_name_ex EC_F_EC_GROUP_NEW_EX:302:EC_GROUP_new_ex EC_F_EC_GROUP_NEW_FROM_DATA:175:ec_group_new_from_data EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS:263:EC_GROUP_new_from_ecparameters diff --git a/doc/man3/EC_GROUP_new.pod b/doc/man3/EC_GROUP_new.pod index fa61275806..76fed3b246 100644 --- a/doc/man3/EC_GROUP_new.pod +++ b/doc/man3/EC_GROUP_new.pod @@ -11,7 +11,7 @@ EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_new_curve_GFp, EC_GROUP_new_curve_GF2m, -EC_GROUP_new_by_curve_name_ex, +EC_GROUP_new_by_curve_name_with_libctx, EC_GROUP_new_by_curve_name, EC_GROUP_set_curve, EC_GROUP_get_curve, @@ -34,7 +34,8 @@ objects const BIGNUM *b, BN_CTX *ctx); EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); - EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid); + EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, + const char *propq, int nid); EC_GROUP *EC_GROUP_new_by_curve_name(int nid); int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, @@ -83,24 +84,24 @@ pentanomial for this parameter. Although deprecated since OpenSSL 3.0 and should no longer be used, a new curve can be constructed by calling EC_GROUP_new(), using the -implementation provided by B (see L) and -associated with the library context B (see L). -The B parameter may be NULL in which case the default library context is +implementation provided by I (see L) and +associated with the library context I (see L). +The I parameter may be NULL in which case the default library context is used. It is then necessary to call EC_GROUP_set_curve() to set the curve parameters. Applications should instead use one of the other EC_GROUP_new_* constructors. EC_GROUP_new_from_ecparameters() will create a group from the -specified B and +specified I and EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK -B. +I. -EC_GROUP_set_curve() sets the curve parameters B

, B and B. For a curve -over Fp B

is the prime for the field. For a curve over F2^m B

represents +EC_GROUP_set_curve() sets the curve parameters I

, I and I. For a curve +over Fp I

is the prime for the field. For a curve over F2^m I

represents the irreducible polynomial - each bit represents a term in the polynomial. Therefore there will either be three or five bits set dependent on whether the polynomial is a trinomial or a pentanomial. -In either case, B and B represents the coefficients a and b from the +In either case, I and I represents the coefficients a and b from the relevant equation introduced above. EC_group_get_curve() obtains the previously set curve parameters. @@ -120,13 +121,13 @@ An appropriate default implementation method will be used. Whilst the library can be used to create any curve using the functions described above, there are also a number of predefined curves that are available. In order to obtain a list of all of the predefined curves, call the function -EC_get_builtin_curves(). The parameter B should be an array of -EC_builtin_curve structures of size B. The function will populate the -B array with information about the built-in curves. If B is less than -the total number of curves available, then the first B curves will be +EC_get_builtin_curves(). The parameter I should be an array of +EC_builtin_curve structures of size I. The function will populate the +I array with information about the built-in curves. If I is less than +the total number of curves available, then the first I curves will be returned. Otherwise the total number of curves will be provided. The return value is the total number of curves available (whether that number has been -populated in B or not). Passing a NULL B, or setting B to 0 will +populated in I or not). Passing a NULL I, or setting I to 0 will do nothing other than return the total number of curves available. The EC_builtin_curve structure is defined as follows: @@ -135,26 +136,28 @@ The EC_builtin_curve structure is defined as follows: const char *comment; } EC_builtin_curve; -Each EC_builtin_curve item has a unique integer id (B), and a human +Each EC_builtin_curve item has a unique integer id (I), and a human readable comment string describing the curve. In order to construct a built-in curve use the function -EC_GROUP_new_by_curve_name_ex() and provide the B of the curve to be -constructed and the associated library context to be used in B (see -L). The B value may be NULL in which case the default -library context is used. +EC_GROUP_new_by_curve_name_with_libctx() and provide the I of the curve to +be constructed, the associated library context to be used in I (see +L) and any property query string in I. The I value +may be NULL in which case the default library context is used. The I +value may also be NULL. -EC_GROUP_new_by_curve_name() is the same as EC_GROUP_new_by_curve_name_ex() -except that the default library context is always used. +EC_GROUP_new_by_curve_name() is the same as +EC_GROUP_new_by_curve_name_with_libctx() except that the default library context +is always used along with a NULL property query string. EC_GROUP_free() frees the memory associated with the EC_GROUP. -If B is NULL nothing is done. +If I is NULL nothing is done. EC_GROUP_clear_free() is deprecated: it was meant to destroy any sensitive data held within the EC_GROUP and then free its memory, but since all the data stored in the EC_GROUP is public anyway, this function is unnecessary. Its use can be safely replaced with EC_GROUP_free(). -If B is NULL nothing is done. +If I is NULL nothing is done. =head1 RETURN VALUES @@ -182,7 +185,7 @@ L EC_GROUP_new() was deprecated in OpenSSL 3.0. -EC_GROUP_new_by_curve_name_ex() was added in OpenSSL 3.0. +EC_GROUP_new_by_curve_name_with_libctx() was added in OpenSSL 3.0. =item * diff --git a/doc/man3/EC_KEY_new.pod b/doc/man3/EC_KEY_new.pod index 04ad740bc6..a907435153 100644 --- a/doc/man3/EC_KEY_new.pod +++ b/doc/man3/EC_KEY_new.pod @@ -2,10 +2,10 @@ =head1 NAME -EC_KEY_get_method, EC_KEY_set_method, EC_KEY_new_ex, +EC_KEY_get_method, EC_KEY_set_method, EC_KEY_new_with_libctx, EC_KEY_new, EC_KEY_get_flags, EC_KEY_set_flags, EC_KEY_clear_flags, -EC_KEY_new_by_curve_name_ex, EC_KEY_new_by_curve_name, EC_KEY_free, EC_KEY_copy, -EC_KEY_dup, EC_KEY_up_ref, EC_KEY_get0_engine, +EC_KEY_new_by_curve_name_with_libctx, EC_KEY_new_by_curve_name, EC_KEY_free, +EC_KEY_copy, EC_KEY_dup, EC_KEY_up_ref, EC_KEY_get0_engine, EC_KEY_get0_group, EC_KEY_set_group, EC_KEY_get0_private_key, EC_KEY_set_private_key, EC_KEY_get0_public_key, EC_KEY_set_public_key, EC_KEY_get_conv_form, @@ -19,12 +19,13 @@ EC_KEY objects #include - EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx); + EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq); EC_KEY *EC_KEY_new(void); int EC_KEY_get_flags(const EC_KEY *key); void EC_KEY_set_flags(EC_KEY *key, int flags); void EC_KEY_clear_flags(EC_KEY *key, int flags); - EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid); + EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, + const char *propq, int nid); EC_KEY *EC_KEY_new_by_curve_name(int nid); void EC_KEY_free(EC_KEY *key); EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); @@ -64,9 +65,9 @@ Deprecated since OpenSSL 3.0: An EC_KEY represents a public key and, optionally, the associated private key. A new EC_KEY with no associated curve can be constructed by calling -EC_KEY_new_ex() and specifying the associated library context in B -(see L). -The B parameter may be NULL in which case the default library context is +EC_KEY_new_ex() and specifying the associated library context in I +(see L) and property query string I. +The I parameter may be NULL in which case the default library context is used. The reference count for the newly created EC_KEY is initially set to 1. @@ -77,24 +78,26 @@ EC_KEY_new() is the same as EC_KEY_new_ex() except that the default library context is always used. Alternatively a new EC_KEY can be constructed by calling -EC_KEY_new_by_curve_name_ex() and supplying the nid of the associated curve and -the library context to be used B (see L). -The B parameter may be NULL in which case the default library context is -used. +EC_KEY_new_by_curve_name_with_libctx() and supplying the nid of the associated +curve, the library context to be used I (see L) and any +property query string I. +The I parameter may be NULL in which case the default library context is +used. The I value may also be NULL. See L for a description of curve names. This function simply wraps calls to EC_KEY_new_ex() and -EC_GROUP_new_by_curve_name_ex(). +EC_GROUP_new_by_curve_name_with_libctx(). -EC_KEY_new_by_curve_name() is the same as EC_KEY_new_by_curve_name_ex() except -that the default library context is always used. +EC_KEY_new_by_curve_name() is the same as EC_KEY_new_by_curve_name_with_libctx() +except that the default library context is always used and a NULL property query +string. Calling EC_KEY_free() decrements the reference count for the EC_KEY object, and if it has dropped to zero then frees the memory associated with it. If -B is NULL nothing is done. +I is NULL nothing is done. -EC_KEY_copy() copies the contents of the EC_KEY in B into B. +EC_KEY_copy() copies the contents of the EC_KEY in I into I. -EC_KEY_dup() creates a new EC_KEY object and copies B into it. +EC_KEY_dup() creates a new EC_KEY object and copies I into it. EC_KEY_up_ref() increments the reference count associated with the EC_KEY object. @@ -103,7 +106,7 @@ EC_KEY_get0_engine() returns a handle to the ENGINE that has been set for this EC_KEY object. EC_KEY_generate_key() generates a new public and private key for the supplied -B object. B must have an EC_GROUP object associated with it +I object. I must have an EC_GROUP object associated with it before calling this function. The private key is a random integer (0 < priv_key < order, where I is the order of the EC_GROUP object). The public key is an EC_POINT on the curve calculated by multiplying the generator for the @@ -112,27 +115,27 @@ curve by the private key. EC_KEY_check_key() performs various sanity checks on the EC_KEY object to confirm that it is valid. -EC_KEY_set_public_key_affine_coordinates() sets the public key for B based +EC_KEY_set_public_key_affine_coordinates() sets the public key for I based on its affine co-ordinates; i.e., it constructs an EC_POINT object based on -the supplied B and B values and sets the public key to be this +the supplied I and I values and sets the public key to be this EC_POINT. It also performs certain sanity checks on the key to confirm that it is valid. The functions EC_KEY_get0_group(), EC_KEY_set_group(), EC_KEY_get0_private_key(), EC_KEY_set_private_key(), EC_KEY_get0_public_key(), and EC_KEY_set_public_key() get and set the EC_GROUP object, the private key, -and the EC_POINT public key for the B respectively. +and the EC_POINT public key for the I respectively. The functions EC_KEY_get_conv_form() and EC_KEY_set_conv_form() get and set the -point_conversion_form for the B. For a description of +point_conversion_form for the I. For a description of point_conversion_forms please see L. -EC_KEY_set_flags() sets the flags in the B parameter on the EC_KEY +EC_KEY_set_flags() sets the flags in the I parameter on the EC_KEY object. Any flags that are already set are left set. The flags currently defined are EC_FLAG_NON_FIPS_ALLOW and EC_FLAG_FIPS_CHECKED. In addition there is the flag EC_FLAG_COFACTOR_ECDH which is specific to ECDH. EC_KEY_get_flags() returns the current flags that are set for this EC_KEY. -EC_KEY_clear_flags() clears the flags indicated by the B parameter; all +EC_KEY_clear_flags() clears the flags indicated by the I parameter; all other flags are left in their existing state. EC_KEY_set_asn1_flag() sets the asn1_flag on the underlying EC_GROUP object @@ -147,11 +150,11 @@ hardcoded lookup tables for. EC_KEY_oct2key() and EC_KEY_key2buf() are identical to the functions EC_POINT_oct2point() and EC_POINT_point2buf() except they use the public key -EC_POINT in B. +EC_POINT in I. EC_KEY_oct2priv() and EC_KEY_priv2oct() convert between the private key -component of B and octet form. The octet form consists of the content -octets of the B OCTET STRING in an B ASN.1 structure. +component of I and octet form. The octet form consists of the content +octets of the I OCTET STRING in an I ASN.1 structure. The function EC_KEY_priv2oct() must be supplied with a buffer long enough to store the octet form. The return value provides the number of octets stored. @@ -159,17 +162,18 @@ Calling the function with a NULL buffer will not perform the conversion but will just return the required buffer length. The function EC_KEY_priv2buf() allocates a buffer of suitable length and writes -an EC_KEY to it in octet format. The allocated buffer is written to B<*pbuf> +an EC_KEY to it in octet format. The allocated buffer is written to I<*pbuf> and its length is returned. The caller must free up the allocated buffer with a -call to OPENSSL_free(). Since the allocated buffer value is written to B<*pbuf> -the B parameter B be B. +call to OPENSSL_free(). Since the allocated buffer value is written to I<*pbuf> +the I parameter B be B. EC_KEY_priv2buf() converts an EC_KEY private key into an allocated buffer. =head1 RETURN VALUES -EC_KEY_new_ex(), EC_KEY_new(), EC_KEY_new_by_curve_name() and EC_KEY_dup() -return a pointer to the newly created EC_KEY object, or NULL on error. +EC_KEY_new_with_libctx(), EC_KEY_new(), EC_KEY_new_by_curve_name_with_libctx(), +EC_KEY_new_by_curve_name() and EC_KEY_dup() return a pointer to the newly +created EC_KEY object, or NULL on error. EC_KEY_get_flags() returns the flags associated with the EC_KEY object as an integer. diff --git a/include/crypto/ec.h b/include/crypto/ec.h index bccebb06db..a771cfd706 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -54,6 +54,7 @@ int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx); int ec_key_private_check(const EC_KEY *eckey); int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx); OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *eckey); +const char *ec_key_get0_propq(const EC_KEY *eckey); const char *ec_curve_nid2name(int nid); int ec_curve_name2nid(const char *name); const unsigned char *ecdsa_algorithmidentifier_encoding(int md_nid, size_t *len); diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 1302e27bb0..35dbeb9301 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -383,15 +383,18 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, * Creates a EC_GROUP object with a curve specified by a NID * \param libctx The associated library context or NULL for the default * context + * \param propq A property query string * \param nid NID of the OID of the curve name * \return newly created EC_GROUP object with specified curve or NULL * if an error occurred */ -EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid); +EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, + const char *propq, int nid); /** * Creates a EC_GROUP object with a curve specified by a NID. Same as - * EC_GROUP_new_by_curve_name_ex but the libctx is always NULL. + * EC_GROUP_new_by_curve_name_with_libctx but the libctx and propq are always + * NULL. * \param nid NID of the OID of the curve name * \return newly created EC_GROUP object with specified curve or NULL * if an error occurred @@ -864,11 +867,11 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); * which case the default library context is used. * \return EC_KEY object or NULL if an error occurred. */ -EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx); +EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq); /** - * Creates a new EC_KEY object. Same as calling EC_KEY_new_ex with a NULL - * library context + * Creates a new EC_KEY object. Same as calling EC_KEY_new_with_libctx with a + * NULL library context * \return EC_KEY object or NULL if an error occurred. */ EC_KEY *EC_KEY_new(void); @@ -882,17 +885,19 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags); /** * Creates a new EC_KEY object using a named curve as underlying * EC_GROUP object. - * \param ctx The library context for to use for this EC_KEY. May be NULL in - * which case the default library context is used. - * \param nid NID of the named curve. + * \param ctx The library context for to use for this EC_KEY. May be NULL in + * which case the default library context is used. + * \param propq Any property query string + * \param nid NID of the named curve. * \return EC_KEY object or NULL if an error occurred. */ -EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid); +EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, const char *propq, + int nid); /** * Creates a new EC_KEY object using a named curve as underlying * EC_GROUP object. Same as calling EC_KEY_new_by_curve_name_ex with a NULL - * library context. + * library context and property query string. * \param nid NID of the named curve. * \return EC_KEY object or NULL if an error occurred. */ diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h index 49adc7c681..033c94d9a9 100644 --- a/include/openssl/ecerr.h +++ b/include/openssl/ecerr.h @@ -128,7 +128,6 @@ int ERR_load_EC_strings(void); # define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 0 # define EC_F_EC_GROUP_NEW 0 # define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 0 -# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX 0 # define EC_F_EC_GROUP_NEW_EX 0 # define EC_F_EC_GROUP_NEW_FROM_DATA 0 # define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS 0 diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 9efb6af1c9..4d39570464 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -194,7 +194,7 @@ static int dummy_evp_call(OPENSSL_CTX *libctx) #ifndef OPENSSL_NO_EC /* Do some dummy EC calls */ - key = EC_KEY_new_by_curve_name_ex(libctx, NID_X9_62_prime256v1); + key = EC_KEY_new_by_curve_name_with_libctx(libctx, NULL, NID_X9_62_prime256v1); if (key == NULL) goto err; diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 0b006047d5..cd8e7f5ece 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -244,7 +244,7 @@ int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl, static void *ec_newdata(void *provctx) { - return EC_KEY_new_ex(PROV_LIBRARY_CONTEXT_OF(provctx)); + return EC_KEY_new_with_libctx(PROV_LIBRARY_CONTEXT_OF(provctx), NULL); } static @@ -667,7 +667,7 @@ static int ec_gen_set_group(void *genctx, int nid) struct ec_gen_ctx *gctx = genctx; EC_GROUP *group; - group = EC_GROUP_new_by_curve_name_ex(gctx->libctx, nid); + group = EC_GROUP_new_by_curve_name_with_libctx(gctx->libctx, NULL, nid); if (group == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); return 0; @@ -760,7 +760,7 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) int ret = 1; /* Start optimistically */ if (gctx == NULL - || (ec = EC_KEY_new_ex(gctx->libctx)) == NULL) + || (ec = EC_KEY_new_with_libctx(gctx->libctx, NULL)) == NULL) return NULL; /* We must always assign a group, no matter what */ diff --git a/util/libcrypto.num b/util/libcrypto.num index 38cc5700d7..acaa17394e 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4683,9 +4683,9 @@ ERR_set_error ? 3_0_0 EXIST::FUNCTION: ERR_vset_error ? 3_0_0 EXIST::FUNCTION: X509_get0_authority_issuer ? 3_0_0 EXIST::FUNCTION: X509_get0_authority_serial ? 3_0_0 EXIST::FUNCTION: -EC_GROUP_new_by_curve_name_ex ? 3_0_0 EXIST::FUNCTION:EC -EC_KEY_new_ex ? 3_0_0 EXIST::FUNCTION:EC -EC_KEY_new_by_curve_name_ex ? 3_0_0 EXIST::FUNCTION:EC +EC_GROUP_new_by_curve_name_ex ? 3_0_0 NOEXIST::FUNCTION:EC +EC_KEY_new_ex ? 3_0_0 NOEXIST::FUNCTION:EC +EC_KEY_new_by_curve_name_ex ? 3_0_0 NOEXIST::FUNCTION:EC OPENSSL_hexstr2buf_ex ? 3_0_0 EXIST::FUNCTION: OPENSSL_buf2hexstr_ex ? 3_0_0 EXIST::FUNCTION: OSSL_PARAM_allocate_from_text ? 3_0_0 EXIST::FUNCTION: @@ -5100,3 +5100,6 @@ EVP_PKEY_parameters_eq ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_query_operation ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_get0_provider_ctx ? 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_get_capabilities ? 3_0_0 EXIST::FUNCTION: +EC_GROUP_new_by_curve_name_with_libctx ? 3_0_0 EXIST::FUNCTION:EC +EC_KEY_new_with_libctx ? 3_0_0 EXIST::FUNCTION:EC +EC_KEY_new_by_curve_name_with_libctx ? 3_0_0 EXIST::FUNCTION:EC