]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
EVP: Adapt the RSA specific EVP_PKEY_CTX setter / getter functions
authorRichard Levitte <levitte@openssl.org>
Mon, 25 Jan 2021 14:38:32 +0000 (15:38 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 23 Feb 2021 12:41:48 +0000 (13:41 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13913)

crypto/evp/ctrl_params_translate.c
crypto/rsa/rsa_lib.c

index 84a55e4d078e9ab2ed5b40a451a5ff0ddf4c6e98..1e7001809b96b101afc47eb1d8e20a6574f3daf6 100644 (file)
@@ -89,10 +89,12 @@ struct translation_st;           /* Forwarding */
  *                              The return value from the fixup_args call
  *                              with the POST_CTRL_TO_PARAMS state becomes
  *                              the return value back to EVP_PKEY_CTX_ctrl().
+ *
  * CLEANUP_CTRL_TO_PARAMS       The cleanup_args functions has been called
  *                              from EVP_PKEY_CTX_ctrl(), to clean up what
  *                              the fixup_args function has done, if needed.
  *
+ *
  * PRE_CTRL_STR_TO_PARAMS       The fixup_args function has been called
  * POST_CTRL_STR_TO_PARAMS      from EVP_PKEY_CTX_ctrl_str(), to help with
  *                              translating the ctrl_str data to an
@@ -111,6 +113,7 @@ struct translation_st;           /* Forwarding */
  *                              With the POST_CTRL_STR_TO_PARAMS state,
  *                              the fixup_args function is only expected
  *                              to return a value.
+ *
  * CLEANUP_CTRL_STR_TO_PARAMS   The cleanup_args functions has been called
  *                              from EVP_PKEY_CTX_ctrl_str(), to clean up
  *                              what the fixup_args function has done, if
@@ -136,6 +139,7 @@ struct translation_st;           /* Forwarding */
  *                              fixup_args function is expected to
  *                              modify the passed |*params| in whatever
  *                              way necessary, when |action_type == GET|.
+ *
  * CLEANUP_PARAMS_TO_CTRL       The cleanup_args functions has been called
  *                              from EVP_PKEY_CTX_get_params() or
  *                              EVP_PKEY_CTX_set_params(), to clean up what
@@ -198,7 +202,7 @@ struct translation_ctx_st {
      */
 
     /*
-     * copy of the ctrl-style void* argument, if the the fixup_args function
+     * Copy of the ctrl-style void* argument, if the the fixup_args function
      * needs to manipulate |p2| but wants to remember original.
      */
     void *orig_p2;
index 6ca4f3a5414359e25a21cfda0c3520934ad8f1fa..817372cbb769af4bb1d84321e26c768963c53292 100644 (file)
@@ -838,399 +838,219 @@ int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
 }
 
 #ifndef FIPS_MODULE
-int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
+/* Helpers to set or get diverse hash algorithm names */
+static int int_set_rsa_md_name(EVP_PKEY_CTX *ctx,
+                               /* For checks */
+                               int keytype, int optype,
+                               /* For EVP_PKEY_CTX_set_params() */
+                               const char *mdkey, const char *mdname,
+                               const char *propkey, const char *mdprops)
 {
-    OSSL_PARAM pad_params[2], *p = pad_params;
+    OSSL_PARAM params[3], *p = params;
 
-    if (ctx == NULL) {
+    if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
         return -2;
     }
 
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-         || ctx->op.ciph.ciphprovctx == NULL)
-        && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-            || ctx->op.sig.sigprovctx == NULL))
-        return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING,
-                                 pad_mode, NULL);
+    /* If key type not RSA return error */
+    switch (keytype) {
+    case -1:
+        if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+            && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
+            return -1;
+        break;
+    default:
+        if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype)))
+            return -1;
+        break;
+    }
 
-    *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, &pad_mode);
+    /* Cast away the const. This is read only so should be safe */
+    *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, 0);
+    if (evp_pkey_ctx_is_provided(ctx) && mdprops != NULL) {
+        /* Cast away the const. This is read only so should be safe */
+        *p++ = OSSL_PARAM_construct_utf8_string(propkey, (char *)mdprops, 0);
+    }
     *p++ = OSSL_PARAM_construct_end();
 
