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");
 }