Commit 8f6fd3f5b5 for openssl.org
commit 8f6fd3f5b5d700d6b6e63e14e8e0bbc7a68cc04e
Author: Simo Sorce <simo@redhat.com>
Date: Tue Sep 1 22:18:58 2026 -0400
Pass parameters to evp_keymgmt_newdata
Update EVP keymgmt utility and export functions to pass provided parameters,
such as property queries, to evp_keymgmt_newdata() instead of NULL.
Implement OSSL_FUNC_KEYMGMT_NEW_EX in the ML-DSA key management implementation
to parse and apply property query parameters during key allocation, and add
corresponding test coverage.
Assisted-by: Gemini:Gemini 3.7 Flash
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Merge-date: Mon Sep 7 18:53:10 2026
Merged-from: https://github.com/openssl/openssl/pull/32636
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index 1d80c747b7..108601e939 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -33,7 +33,7 @@ int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg)
/* Just in time creation of keydata */
if (data->keydata == NULL) {
- if ((data->keydata = evp_keymgmt_newdata(data->keymgmt, NULL)) == NULL) {
+ if ((data->keydata = evp_keymgmt_newdata(data->keymgmt, params)) == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
return 0;
}
@@ -320,7 +320,7 @@ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
{
void *keydata = NULL;
- if ((keydata = evp_keymgmt_newdata(keymgmt, NULL)) == NULL
+ if ((keydata = evp_keymgmt_newdata(keymgmt, params)) == NULL
|| !evp_keymgmt_import(keymgmt, keydata, selection, params)
|| !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) {
evp_keymgmt_freedata(keymgmt, keydata);
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index f13390b54e..5fdcebf55c 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -1912,6 +1912,10 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
params[0] = OSSL_PARAM_construct_octet_ptr("legacy-object",
&pk->pkey.ptr, sizeof(pk->pkey.ptr));
p = params;
+ } else if (propquery != NULL) {
+ params[0] = OSSL_PARAM_construct_utf8_string(
+ OSSL_PKEY_PARAM_PROPERTIES, (char *)propquery, 0);
+ p = params;
}
keydata = evp_keymgmt_newdata(tmp_keymgmt, p);
if (keydata == NULL)
diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.c b/providers/implementations/keymgmt/ml_dsa_kmgmt.c
index 218ef685b7..97de656676 100644
--- a/providers/implementations/keymgmt/ml_dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/ml_dsa_kmgmt.c
@@ -145,6 +145,23 @@ ML_DSA_KEY *ossl_prov_ml_dsa_new(PROV_CTX *ctx, const char *propq, int evp_type)
return key;
}
+static ML_DSA_KEY *ossl_prov_ml_dsa_new_ex(PROV_CTX *ctx, const OSSL_PARAM params[], int evp_type)
+{
+ struct ml_dsa_new_key_ex_params_st p;
+ const char *propq = NULL;
+
+ if (!ml_dsa_new_key_ex_params_decoder(params, &p))
+ return 0;
+
+ if (p.propq != NULL) {
+ if (p.propq->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ propq = p.propq->data;
+ }
+
+ return ossl_prov_ml_dsa_new(ctx, propq, evp_type);
+}
+
static void ml_dsa_free_key(void *keydata)
{
ossl_ml_dsa_key_free((ML_DSA_KEY *)keydata);
@@ -585,12 +602,17 @@ static void ml_dsa_gen_cleanup(void *genctx)
{ \
return ossl_prov_ml_dsa_new(provctx, NULL, EVP_PKEY_ML_DSA_##alg); \
} \
+ static void *ml_dsa_##alg##_new_key_ex(void *provctx, const OSSL_PARAM params[]) \
+ { \
+ return ossl_prov_ml_dsa_new_ex(provctx, params, EVP_PKEY_ML_DSA_##alg); \
+ } \
static void *ml_dsa_##alg##_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) \
{ \
return ml_dsa_gen(genctx, EVP_PKEY_ML_DSA_##alg); \
} \
const OSSL_DISPATCH ossl_ml_dsa_##alg##_keymgmt_functions[] = { \
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ml_dsa_##alg##_new_key }, \
+ { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))ml_dsa_##alg##_new_key_ex }, \
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ml_dsa_free_key }, \
{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ml_dsa_has }, \
{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ml_dsa_match }, \
diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in b/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in
index 9ab17f5f65..388a0bd65b 100644
--- a/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in
+++ b/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in
@@ -39,3 +39,7 @@ use OpenSSL::paramnames qw(produce_param_decoder);
(['OSSL_PKEY_PARAM_ML_DSA_SEED', 'seed', 'octet_string'],
['OSSL_PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'],
)); -}
+
+{- produce_param_decoder('ml_dsa_new_key_ex_params',
+ (['OSSL_PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'],
+ )); -}
diff --git a/test/ml_dsa_test.c b/test/ml_dsa_test.c
index ca1c1225e2..3eb931404c 100644
--- a/test/ml_dsa_test.c
+++ b/test/ml_dsa_test.c
@@ -17,9 +17,12 @@
#include "crypto/evp.h"
#include "crypto/ml_dsa.h"
+static int do_fips = 0;
+
typedef enum OPTION_choice {
OPT_ERR = -1,
OPT_EOF = 0,
+ OPT_FIPS,
OPT_CONFIG_FILE,
OPT_TEST_ENUM
} OPTION_CHOICE;
@@ -355,6 +358,32 @@ err:
return ret;
}
+static int ml_dsa_newdata_bad_propq_test(void)
+{
+ int ret = 0;
+ EVP_KEYMGMT *keymgmt = NULL;
+ void *keydata = NULL;
+ OSSL_PARAM params[2];
+
+ if (do_fips)
+ return TEST_skip("FIPS not supported");
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES,
+ "provider=fail", 0);
+ params[1] = OSSL_PARAM_construct_end();
+
+ if (!TEST_ptr(keymgmt = EVP_KEYMGMT_fetch(lib_ctx, "ML-DSA-44", NULL)))
+ goto end;
+
+ if (!TEST_ptr_null(keydata = evp_keymgmt_newdata(keymgmt, params)))
+ goto end;
+
+ ret = 1;
+end:
+ EVP_KEYMGMT_free(keymgmt);
+ return ret;
+}
+
static int from_data_invalid_public_test(void)
{
int ret = 0;
@@ -753,6 +782,7 @@ const OPTIONS *test_get_options(void)
{
static const OPTIONS options[] = {
OPT_TEST_OPTIONS_DEFAULT_USAGE,
+ { "fips", OPT_FIPS, '-', "Test with FIPS provider" },
{ "config", OPT_CONFIG_FILE, '<',
"The configuration file to use for the libctx" },
{ NULL }
@@ -767,6 +797,9 @@ int setup_tests(void)
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
+ case OPT_FIPS:
+ do_fips = 1;
+ break;
case OPT_CONFIG_FILE:
config_file = opt_arg();
break;
@@ -797,6 +830,7 @@ int setup_tests(void)
ADD_TEST(from_data_bad_input_test);
ADD_TEST(ml_dsa_digest_sign_verify_test);
ADD_TEST(ml_dsa_priv_pub_bad_t0_test);
+ ADD_TEST(ml_dsa_newdata_bad_propq_test);
/*
* Tested only in the default configuration, with a non-default provider
diff --git a/test/recipes/30-test_ml_dsa.t b/test/recipes/30-test_ml_dsa.t
old mode 100644
new mode 100755
index 142258cfe9..7ca28ac067
--- a/test/recipes/30-test_ml_dsa.t
+++ b/test/recipes/30-test_ml_dsa.t
@@ -92,6 +92,6 @@ SKIP: {
skip "FIPS provider version is too old for ML-DSA test", 1
if !$exit;
- ok(run(test(["ml_dsa_test", "-config", $provconf])),
+ ok(run(test(["ml_dsa_test", "-fips", "-config", $provconf])),
"running ml_dsa_test with FIPS");
}