-    return EVP_PKEY_CTX_set_params(ctx, pad_params);
+    return evp_pkey_ctx_set_params_strict(ctx, params);
 }
 
-int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
+/* Helpers to set or get diverse hash algorithm names */
+static int int_get_rsa_md_name(EVP_PKEY_CTX *ctx,
+                               /* For checks */
+                               int keytype, int optype,
+                               /* For EVP_PKEY_CTX_get_params() */
+                               const char *mdkey,
+                               char *mdname, size_t mdnamesize)
 {
-    OSSL_PARAM pad_params[2], *p = pad_params;
+    OSSL_PARAM params[2], *p = params;
 
-    if (ctx == NULL || pad_mode == NULL) {
+    if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
         return -2;
     }
 
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-         || ctx->op.ciph.ciphprovctx == NULL)
-        && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-            || ctx->op.sig.sigprovctx == NULL))
-        return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0,
-                                 pad_mode);
+    /* If key type not RSA return error */
+    switch (keytype) {
+    case -1:
+        if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+            && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
+            return -1;
+        break;
+    default:
+        if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype)))
+            return -1;
+        break;
+    }
 
-    *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, pad_mode);
+    /* Cast away the const. This is read only so should be safe */
+    *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, mdnamesize);
     *p++ = OSSL_PARAM_construct_end();
 
-    if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
-        return 0;
+    return evp_pkey_ctx_get_params_strict(ctx, params);
+}
 
-    return 1;
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated?
+ */
+int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
+{
+    return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING,
+                             pad_mode, NULL);
+}
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated?
+ */
+int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
+{
+    return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING,
+                             0, pad_mode);
 }
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of passing a name?
+ */
 int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
-    const char *name;
-
-    if (ctx == NULL || md == NULL) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL
-        && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-        && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.keymgmt.genctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
-                                 EVP_PKEY_CTRL_MD, 0, (void *)md);
-
-    name = EVP_MD_name(md);
-
-    return EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(ctx, name, NULL);
+    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+                             EVP_PKEY_CTRL_MD, 0, (void *)(md));
 }
 
 int EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx,
                                             const char *mdname,
                                             const char *mdprops)
 {
-    OSSL_PARAM rsa_params[3], *p = rsa_params;
-
-    if (ctx == NULL || mdname == NULL) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL
-        && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-        && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST,
-                                            /*
-                                             * Cast away the const. This is read
-                                             * only so should be safe
-                                             */
-                                            (char *)mdname, 0);
-    if (mdprops != NULL) {
-        *p++ = OSSL_PARAM_construct_utf8_string(
-                    OSSL_PKEY_PARAM_RSA_DIGEST_PROPS,
-                    /*
-                     * Cast away the const. This is read only so should be safe
-                     */
-                    (char *)mdprops, 0);
-    }
-    *p++ = OSSL_PARAM_construct_end();
-
-    return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+    return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+                               OSSL_PKEY_PARAM_RSA_DIGEST, mdname,
+                               OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, mdprops);
 }
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of passing a name?
+ */
 int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
-    const char *name;
-
-    if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.ciph.ciphprovctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                                 EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md);
-
-    name = (md == NULL) ? "" : EVP_MD_name(md);
-
-    return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, name, NULL);
+    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+                             EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md));
 }
 
 int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
                                       const char *mdprops)
 {
-    OSSL_PARAM rsa_params[3], *p = rsa_params;
-
-    if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
-        return -1;
-
-
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
-                                            /*
-                                             * Cast away the const. This is read
-                                             * only so should be safe
-                                             */
-                                            (char *)mdname, 0);
-    if (mdprops != NULL) {
-        *p++ = OSSL_PARAM_construct_utf8_string(
-                    OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS,
-                    /*
-                     * Cast away the const. This is read
-                     * only so should be safe
-                     */
-                    (char *)mdprops, 0);
-    }
-    *p++ = OSSL_PARAM_construct_end();
-
-    return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+    return
+        int_set_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+                            OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, mdname,
+                            OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, mdprops);
 }
 
 int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name,
