Commit 8991dafa37 for openssl.org

commit 8991dafa37d2bd0960bdd0579819150ac4c57a80
Author: Pauli <paul.dale@oracle.com>
Date:   Tue Aug 25 16:38:12 2026 +1000

    rsa: use selection-specific import decoders

    Assisted-by: ChatGPT:gpt-5.6Sol

    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
    (Merged from https://github.com/openssl/openssl/pull/32502)

diff --git a/include/crypto/rsa_params.h.in b/include/crypto/rsa_params.h.in
index 10188299df..e7fcf95cc1 100644
--- a/include/crypto/rsa_params.h.in
+++ b/include/crypto/rsa_params.h.in
@@ -7,11 +7,17 @@
  * https://www.openssl.org/source/license.html
  */

+#ifndef OSSL_CRYPTO_RSA_PARAMS_H
+#define OSSL_CRYPTO_RSA_PARAMS_H
+
+/* clang-format off */
+
 {-
 use OpenSSL::paramnames qw(produce_param_decoder);
 -}

 #include "crypto/rsa.h"
+#include <openssl/core_names.h>
 #include <openssl/err.h>
 #include <openssl/proverr.h>

@@ -114,17 +120,24 @@ return "";
 #define rsa_pss_todata_st rsa_params_st
 {- produce_param_decoder('rsa_pss_todata', @RSA_PSS_EXPORT_TYPES); -}

-/* The provider keymgmt import path parses its input only once. */
-#define rsa_import_st rsa_params_st
-{- produce_param_decoder('rsa_import',
-                         (@RSA_KEY_TYPES,
-                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'],
-                          @RSA_PSS_IMPORT_TYPES
-                         )); -}
-
-/* Parameters processed by rsa_get_params(), including conditional ACVP data. */
+/*
+ * Parameters processed by plain RSA get_params(), including conditional ACVP
+ * data.
+ */
 #define rsa_get_params_st rsa_params_st
 {- produce_param_decoder('rsa_get_params',
+                         (['OSSL_PKEY_PARAM_BITS',              'bits',            'int'],
+                          ['OSSL_PKEY_PARAM_SECURITY_BITS',     'secbits',          'int'],
+                          ['OSSL_PKEY_PARAM_MAX_SIZE',          'maxsize',          'int'],
+                          ['OSSL_PKEY_PARAM_SECURITY_CATEGORY', 'seccat',           'int'],
+                          ['OSSL_PKEY_PARAM_DEFAULT_DIGEST',    'default_digest',   'utf8_string'],
+                          @RSA_KEY_TYPES,
+                          @RSA_ACVP_OUTPUT_TYPES
+                         )); -}
+
+/* Parameters processed by RSA-PSS get_params(). */
+#define rsapss_get_params_st rsa_params_st
+{- produce_param_decoder('rsapss_get_params',
                          (['OSSL_PKEY_PARAM_BITS',              'bits',            'int'],
                           ['OSSL_PKEY_PARAM_SECURITY_BITS',     'secbits',          'int'],
                           ['OSSL_PKEY_PARAM_MAX_SIZE',          'maxsize',          'int'],
@@ -154,8 +167,7 @@ return "";
 #define rsa_pkey_import_from_st rsa_params_st
 {- produce_param_decoder('rsa_pkey_import_from',
                          (@RSA_KEY_TYPES,
-                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'],
-                          @RSA_PSS_IMPORT_TYPES
+                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int']
                          )); -}

 #define rsa_pss_pkey_import_from_st rsa_params_st
@@ -173,8 +185,7 @@ return "";
 {- produce_param_decoder('rsa_acvp_output', @RSA_ACVP_OUTPUT_TYPES); -}

 /* Selection-specific import and export declarations. */
-#define rsa_key_import_types_st
-#define rsa_key_import_types_decoder
+#define rsa_key_import_types_st rsa_params_st
 {- produce_param_decoder('rsa_key_import_types',
                          (@RSA_KEY_TYPES,
                           ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int']
@@ -184,23 +195,52 @@ return "";
 #define rsa_key_export_types_decoder
 {- produce_param_decoder('rsa_key_export_types', @RSA_KEY_TYPES); -}

-#define rsa_other_import_types_st
-#define rsa_other_import_types_decoder
-{- produce_param_decoder('rsa_other_import_types', @RSA_PSS_IMPORT_TYPES); -}
+#define rsa_other_import_types_st rsa_params_st
+{- produce_param_decoder('rsa_other_import_types'); -}

 #define rsa_other_export_types_st
 #define rsa_other_export_types_decoder
-{- produce_param_decoder('rsa_other_export_types', @RSA_PSS_EXPORT_TYPES); -}
+{- produce_param_decoder('rsa_other_export_types'); -}

-#define rsa_all_import_types_st
-#define rsa_all_import_types_decoder
+#define rsa_all_import_types_st rsa_params_st
 {- produce_param_decoder('rsa_all_import_types',
                          (@RSA_KEY_TYPES,
-                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'],
-                          @RSA_PSS_IMPORT_TYPES
+                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int']
                          )); -}

 #define rsa_all_export_types_st
 #define rsa_all_export_types_decoder
-{- produce_param_decoder('rsa_all_export_types',
+{- produce_param_decoder('rsa_all_export_types', @RSA_KEY_TYPES); -}
+
+#define rsapss_key_import_types_st rsa_params_st
+{- produce_param_decoder('rsapss_key_import_types',
+                         (@RSA_KEY_TYPES,
+                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int']
+                         )); -}
+
+#define rsapss_key_export_types_st
+#define rsapss_key_export_types_decoder
+{- produce_param_decoder('rsapss_key_export_types', @RSA_KEY_TYPES); -}
+
+#define rsapss_other_import_types_st rsa_params_st
+{- produce_param_decoder('rsapss_other_import_types', @RSA_PSS_IMPORT_TYPES); -}
+
+#define rsapss_other_export_types_st
+#define rsapss_other_export_types_decoder
+{- produce_param_decoder('rsapss_other_export_types', @RSA_PSS_EXPORT_TYPES); -}
+
+#define rsapss_all_import_types_st rsa_params_st
+{- produce_param_decoder('rsapss_all_import_types',
+                         (@RSA_KEY_TYPES,
+                          ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'],
+                          @RSA_PSS_IMPORT_TYPES
+                         )); -}
+
+#define rsapss_all_export_types_st
+#define rsapss_all_export_types_decoder
+{- produce_param_decoder('rsapss_all_export_types',
                          (@RSA_KEY_TYPES, @RSA_PSS_EXPORT_TYPES)); -}
+
+/* clang-format on */
+
+#endif
diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c
index 5056b1fc5f..ceb6f02cda 100644
--- a/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -44,14 +44,18 @@ static OSSL_FUNC_keymgmt_load_fn rsa_load;
 static OSSL_FUNC_keymgmt_load_fn rsapss_load;
 static OSSL_FUNC_keymgmt_free_fn rsa_freedata;
 static OSSL_FUNC_keymgmt_get_params_fn rsa_get_params;
+static OSSL_FUNC_keymgmt_get_params_fn rsapss_get_params;
 static OSSL_FUNC_keymgmt_gettable_params_fn rsa_gettable_params;
+static OSSL_FUNC_keymgmt_gettable_params_fn rsapss_gettable_params;
 static OSSL_FUNC_keymgmt_has_fn rsa_has;
 static OSSL_FUNC_keymgmt_match_fn rsa_match;
 static OSSL_FUNC_keymgmt_validate_fn rsa_validate;
 static OSSL_FUNC_keymgmt_import_fn rsa_import;
 static OSSL_FUNC_keymgmt_import_types_fn rsa_import_types;
+static OSSL_FUNC_keymgmt_import_types_fn rsapss_import_types;
 static OSSL_FUNC_keymgmt_export_fn rsa_export;
 static OSSL_FUNC_keymgmt_export_types_fn rsa_export_types;
+static OSSL_FUNC_keymgmt_export_types_fn rsapss_export_types;
 static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_query_operation_name;
 static OSSL_FUNC_keymgmt_dup_fn rsa_dup;

@@ -228,22 +232,94 @@ static int rsa_match(const void *keydata1, const void *keydata2, int selection)
     return ok;
 }

+enum {
+    RSA_IMEXPORT_TYPE_NONE = 0,
+    RSA_IMEXPORT_TYPE_OTHER = 1,
+    RSA_IMEXPORT_TYPE_KEY = 2,
+    RSA_IMEXPORT_TYPE_ALL = RSA_IMEXPORT_TYPE_OTHER | RSA_IMEXPORT_TYPE_KEY,
+    RSA_IMEXPORT_TYPE_COUNT
+};
+
+typedef int (*rsa_import_types_decoder_fn)(const OSSL_PARAM *, RSA_PARAMS *);
+
+struct rsa_imexport_types_st {
+    const OSSL_PARAM *import_types;
+    rsa_import_types_decoder_fn import_decoder;
+    const OSSL_PARAM *export_types;
+};
+
+static const struct rsa_imexport_types_st
+    rsa_imexport_types[RSA_IMEXPORT_TYPE_COUNT]
+    = {
+          [RSA_IMEXPORT_TYPE_OTHER] = {
+              rsa_other_import_types_list,
+              rsa_other_import_types_decoder,
+              rsa_other_export_types_list,
+          },
+          [RSA_IMEXPORT_TYPE_KEY] = {
+              rsa_key_import_types_list,
+              rsa_key_import_types_decoder,
+              rsa_key_export_types_list,
+          },
+          [RSA_IMEXPORT_TYPE_ALL] = {
+              rsa_all_import_types_list,
+              rsa_all_import_types_decoder,
+              rsa_all_export_types_list,
+          },
+      };
+
+static const struct rsa_imexport_types_st
+    rsapss_imexport_types[RSA_IMEXPORT_TYPE_COUNT]
+    = {
+          [RSA_IMEXPORT_TYPE_OTHER] = {
+              rsapss_other_import_types_list,
+              rsapss_other_import_types_decoder,
+              rsapss_other_export_types_list,
+          },
+          [RSA_IMEXPORT_TYPE_KEY] = {
+              rsapss_key_import_types_list,
+              rsapss_key_import_types_decoder,
+              rsapss_key_export_types_list,
+          },
+          [RSA_IMEXPORT_TYPE_ALL] = {
+              rsapss_all_import_types_list,
+              rsapss_all_import_types_decoder,
+              rsapss_all_export_types_list,
+          },
+      };
+
+static int rsa_imexport_type_select(int selection)
+{
+    int type_select = RSA_IMEXPORT_TYPE_NONE;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
+        type_select |= RSA_IMEXPORT_TYPE_OTHER;
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
+        type_select |= RSA_IMEXPORT_TYPE_KEY;
+    return type_select;
+}
+
 static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[])
 {
     RSA *rsa = keydata;
     RSA_PARAMS p;
+    const struct rsa_imexport_types_st *types;
+    int type_select;
     int rsa_type;
     int ok = 1;
     int pss_defaults_set = 0;

-    if (!ossl_prov_is_running() || rsa == NULL
-        || !rsa_import_decoder(params, &p))
-        return 0;
-
-    if ((selection & RSA_POSSIBLE_SELECTIONS) == 0)
+    if (!ossl_prov_is_running() || rsa == NULL)
         return 0;

+    type_select = rsa_imexport_type_select(selection);
     rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK);
+    types = rsa_type == RSA_FLAG_TYPE_RSASSAPSS
+        ? rsapss_imexport_types
+        : rsa_imexport_types;
+    if (type_select == RSA_IMEXPORT_TYPE_NONE
+        || !types[type_select].import_decoder(params, &p))
+        return 0;

     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
         ok = ok && pss_params_fromdata(ossl_rsa_get0_pss_params_30(rsa), &pss_defaults_set, &p, rsa_type, ossl_rsa_get0_libctx(rsa));
@@ -263,12 +339,14 @@ static int rsa_export(void *keydata, int selection,
     const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa);
     OSSL_PARAM_BLD *tmpl;
     OSSL_PARAM *params = NULL;
+    int type_select;
     int ok = 1;

     if (!ossl_prov_is_running() || rsa == NULL)
         return 0;

-    if ((selection & RSA_POSSIBLE_SELECTIONS) == 0)
+    type_select = rsa_imexport_type_select(selection);
+    if (type_select == RSA_IMEXPORT_TYPE_NONE)
         return 0;

     tmpl = OSSL_PARAM_BLD_new();
@@ -297,52 +375,37 @@ err:

 static const OSSL_PARAM *rsa_import_types(int selection)
 {
-    int type_select = 0;
+    return rsa_imexport_types[rsa_imexport_type_select(selection)].import_types;
+}

-    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
-        type_select += 1;
-    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
-        type_select += 2;
-    switch (type_select) {
-    case 1:
-        return rsa_other_import_types_list;
-    case 2:
-        return rsa_key_import_types_list;
-    case 3:
-        return rsa_all_import_types_list;
-    default:
-        return NULL;
-    }
+static const OSSL_PARAM *rsapss_import_types(int selection)
+{
+    return rsapss_imexport_types[rsa_imexport_type_select(selection)]
+        .import_types;
 }

 static const OSSL_PARAM *rsa_export_types(int selection)
 {
-    int type_select = 0;
+    return rsa_imexport_types[rsa_imexport_type_select(selection)].export_types;
+}

-    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
-        type_select += 1;
-    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
-        type_select += 2;
-    switch (type_select) {
-    case 1:
-        return rsa_other_export_types_list;
-    case 2:
-        return rsa_key_export_types_list;
-    case 3:
-        return rsa_all_export_types_list;
-    default:
-        return NULL;
-    }
+static const OSSL_PARAM *rsapss_export_types(int selection)
+{
+    return rsapss_imexport_types[rsa_imexport_type_select(selection)]
+        .export_types;
 }

-static int rsa_get_params(void *key, OSSL_PARAM params[])
+typedef int (*rsa_get_params_decoder_fn)(const OSSL_PARAM *, RSA_PARAMS *);
+
+static int common_get_params(void *key, OSSL_PARAM params[],
+    rsa_get_params_decoder_fn decoder)
 {
     RSA *rsa = key;
     RSA_PARAMS p;
     const RSA_PSS_PARAMS_30 *pss_params;
     int rsa_type, empty;

-    if (rsa == NULL || !rsa_get_params_decoder(params, &p))
+    if (rsa == NULL || !decoder(params, &p))
         return 0;
     pss_params = ossl_rsa_get0_pss_params_30(rsa);
     rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK);
@@ -389,11 +452,26 @@ static int rsa_get_params(void *key, OSSL_PARAM params[])
         && ossl_rsa_todata_parsed(rsa, NULL, &p, 1);
 }

+static int rsa_get_params(void *key, OSSL_PARAM params[])
+{
+    return common_get_params(key, params, rsa_get_params_decoder);
+}
+
+static int rsapss_get_params(void *key, OSSL_PARAM params[])
+{
+    return common_get_params(key, params, rsapss_get_params_decoder);
+}
+
 static const OSSL_PARAM *rsa_gettable_params(void *provctx)
 {
     return rsa_get_params_list;
 }

+static const OSSL_PARAM *rsapss_gettable_params(void *provctx)
+{
+    return rsapss_get_params_list;
+}
+
 static int rsa_validate(const void *keydata, int selection, int checktype)
 {
     const RSA *rsa = keydata;
@@ -739,15 +817,16 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = {
     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))rsa_gen_cleanup },
     { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))rsapss_load },
     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))rsa_freedata },
-    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))rsa_get_params },
-    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))rsa_gettable_params },
+    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))rsapss_get_params },
+    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS,
+        (void (*)(void))rsapss_gettable_params },
     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))rsa_has },
     { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))rsa_match },
     { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))rsa_validate },
     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))rsa_import },
-    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsa_import_types },
+    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsapss_import_types },
     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export },
-    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types },
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsapss_export_types },
     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
         (void (*)(void))rsa_query_operation_name },
     { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup },
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 94fd17a268..c65dd9ca7f 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -9893,6 +9893,8 @@ int setup_tests(void)
     ADD_TEST(test_RSA_verify_recover_rejects_short_buffer);
     ADD_TEST(test_RSA_verify_recover_empty_payload);
     ADD_TEST(test_RSA_encrypt);
+    ADD_TEST(test_EVP_rsa_pss_utf8_ptr_params);
+    ADD_TEST(test_rsa_algorithm_param_lists);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     ADD_TEST(test_RSA_legacy);
 #endif