From: Dmitry Belyavskiy Date: Wed, 14 Jan 2026 16:59:38 +0000 (+0100) Subject: Disabling explicit EC curves encoding X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=54d175c7d5f476e2a2c93c050dc145f484c93fbd;p=thirdparty%2Fopenssl.git Disabling explicit EC curves encoding In case the parameters don't exactly match the well-known ones Reviewed-by: Paul Dale Reviewed-by: Simo Sorce (Merged from https://github.com/openssl/openssl/pull/29639) --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33444738e9a..c915b6b2176 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,7 +93,7 @@ jobs: run: echo "FIPS_VENDOR=CI" >> VERSION.dat - name: config # enable-quic is on by default, but we leave it here to check we're testing the explicit enable somewhere - run: CC=gcc ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-sslkeylog enable-fips enable-quic enable-lms && perl configdata.pm --dump + run: CC=gcc ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-sslkeylog enable-fips enable-quic enable-lms && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info @@ -414,7 +414,7 @@ jobs: sudo cat /proc/sys/vm/mmap_rnd_bits sudo sysctl -w vm.mmap_rnd_bits=28 - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo enable-asan enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-fips enable-lms && perl configdata.pm --dump + run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo enable-asan enable-ec_explicit_curves enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-fips enable-lms && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info @@ -443,7 +443,7 @@ jobs: sudo cat /proc/sys/vm/mmap_rnd_bits sudo sysctl -w vm.mmap_rnd_bits=28 - name: config - run: ./config --strict-warnings --banner=Configured --debug -DPEDANTIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION enable-asan enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-weak-ssl-ciphers enable-nextprotoneg && perl configdata.pm --dump + run: ./config --strict-warnings --banner=Configured --debug -DPEDANTIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION enable-asan enable-ec_explicit_curves enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-weak-ssl-ciphers enable-nextprotoneg && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info @@ -474,7 +474,7 @@ jobs: sudo sysctl -w vm.mmap_rnd_bits=28 - name: config # --debug -O1 is to produce a debug build that runs in a reasonable amount of time - run: CC=clang ./config --strict-warnings --banner=Configured --debug no-shared -O1 -fsanitize=memory -DOSSL_SANITIZE_MEMORY -fno-optimize-sibling-calls enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-fips enable-lms no-slh-dsa && perl configdata.pm --dump + run: CC=clang ./config --strict-warnings --banner=Configured --debug no-shared -O1 -fsanitize=memory -DOSSL_SANITIZE_MEMORY -fno-optimize-sibling-calls enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-ec_explicit_curves enable-fips enable-lms no-slh-dsa && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info @@ -563,7 +563,7 @@ jobs: - name: install extra config support run: sudo apt-get -y install libsctp-dev abigail-tools libzstd-dev zstd - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ktls enable-fips enable-lms enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-weak-ssl-ciphers enable-trace enable-zlib enable-zstd && perl configdata.pm --dump + run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-ktls enable-fips enable-lms enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-weak-ssl-ciphers enable-trace enable-zlib enable-zstd && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info @@ -613,7 +613,7 @@ jobs: - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo no-shared enable-crypto-mdebug enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 no-fips && perl configdata.pm --dump + run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo no-shared enable-crypto-mdebug enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 enable-ec_explicit_curves no-fips && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info diff --git a/CHANGES.md b/CHANGES.md index ff960d0dcc9..dfe4b0d2d38 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,12 @@ OpenSSL 4.0 *Shane Lontis* + * Support of explicit EC curves was disabled by default, an error will occur if + an explicit EC curve doesn't match any known one. New configuration option, + `enable-ec_explicit_curves` is added. + + *Dmitry Belyavskiy* + * Removed configure options can now only be disabled. You may continue to use `disable-`, which will remain supported. Using `enable-` for a removed feature is no longer permitted. diff --git a/Configure b/Configure index 3b8f2e45874..7682185697a 100755 --- a/Configure +++ b/Configure @@ -466,6 +466,7 @@ my @disablables = ( "dtls", "ec", "ec2m", + "ec_explicit_curves", "ec_nistp_64_gcc_128", "ecdh", "ecdsa", @@ -601,6 +602,7 @@ our %disabled = ( # "what" => "comment" "demos" => "default", "h3demo" => "default", "hqinterop" => "default", + "ec_explicit_curves" => "default", "ec_nistp_64_gcc_128" => "default", "egd" => "default", "engine" => "default", @@ -654,7 +656,7 @@ my @disable_cascades = ( "zstd" => [ "zstd-dynamic" ], "des" => [ "mdc2" ], "deprecated" => [ "tls-deprecated-ec" ], - "ec" => [ qw(ec2m ecdsa ecdh sm2 gost ecx tls-deprecated-ec) ], + "ec" => [ qw(ec2m ec_explicit_curves ecdsa ecdh sm2 gost ecx tls-deprecated-ec) ], "dgram" => [ "dtls", "quic", "sctp" ], "sock" => [ "dgram", "tfo" ], "dtls" => [ @dtls ], diff --git a/INSTALL.md b/INSTALL.md index 9884caabe95..252bc13e7c5 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -771,6 +771,12 @@ Disable legacy TLS EC groups that were deprecated in RFC8422. These are the Koblitz curves, B, B, B, B, and the binary Elliptic curves that would also be disabled by C. +### enable-ec_expicit_curves + +Enable support for explictitly specified elliptic curves not matching the +well-known ones. Until this option is on, such curves can't be instantiated +from ASN.1 formats. + ### enable-ec_nistp_64_gcc_128 Enable support for optimised implementations of some commonly used NIST diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 01a39337130..c6deacc1a7c 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -888,6 +888,14 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) group->decoded_from_explicit_params = 1; +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + if (EC_GROUP_check_named_curve(group, 0, NULL) == NID_undef) { + EC_GROUP_free(group); + ECPKPARAMETERS_free(params); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP); + return NULL; + } +#endif if (a) { EC_GROUP_free(*a); @@ -948,6 +956,13 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) goto err; } +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + if (EC_GROUP_check_named_curve(ret->group, 0, NULL) == NID_undef) { + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP); + goto err; + } +#endif + ret->version = priv_key->version; if (priv_key->privateKey) { diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index b041ecd0f72..079a02b59f2 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -1577,7 +1577,9 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], int is_prime_field = 1; BN_CTX *bnctx = NULL; const unsigned char *buf = NULL; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES int encoding_flag = -1; +#endif #endif /* This is the simple named group case */ @@ -1752,6 +1754,12 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], goto err; } if (named_group == group) { +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + if (EC_GROUP_check_named_curve(group, 0, NULL) == NID_undef) { + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP); + goto err; + } +#else /* * If we did not find a named group then the encoding should be explicit * if it was specified @@ -1767,6 +1775,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], goto err; } EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE); +#endif } else { EC_GROUP_free(group); group = named_group; diff --git a/test/ectest.c b/test/ectest.c index 9fca45bad45..c4d2c97ea7d 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -2555,6 +2555,7 @@ err: return r; } +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES /*- * random 256-bit explicit parameters curve, cofactor absent * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit) @@ -2644,6 +2645,7 @@ err: EC_GROUP_free(group); return ret; } +#endif /*- * For named curves, test that: @@ -2887,23 +2889,28 @@ err: static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx, unsigned char *gen, size_t gen_size) { - int ret = 0, i_out; + int ret = 0; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkeyparam = NULL; OSSL_PARAM_BLD *bld = NULL; const char *field_name; OSSL_PARAM *params = NULL; - const OSSL_PARAM *gettable; BIGNUM *p, *a, *b; BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL; BIGNUM *order_out = NULL, *cofactor_out = NULL; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES + const OSSL_PARAM *gettable; + int i_out; char name[80]; unsigned char buf[1024]; size_t buf_len, name_len; #ifndef OPENSSL_NO_EC2M - unsigned int k1 = 0, k2 = 0, k3 = 0; const char *basis_name = NULL; #endif +#endif +#ifndef OPENSSL_NO_EC2M + unsigned int k1 = 0, k2 = 0, k3 = 0; +#endif p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); @@ -2919,11 +2926,15 @@ static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx, field_name = SN_X9_62_characteristic_two_field; #ifndef OPENSSL_NO_EC2M if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) { +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES basis_name = SN_X9_62_tpBasis; +#endif if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1))) goto err; } else { +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES basis_name = SN_X9_62_ppBasis; +#endif if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))) goto err; } @@ -2958,11 +2969,19 @@ static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx, if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld)) || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0) +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + || !TEST_int_le(EVP_PKEY_fromdata(pctx, &pkeyparam, + EVP_PKEY_KEY_PARAMETERS, params), + 0) +#else || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam, EVP_PKEY_KEY_PARAMETERS, params), - 0)) + 0) +#endif + ) goto err; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES /*- Check that all the set values are retrievable -*/ /* There should be no match to a group name since the generator changed */ @@ -3096,6 +3115,7 @@ static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx, #endif ) goto err; +#endif ret = 1; err: BN_free(order_out); @@ -3218,12 +3238,15 @@ static int custom_params_test(int id) EC_KEY *eckey1 = NULL, *eckey2 = NULL; EVP_PKEY *pkey1 = NULL, *pkey2 = NULL; EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL; - size_t sslen, t, bsize; + size_t bsize; unsigned char *pub1 = NULL, *pub2 = NULL; OSSL_PARAM_BLD *param_bld = NULL; OSSL_PARAM *params1 = NULL, *params2 = NULL; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES const unsigned char *export = NULL; size_t export_size = 0; + size_t sslen, t; +#endif EVP_SKEY *skey = NULL; /* Do some setup */ @@ -3391,6 +3414,16 @@ static int custom_params_test(int id) goto err; eckey2 = NULL; /* ownership passed to pkey2 */ +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + /* Compute keyexchange in both directions - fail with custom params */ + if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL)) + || !TEST_int_le(EVP_PKEY_derive_init(pctx1), 0)) + goto err; + if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new(pkey2, NULL)) + || !TEST_int_le(EVP_PKEY_derive_init(pctx2), 0)) + goto err; + +#else /* Compute keyexchange in both directions */ if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL)) || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1) @@ -3474,7 +3507,7 @@ static int custom_params_test(int id) /* compare with previous result */ || !TEST_mem_eq(export, export_size, buf2, sslen)) goto err; - +#endif ret = 1; err: @@ -3561,7 +3594,9 @@ int setup_tests(void) ADD_TEST(parameter_test); ADD_TEST(ossl_parameter_test); +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES ADD_TEST(cofactor_range_test); +#endif ADD_ALL_TESTS(cardinality_test, (int)crv_len); ADD_TEST(prime_field_tests); #ifndef OPENSSL_NO_EC2M diff --git a/test/evp_test.c b/test/evp_test.c index c8920b6f73a..7ce3be97798 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -5433,8 +5433,16 @@ top: pkey = NULL; start: if (strcmp(pp->key, "PrivateKey") == 0) { + int unsupported = 0; + pkey = PEM_read_bio_PrivateKey_ex(t->s.key, NULL, 0, NULL, libctx, NULL); - if (pkey == NULL && !key_unsupported()) { + if (pkey == NULL) + unsupported = key_unsupported(); +#ifdef OPENSSL_NO_EC_EXPLICIT_CURVES + if (strcmp(pp->value, "EC_EXPLICIT") == 0) + unsupported = 1; +#endif + if (pkey == NULL && !unsupported) { EVP_PKEY_free(pkey); TEST_info("Can't read private key %s", pp->value); TEST_openssl_errors();