-                                      size_t namelen)
+                                      size_t namesize)
 {
-    OSSL_PARAM rsa_params[2], *p = rsa_params;
-
-    if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
-        return -1;
-
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
-                                            name, namelen);
-    *p++ = OSSL_PARAM_construct_end();
-
-    if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
-        return -1;
-
-    return 1;
+    return int_get_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+                               OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
+                               name, namesize);
 }
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of getting a name?
+ */
 int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
 {
-    /* 80 should be big enough */
-    char name[80] = "";
-
-    if (ctx == NULL || md == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.ciph.ciphprovctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                                 EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
-
-    if (EVP_PKEY_CTX_get_rsa_oaep_md_name(ctx, name, sizeof(name)) <= 0)
-        return -1;
-
-    /* May be NULL meaning "unknown" */
-    *md = evp_get_digestbyname_ex(ctx->libctx, name);
-
-    return 1;
+    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+                             EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
 }
 
-static int int_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx,
-                               /* For EVP_PKEY_CTX_ctrl() */
-                               int keytype, int optype, int cmd,
-                               const EVP_MD *md,
                              /* For EVP_PKEY_CTX_set_params() */
-                               const char *mdname, const char *mdprops)
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of passing a name?
+ */
+int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
-    OSSL_PARAM rsa_params[3], *p = rsa_params;
-
-    if (ctx == NULL || (ctx->operation & optype) == 0) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL
-        && (keytype == -1
-            ? (ctx->pmeth->pkey_id != EVP_PKEY_RSA
-               && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-            : ctx->pmeth->pkey_id != keytype))
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (cmd != -1) {
-        if ((EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-             && ctx->op.ciph.ciphprovctx == NULL)
-            || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-                && ctx->op.sig.sigprovctx == NULL)
-            || (EVP_PKEY_CTX_IS_GEN_OP(ctx)
-                && ctx->op.keymgmt.genctx == NULL))
-            return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, (void *)md);
-
-        mdname = (md == NULL) ? "" : EVP_MD_name(md);
-    }
-
-
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
-                                            /*
-                                             * Cast away the const. This is
-                                             * read only so should be safe
-                                             */
-                                            (char *)mdname, 0);
-    if (mdprops != NULL) {
-        *p++ =
-            OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_PROPERTIES,
-                                             /*
-                                              * Cast away the const. This is
-                                              * read only so should be safe
-                                              */
-                                             (char *)mdprops, 0);
-    }
-    *p++ = OSSL_PARAM_construct_end();
-
-    return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+    return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+                             EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md));
 }
 
-int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
+                                      const char *mdprops)
 {
-    return int_set_rsa_mgf1_md(ctx, -1,
+    return int_set_rsa_md_name(ctx, -1,
                                EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
-                               EVP_PKEY_CTRL_RSA_MGF1_MD, md, NULL, NULL);
+                               OSSL_PKEY_PARAM_MGF1_DIGEST, mdname,
+                               OSSL_PKEY_PARAM_MGF1_PROPERTIES, mdprops);
 }
 
-int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
-                                      const char *mdprops)
+int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
+                                      size_t namesize)
 {
-    return int_set_rsa_mgf1_md(ctx, -1,
+    return int_get_rsa_md_name(ctx, -1,
                                EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
-                               -1, NULL, mdname, mdprops);
+                               OSSL_PKEY_PARAM_MGF1_DIGEST, name, namesize);
 }
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of passing a name?
+ */
 int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
 {
-    return int_set_rsa_mgf1_md(ctx, EVP_PKEY_RSA_PSS,
-                               EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_MGF1_MD,
-                               md, NULL, NULL);
+    return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+                             EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md));
 }
 
 int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name(EVP_PKEY_CTX *ctx,
                                                  const char *mdname)
 {
-    return int_set_rsa_mgf1_md(ctx, EVP_PKEY_RSA_PSS,
-                               EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
-                               -1, NULL, mdname, NULL);
-}
-
-int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
-                                      size_t namelen)
-{
-    OSSL_PARAM rsa_params[2], *p = rsa_params;
-
-    if (ctx == NULL
-            || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-                && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
-                                            name, namelen);
-    *p++ = OSSL_PARAM_construct_end();
-
-    if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
-        return -1;
-
-    return 1;
+    return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+                               OSSL_PKEY_PARAM_MGF1_DIGEST, mdname,
+                               NULL, NULL);
 }
 
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ * TODO(3.0) Should this be deprecated in favor of getting a name?
+ */
 int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
 {
-    /* 80 should be big enough */
-    char name[80] = "";
-
-    if (ctx == NULL
-            || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-                && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if ((EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
-                && ctx->op.ciph.ciphprovctx == NULL)
-            || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-                && ctx->op.sig.sigprovctx == NULL))
-        return EVP_PKEY_CTX_ctrl(ctx, -1,
-                                 EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
-                                 EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)md);
-
-    if (EVP_PKEY_CTX_get_rsa_mgf1_md_name(ctx, name, sizeof(name)) <= 0)
-        return -1;
-
-    /* May be NULL meaning "unknown" */
-    *md = evp_get_digestbyname_ex(ctx->libctx, name);
-
-    return 1;
+    return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+                             EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(md));
 }
 
 int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
