From: Viktor Dukhovni Date: Wed, 20 May 2026 12:59:19 +0000 (+1000) Subject: Fix EVP_PKEY_dup() for ML-KEM keys X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=796fbbfe40bbc3ac8cc330f47443c96e33a9993c;p=thirdparty%2Fopenssl.git Fix EVP_PKEY_dup() for ML-KEM keys ossl_ml_kem_key_dup() left the (PUB|PRIV) selection case unhandled, so EVP_PKEY_dup() silently returned NULL for ML-KEM-512/768/1024. add_storage() also zeroed the duplicated rho_pkhash, leaving the dup unequal to the original. Add a parameterised dup sweep to test/endecode_test.c covering every supported public-key algorithm in three shapes: full keypair, public-only, and embryonic (parameters-only). While here, stop endecode_test from silently passing when key generation fails: setup_tests() now returns its accumulated status, MAKE_*KEYS no longer short-circuits, and each ADD_TEST_SUITE is now conditional on keygen success. Guard the explicit-EC-curve tests with OPENSSL_NO_EC_EXPLICIT_CURVES. Reviewed-by: Neil Horman Reviewed-by: Bob Beck MergeDate: Thu Jun 18 08:02:28 2026 (Merged from https://github.com/openssl/openssl/pull/31252) --- diff --git a/crypto/ml_kem/ml_kem.c b/crypto/ml_kem/ml_kem.c index 8fa5db9cc87..c8e6188f67d 100644 --- a/crypto/ml_kem/ml_kem.c +++ b/crypto/ml_kem/ml_kem.c @@ -1537,7 +1537,8 @@ end: * The caller should only store private data in `priv` *after* a successful * (non-zero) return from this function. */ -static __owur int add_storage(scalar *pub, scalar *priv, int private, ML_KEM_KEY *key) +static __owur int add_storage(scalar *pub, scalar *priv, + int private, int dup, ML_KEM_KEY *key) { int rank = key->vinfo->rank; @@ -1552,9 +1553,11 @@ static __owur int add_storage(scalar *pub, scalar *priv, int private, ML_KEM_KEY } /* - * We're adding key material, set up rho and pkhash to point to the rho_pkhash buffer + * We're adding key material, set up rho and pkhash to point to the + * rho_pkhash buffer. Zero the key hash when creating fresh keys. */ - memset(key->rho_pkhash, 0, sizeof(key->rho_pkhash)); + if (dup == 0) + memset(key->rho_pkhash, 0, sizeof(key->rho_pkhash)); key->rho = key->rho_pkhash; key->pkhash = key->rho_pkhash + ML_KEM_RANDOM_BYTES; key->d = key->z = NULL; @@ -1683,8 +1686,6 @@ ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection) { int ok = 0; ML_KEM_KEY *ret; - void *tmp_pub; - void *tmp_priv; if (key == NULL) return NULL; @@ -1706,28 +1707,27 @@ ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection) selection = 0; else if (!ossl_ml_kem_have_prvkey(key)) selection &= ~OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + else if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + selection &= ~OSSL_KEYMGMT_SELECT_PUBLIC_KEY; switch (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) { case 0: ok = 1; break; case OSSL_KEYMGMT_SELECT_PUBLIC_KEY: - ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), NULL, 0, ret); + ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), NULL, 0, 1, ret); break; case OSSL_KEYMGMT_SELECT_PRIVATE_KEY: - tmp_pub = OPENSSL_memdup(key->t, key->vinfo->puballoc); - if (tmp_pub == NULL) - break; - tmp_priv = OPENSSL_secure_malloc(key->vinfo->prvalloc); - if (tmp_priv == NULL) { - OPENSSL_free(tmp_pub); - break; + /* Frees both and returns 0 if either is NULL */ + ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), + OPENSSL_secure_malloc(key->vinfo->prvalloc), 1, 1, ret); + if (ok) { + memcpy(ret->s, key->s, key->vinfo->prvalloc); + + /* Duplicated keys retain |d|, if available */ + if (key->d != NULL) + ret->d = ret->z + ML_KEM_RANDOM_BYTES; } - if ((ok = add_storage(tmp_pub, tmp_priv, 1, ret)) != 0) - memcpy(tmp_priv, key->s, key->vinfo->prvalloc); - /* Duplicated keys retain |d|, if available */ - if (key->d != NULL) - ret->d = ret->z + ML_KEM_RANDOM_BYTES; break; } @@ -1840,7 +1840,7 @@ int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len, ML_KEM_KEY *key) || (mdctx = EVP_MD_CTX_new()) == NULL) return 0; - if (add_storage(OPENSSL_malloc(vinfo->puballoc), NULL, 0, key)) + if (add_storage(OPENSSL_malloc(vinfo->puballoc), NULL, 0, 0, key)) ret = parse_pubkey(in, mdctx, key); if (!ret) @@ -1869,7 +1869,7 @@ int ossl_ml_kem_parse_private_key(const uint8_t *in, size_t len, return 0; if (add_storage(OPENSSL_malloc(vinfo->puballoc), - OPENSSL_secure_malloc(vinfo->prvalloc), 1, key)) + OPENSSL_secure_malloc(vinfo->prvalloc), 1, 0, key)) ret = parse_prvkey(in, mdctx, key); if (!ret) @@ -1918,7 +1918,7 @@ int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key) CONSTTIME_SECRET(seed, ML_KEM_SEED_BYTES); if (add_storage(OPENSSL_malloc(vinfo->puballoc), - OPENSSL_secure_malloc(vinfo->prvalloc), 1, key)) + OPENSSL_secure_malloc(vinfo->prvalloc), 1, 0, key)) ret = genkey(seed, mdctx, pubenc, key); OPENSSL_cleanse(seed, sizeof(seed)); diff --git a/test/endecode_test.c b/test/endecode_test.c index 823ac06194f..8afbee59ba3 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -60,6 +60,7 @@ static OSSL_PROVIDER *keyprov = NULL; #ifndef OPENSSL_NO_EC static BN_CTX *bnctx = NULL; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES static OSSL_PARAM_BLD *bld_prime_nc = NULL; static OSSL_PARAM_BLD *bld_prime = NULL; static OSSL_PARAM *ec_explicit_prime_params_nc = NULL; @@ -72,6 +73,7 @@ static OSSL_PARAM *ec_explicit_tri_params_nc = NULL; static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL; #endif #endif +#endif #ifndef OPENSSL_NO_KEYPARAMS static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams) @@ -912,21 +914,161 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key) test_mem, check_public_MSBLOB, dump_der, 0); } +/* + * Build a public-only EVP_PKEY of the same algorithm as |src| by + * round-tripping the public component through OSSL_PARAMs. + */ +static EVP_PKEY *make_public_only_copy(EVP_PKEY *src) +{ + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *cctx = NULL; + EVP_PKEY *pub = NULL; + + if (!EVP_PKEY_todata(src, EVP_PKEY_PUBLIC_KEY, ¶ms)) + goto end; + if ((cctx = EVP_PKEY_CTX_new_from_pkey(NULL, src, NULL)) == NULL + || EVP_PKEY_fromdata_init(cctx) <= 0 + || EVP_PKEY_fromdata(cctx, &pub, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + EVP_PKEY_free(pub); + pub = NULL; + } +end: + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(cctx); + return pub; +} + +/* + * Build an "embryonic" EVP_PKEY of the same algorithm as |src|: just + * the keymgmt-bound type and (where applicable) domain parameters + * copied across, with no key material. Mirrors the idiom used in + * test/ml_kem_evp_extra_test.c. + */ +static EVP_PKEY *make_embryonic_copy(EVP_PKEY *src) +{ + EVP_PKEY *embryo = EVP_PKEY_new(); + + if (embryo == NULL) + return NULL; + if (EVP_PKEY_copy_parameters(embryo, src) <= 0) { + EVP_PKEY_free(embryo); + return NULL; + } + return embryo; +} + +/* + * Check that EVP_PKEY_dup() works for every supported provider-backed + * key type, and that the duplicate compares equal to the original. + * + * Exercised in three shapes: + * 1. The full keypair |key| (typically pub + priv). + * 2. A public-only key derived from |key|. + * 3. An "embryonic" key (algorithm + domain parameters only, no key + * material) produced with EVP_PKEY_copy_parameters(). + */ +static int test_dup(const char *type, EVP_PKEY *key) +{ + EVP_PKEY *dup = NULL; + EVP_PKEY *pub_only = NULL; + EVP_PKEY *embryo = NULL; + int ok = 0; + + if (!TEST_ptr(key)) { + TEST_info("%s: no source key", type); + return 0; + } + + /* 1. Dup the full keypair. */ + if (!TEST_ptr(dup = EVP_PKEY_dup(key))) { + TEST_info("%s: EVP_PKEY_dup of keypair returned NULL", type); + goto end; + } + if (!TEST_int_eq(EVP_PKEY_eq(key, dup), 1)) { + TEST_info("%s: keypair dup does not compare equal to original", type); + goto end; + } + EVP_PKEY_free(dup); + dup = NULL; + + /* 2. Dup a public-only copy of the same key. */ + if (!TEST_ptr(pub_only = make_public_only_copy(key))) { + TEST_info("%s: could not derive a public-only key", type); + goto end; + } + if (!TEST_ptr(dup = EVP_PKEY_dup(pub_only))) { + TEST_info("%s: EVP_PKEY_dup of public-only key returned NULL", type); + goto end; + } + if (!TEST_int_eq(EVP_PKEY_eq(pub_only, dup), 1)) { + TEST_info("%s: public-only dup does not compare equal to original", + type); + goto end; + } + EVP_PKEY_free(dup); + dup = NULL; + + /* + * 3. Dup an embryonic key (just algorithm + domain parameters, no + * key bits). Not every keymgmt allows building such a key: RSA's + * dup op, for instance, deliberately refuses any selection without + * keypair bits ("do not allow creating empty keys by duplication"), + * which makes EVP_PKEY_copy_parameters() fail for RSA / RSA-PSS. + * Treat that as a graceful skip rather than a hard failure. + * + * Where an embryo can be built, the right comparator is + * EVP_PKEY_parameters_eq(): EVP_PKEY_eq() returns 0 for material- + * less keys because it requires public bits to match. Algorithms + * without domain parameters may legitimately answer -2 ("nothing + * to compare"). We only reject 0 (definitively unequal) and -1 + * (different keymgmts). + */ + embryo = make_embryonic_copy(key); + if (embryo != NULL) { + if (!TEST_ptr(dup = EVP_PKEY_dup(embryo))) { + TEST_info("%s: EVP_PKEY_dup of embryonic key returned NULL", + type); + goto end; + } + { + int eq = EVP_PKEY_parameters_eq(embryo, dup); + + if (!TEST_true(eq == 1 || eq == -2)) { + TEST_info("%s: embryonic dup parameters_eq %d (want 1 or -2)", + type, eq); + goto end; + } + } + } else { + TEST_info("%s: skipping embryonic dup (no params-only key shape)", + type); + } + + ok = 1; +end: + EVP_PKEY_free(dup); + EVP_PKEY_free(pub_only); + EVP_PKEY_free(embryo); + return ok; +} + #define KEYS(KEYTYPE) \ static EVP_PKEY *key_##KEYTYPE = NULL #define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \ - ok = ok \ - && TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, NULL, params)) + ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, NULL, params)) #define FREE_KEYS(KEYTYPE) \ EVP_PKEY_free(key_##KEYTYPE); #define DOMAIN_KEYS(KEYTYPE) \ static EVP_PKEY *template_##KEYTYPE = NULL; \ static EVP_PKEY *key_##KEYTYPE = NULL -#define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params) \ - ok = ok \ - && TEST_ptr(template_##KEYTYPE = make_template(KEYTYPEstr, params)) \ - && TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, template_##KEYTYPE, NULL)) +#define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params) \ + do { \ + ok &= TEST_ptr(template_##KEYTYPE = make_template(KEYTYPEstr, \ + params)); \ + ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, \ + template_##KEYTYPE, NULL)); \ + } while (0) #define FREE_DOMAIN_KEYS(KEYTYPE) \ EVP_PKEY_free(template_##KEYTYPE); \ EVP_PKEY_free(key_##KEYTYPE) @@ -959,16 +1101,25 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key) static int test_public_##KEYTYPE##_via_PEM(void) \ { \ return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \ + } \ + static int test_dup_##KEYTYPE(void) \ + { \ + return test_dup(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE(KEYTYPE) \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_i2d); \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \ - ADD_TEST(test_protected_##KEYTYPE##_via_DER); \ - ADD_TEST(test_protected_##KEYTYPE##_via_PEM); \ - ADD_TEST(test_public_##KEYTYPE##_via_DER); \ - ADD_TEST(test_public_##KEYTYPE##_via_PEM) +#define ADD_TEST_SUITE(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) { \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_i2d); \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \ + ADD_TEST(test_protected_##KEYTYPE##_via_DER); \ + ADD_TEST(test_protected_##KEYTYPE##_via_PEM); \ + ADD_TEST(test_public_##KEYTYPE##_via_DER); \ + ADD_TEST(test_public_##KEYTYPE##_via_PEM); \ + ADD_TEST(test_dup_##KEYTYPE); \ + } \ + } while (0) #define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr) \ static int test_params_##KEYTYPE##_via_DER(void) \ @@ -980,9 +1131,13 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key) return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE_PARAMS(KEYTYPE) \ - ADD_TEST(test_params_##KEYTYPE##_via_DER); \ - ADD_TEST(test_params_##KEYTYPE##_via_PEM) +#define ADD_TEST_SUITE_PARAMS(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) { \ + ADD_TEST(test_params_##KEYTYPE##_via_DER); \ + ADD_TEST(test_params_##KEYTYPE##_via_PEM); \ + } \ + } while (0) #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr) \ static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void) \ @@ -994,9 +1149,13 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key) return test_protected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE_LEGACY(KEYTYPE) \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \ - ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM) +#define ADD_TEST_SUITE_LEGACY(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) { \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \ + ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM); \ + } \ + } while (0) #define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr) \ static int test_unprotected_##KEYTYPE##_via_MSBLOB(void) \ @@ -1008,25 +1167,35 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key) return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE_MSBLOB(KEYTYPE) \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \ - ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB) +#define ADD_TEST_SUITE_MSBLOB(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) { \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \ + ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB); \ + } \ + } while (0) #define IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE, KEYTYPEstr) \ static int test_unprotected_##KEYTYPE##_via_PVK(void) \ { \ return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE) \ - ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK) +#define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK); \ + } while (0) #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_PVKKDF) #define IMPLEMENT_TEST_SUITE_PROTECTED_PVK(KEYTYPE, KEYTYPEstr) \ static int test_protected_##KEYTYPE##_via_PVK(void) \ { \ return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \ } -#define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE) \ - ADD_TEST(test_protected_##KEYTYPE##_via_PVK) +#define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE) \ + do { \ + if (key_##KEYTYPE != NULL) \ + ADD_TEST(test_protected_##KEYTYPE##_via_PVK); \ + } while (0) #endif #ifndef OPENSSL_NO_DH @@ -1057,6 +1226,7 @@ DOMAIN_KEYS(EC); IMPLEMENT_TEST_SUITE(EC, "EC", 1) IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC") IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC") +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES DOMAIN_KEYS(ECExplicitPrimeNamedCurve); IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC", 1) IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC") @@ -1071,6 +1241,7 @@ DOMAIN_KEYS(ECExplicitTri2G); IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC", 0) IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC") #endif +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ #ifndef OPENSSL_NO_SM2 KEYS(SM2); IMPLEMENT_TEST_SUITE(SM2, "SM2", 0) @@ -1153,6 +1324,7 @@ IMPLEMENT_TEST_SUITE(ML_DSA_87, "ML-DSA-87", 1) #endif /* OPENSSL_NO_ML_DSA */ #ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES /* Explicit parameters that match a named curve */ static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld, const unsigned char *gen, @@ -1333,6 +1505,7 @@ static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld) return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2)); } #endif /* OPENSSL_NO_EC2M */ +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ /* * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects @@ -1472,8 +1645,10 @@ int setup_tests(void) return 0; #ifndef OPENSSL_NO_EC - if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx)) - || !TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new()) + if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx))) + return 0; +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES + if (!TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new()) || !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new()) || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc) || !create_ec_explicit_prime_params(bld_prime) @@ -1489,6 +1664,7 @@ int setup_tests(void) #endif ) return 0; +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ #endif TEST_info("Generating keys..."); @@ -1505,12 +1681,14 @@ int setup_tests(void) #ifndef OPENSSL_NO_EC TEST_info("Generating EC keys..."); MAKE_DOMAIN_KEYS(EC, "EC", EC_params); +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc); MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit); #ifndef OPENSSL_NO_EC2M MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc); MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit); #endif +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ #ifndef OPENSSL_NO_SM2 MAKE_KEYS(SM2, "SM2", NULL); #endif @@ -1553,12 +1731,17 @@ int setup_tests(void) #endif /* OPENSSL_NO_SLH_DSA */ TEST_info("Loading RSA key..."); - ok = ok && TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx)); + ok &= TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx)); TEST_info("Loading RSA_PSS key..."); - ok = ok && TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx)); + ok &= TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx)); TEST_info("Generating keys done"); - if (ok) { + /* + * Register every test whose key was successfully generated. The + * per-algorithm key_##KEYTYPE != NULL guard inside each + * ADD_TEST_SUITE* macro keeps us from referencing missing keys. + */ + { #ifndef OPENSSL_NO_DH ADD_TEST_SUITE(DH); ADD_TEST_SUITE_PARAMS(DH); @@ -1584,6 +1767,7 @@ int setup_tests(void) ADD_TEST_SUITE(EC); ADD_TEST_SUITE_PARAMS(EC); ADD_TEST_SUITE_LEGACY(EC); +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES ADD_TEST_SUITE(ECExplicitPrimeNamedCurve); ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve); ADD_TEST_SUITE(ECExplicitPrime2G); @@ -1594,6 +1778,7 @@ int setup_tests(void) ADD_TEST_SUITE(ECExplicitTri2G); ADD_TEST_SUITE_LEGACY(ECExplicitTri2G); #endif +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ #ifndef OPENSSL_NO_SM2 if (!is_fips_3_0_0) { /* 3.0.0 FIPS provider imports explicit EC params and then fails. */ @@ -1657,12 +1842,13 @@ int setup_tests(void) #endif /* OPENSSL_NO_SLH_DSA */ } - return 1; + return ok; } void cleanup_tests(void) { #ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES OSSL_PARAM_free(ec_explicit_prime_params_nc); OSSL_PARAM_free(ec_explicit_prime_params_explicit); OSSL_PARAM_BLD_free(bld_prime_nc); @@ -1673,6 +1859,7 @@ void cleanup_tests(void) OSSL_PARAM_BLD_free(bld_tri_nc); OSSL_PARAM_BLD_free(bld_tri); #endif +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ BN_CTX_free(bnctx); #endif /* OPENSSL_NO_EC */ @@ -1685,12 +1872,14 @@ void cleanup_tests(void) #endif #ifndef OPENSSL_NO_EC FREE_DOMAIN_KEYS(EC); +#ifndef OPENSSL_NO_EC_EXPLICIT_CURVES FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve); FREE_DOMAIN_KEYS(ECExplicitPrime2G); #ifndef OPENSSL_NO_EC2M FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve); FREE_DOMAIN_KEYS(ECExplicitTri2G); #endif +#endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */ #ifndef OPENSSL_NO_SM2 FREE_KEYS(SM2); #endif