@@ -1244,27 +1064,20 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
     }
 
     /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+    if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
         return -1;
 
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.ciph.ciphprovctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                                 EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen,
-                                 (void *)label);
+    /* TODO(3.0) Shouldn't a set0 translate into setting an OCTET_PTR? */
 
+    /* Cast away the const. This is read only so should be safe */
     *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL,
-                                             /*
-                                              * Cast away the const. This is
-                                              * read only so should be safe
-                                              */
-                                             (void *)label,
-                                             (size_t)llen);
+                                             (void *)label, (size_t)llen);
     *p++ = OSSL_PARAM_construct_end();
 
-    if (!EVP_PKEY_CTX_set_params(ctx, rsa_params))
+    if (!evp_pkey_ctx_set_params_strict(ctx, rsa_params))
         return 0;
 
+    /* TODO(3.0) ????? */
     OPENSSL_free(label);
     return 1;
 }
@@ -1281,15 +1094,9 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label)
     }
 
     /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+    if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
         return -1;
 
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.ciph.ciphprovctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
-                                 EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0,
-                                 (void *)label);
-
     *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL,
                                           (void **)label, 0);
     *p++ = OSSL_PARAM_construct_end();
@@ -1304,84 +1111,63 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label)
     return (int)labellen;
 }
 
-static int int_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen,
-                                   int keytype, int optype)
-{
-    OSSL_PARAM pad_params[2], *p = pad_params;
-
-    if (ctx == NULL || (ctx->operation & optype) == 0) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-        && (keytype == -1
-            ? (ctx->pmeth->pkey_id != EVP_PKEY_RSA
-               && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
-            : ctx->pmeth->pkey_id != keytype))
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if ((EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-         && ctx->op.sig.sigprovctx == NULL)
-        || (EVP_PKEY_CTX_IS_GEN_OP(ctx)
-            && ctx->op.keymgmt.genctx == NULL))
-        return EVP_PKEY_CTX_ctrl(ctx, keytype, optype,
-                                 EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
-                                 saltlen, NULL);
-
-    *p++ =
-        OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, &saltlen);
-    *p++ = OSSL_PARAM_construct_end();
-
-    return EVP_PKEY_CTX_set_params(ctx, pad_params);
-}
-
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
 int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
 {
-    return int_set_rsa_pss_saltlen(ctx, saltlen, -1, EVP_PKEY_OP_TYPE_SIG);
+    /*
+     * For some reason, the optype was set to this:
+     *
+     * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY
+     *
+     * However, we do use RSA-PSS with the whole gamut of diverse signature
+     * and verification operations, so the optype gets upgraded to this:
+     *
+     * EVP_PKEY_OP_TYPE_SIG
+     */
+    return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG,
+                             EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltlen, NULL);
 }
 
-int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
 {
-    return int_set_rsa_pss_saltlen(ctx, saltlen, EVP_PKEY_RSA_PSS,
-                                   EVP_PKEY_OP_KEYGEN);
+    /*
+     * Because of circumstances, the optype is updated from:
+     *
+     * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY
+     *
+     * to:
+     *
+     * EVP_PKEY_OP_TYPE_SIG
+     */
+    return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG,
+                             EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, saltlen);
 }
 
-int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
+int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
 {
     OSSL_PARAM pad_params[2], *p = pad_params;
 
-    if (ctx == NULL || saltlen == NULL) {
+    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
         return -2;
     }
 
-    /* If key type not RSA or RSA-PSS return error */
-    if (ctx->pmeth != NULL
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA
-            && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
+    if (!EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
         return -1;
 
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
-        || ctx->op.sig.sigprovctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, -1, -1,
-                                 EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN,
-                                 0, saltlen);
-
-    *p++ =
-        OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, saltlen);
+    *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN,
+                                    &saltlen);
     *p++ = OSSL_PARAM_construct_end();
 
-    if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
-        return 0;
-
-    return 1;
-
+    return evp_pkey_ctx_set_params_strict(ctx, pad_params);
 }
 
 int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits)
@@ -1396,84 +1182,49 @@ int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits)
     }
 
     /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA &&
-        ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
+    if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+        && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
         return -1;
 
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.keymgmt.genctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
-                                 EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
-
     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits2);
     *p++ = OSSL_PARAM_construct_end();
 
-    if (!EVP_PKEY_CTX_set_params(ctx, params))
-        return 0;
-
-    return 1;
+    return evp_pkey_ctx_set_params_strict(ctx, params);
 }
 
-static int evp_pkey_ctx_set_rsa_keygen_pubexp_intern(EVP_PKEY_CTX *ctx,
-                                                     BIGNUM *pubexp,
-                                                     int copy)
+int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
 {
-    OSSL_PARAM_BLD *tmpl;
-    OSSL_PARAM *params;
-    int ret;
-
-    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
-        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
-        return -2;
-    }
-
-    /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
-        return -1;
-
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.keymgmt.genctx == NULL) {
-        if (copy == 1)
-            pubexp = BN_dup(pubexp);
-        ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
+    int ret = RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN,
                                 EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp);
-        if ((copy == 1) && (ret <= 0))
-            BN_free(pubexp);
-        return ret;
-    }
-
-    if ((tmpl = OSSL_PARAM_BLD_new()) == NULL)
-        return 0;
-    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, pubexp)
-        || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
-        OSSL_PARAM_BLD_free(tmpl);
-        return 0;
-    }
-    OSSL_PARAM_BLD_free(tmpl);
-
-    ret = EVP_PKEY_CTX_set_params(ctx, params);
-    OSSL_PARAM_BLD_free_params(params);
 
     /*
      * Satisfy memory semantics for pre-3.0 callers of
      * EVP_PKEY_CTX_set_rsa_keygen_pubexp(): their expectation is that input
      * pubexp BIGNUM becomes managed by the EVP_PKEY_CTX on success.
      */
-    if ((copy == 0) && (ret > 0))
+    if (ret > 0 && evp_pkey_ctx_is_provided(ctx)) {
+        BN_free(ctx->rsa_pubexp);
         ctx->rsa_pubexp = pubexp;
+    }
 
     return ret;
 }
 
-int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
-{
-    return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 0);
-}
-
 int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
 {
-    return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 1);
+    int ret = 0;
+
+    /*
+     * When we're dealing with a provider, there's no need to duplicate
+     * pubexp, as it gets copied when transforming to an OSSL_PARAM anyway.
+     */
+    if (evp_pkey_ctx_is_legacy(ctx))
+        pubexp = BN_dup(pubexp);
+    ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
+                            EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp);
+    if (evp_pkey_ctx_is_legacy(ctx) && ret <= 0)
+        BN_free(pubexp);
+    return ret;
 }
 
 int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes)
@@ -1488,21 +1239,13 @@ int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes)
     }
 
     /* If key type not RSA return error */
-    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+    if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+        && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
         return -1;
 
-    /* TODO(3.0): Remove this eventually when no more legacy */
-    if (ctx->op.keymgmt.genctx == NULL)
-        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
-                                 EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes,
-                                 NULL);
-
     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, &primes2);
     *p++ = OSSL_PARAM_construct_end();
 
-    if (!EVP_PKEY_CTX_set_params(ctx, params))
-        return 0;
-
-    return 1;
+    return evp_pkey_ctx_set_params_strict(ctx, params);
 }
 #endif