#include <openssl/x509v3.h>
#include <openssl/core_names.h>
#include <openssl/dh.h>
+#include <openssl/rsa.h>
#include "internal/cryptlib.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
case EVP_PKEY_CTRL_GET_MD:
return EVP_PKEY_CTX_get_signature_md(ctx, p2);
+ case EVP_PKEY_CTRL_RSA_PADDING:
+ return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
+ case EVP_PKEY_CTRL_GET_RSA_PADDING:
+ return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
+ case EVP_PKEY_CTRL_RSA_OAEP_MD:
+ return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
+ case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
+ return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
+ case EVP_PKEY_CTRL_RSA_MGF1_MD:
+ return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
+ case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
+ return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
+ case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
+ return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
+ case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
+ return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
+ case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+ case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_DECRYPT:
+ case EVP_PKEY_CTRL_CMS_ENCRYPT:
+#endif
+ if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
+ return 1;
+ ERR_raise(ERR_LIB_EVP,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
}
return 0;
}
return ret;
}
+ if (strcmp(name, "rsa_padding_mode") == 0) {
+ int pm;
+
+ if (strcmp(value, "pkcs1") == 0) {
+ pm = RSA_PKCS1_PADDING;
+ } else if (strcmp(value, "sslv23") == 0) {
+ pm = RSA_SSLV23_PADDING;
+ } else if (strcmp(value, "none") == 0) {
+ pm = RSA_NO_PADDING;
+ } else if (strcmp(value, "oeap") == 0) {
+ pm = RSA_PKCS1_OAEP_PADDING;
+ } else if (strcmp(value, "oaep") == 0) {
+ pm = RSA_PKCS1_OAEP_PADDING;
+ } else if (strcmp(value, "x931") == 0) {
+ pm = RSA_X931_PADDING;
+ } else if (strcmp(value, "pss") == 0) {
+ pm = RSA_PKCS1_PSS_PADDING;
+ } else {
+ ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE);
+ return -2;
+ }
+ return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+ }
+
+ if (strcmp(name, "rsa_mgf1_md") == 0)
+ return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, value, NULL);
+
+ if (strcmp(name, "rsa_oaep_md") == 0)
+ return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, value, NULL);
+
+ if (strcmp(name, "rsa_oaep_label") == 0) {
+ unsigned char *lab;
+ long lablen;
+ int ret;
+
+ lab = OPENSSL_hexstr2buf(value, &lablen);
+ if (lab == NULL)
+ return 0;
+ ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
+ if (ret <= 0)
+ OPENSSL_free(lab);
+ return ret;
+ }
+
+
+
return 0;
}
#include <stdio.h>
#include <openssl/crypto.h>
+#include <openssl/core_names.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
#include "crypto/bn.h"
-#include <openssl/engine.h>
-#include <openssl/evp.h>
#include "crypto/evp.h"
#include "crypto/rsa.h"
#include "rsa_local.h"
return 1;
}
+
+int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
+{
+ OSSL_PARAM pad_params[2], *p = pad_params;
+
+ if (ctx == 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 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)
+ return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING,
+ pad_mode, NULL);
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, &pad_mode);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, pad_params);
+}
+
+int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
+{
+ OSSL_PARAM pad_params[2], *p = pad_params;
+
+ if (ctx == NULL || pad_mode == 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 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)
+ return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0,
+ pad_mode);
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, pad_mode);
+ *p++ = OSSL_PARAM_construct_end();
+
+ if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
+ return 0;
+
+ return 1;
+
+}
+
+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);
+}
+
+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,
+ strlen(mdname) + 1);
+ 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,
+ strlen(mdprops) + 1);
+ }
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+}
+
+int EVP_PKEY_CTX_get_rsa_oaep_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)) {
+ 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;
+}
+
+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(name);
+
+ return 1;
+}
+
+int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ const char *name;
+
+ 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 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, EVP_PKEY_RSA,
+ EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md);
+
+ name = (md == NULL) ? "" : EVP_MD_name(md);
+
+ return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, name, NULL);
+}
+
+int EVP_PKEY_CTX_set_rsa_mgf1_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
+ || (!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 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_ASYM_CIPHER_PARAM_MGF1_DIGEST,
+ /*
+ * Cast away the const. This is read
+ * only so should be safe
+ */
+ (char *)mdname,
+ strlen(mdname) + 1);
+ if (mdprops != NULL) {
+ *p++ = OSSL_PARAM_construct_utf8_string(
+ OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS,
+ /*
+ * Cast away the const. This is read
+ * only so should be safe
+ */
+ (char *)mdprops,
+ strlen(mdprops) + 1);
+ }
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+}
+
+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_ASYM_CIPHER_PARAM_MGF1_DIGEST,
+ name, namelen);
+ *p++ = OSSL_PARAM_construct_end();
+
+ if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
+ return -1;
+
+ return 1;
+}
+
+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(name);
+
+ return 1;
+}
+
+int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
+{
+ 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;
+
+ /* 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);
+
+ *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);
+ *p++ = OSSL_PARAM_construct_end();
+
+ if (!EVP_PKEY_CTX_set_params(ctx, rsa_params))
+ return 0;
+
+ OPENSSL_free(label);
+ return 1;
+}
+
+int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label)
+{
+ OSSL_PARAM rsa_params[3], *p = rsa_params;
+ size_t labellen;
+
+ 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_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_size_t(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN,
+ &labellen);
+ *p++ = OSSL_PARAM_construct_end();
+
+ if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
+ return -1;
+
+ if (labellen > INT_MAX)
+ return -1;
+
+ return (int)labellen;
+}
#define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */
/* Signature parameters */
-#define OSSL_SIGNATURE_PARAM_DIGEST "digest"
+#define OSSL_SIGNATURE_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST
#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE "digest-size"
+/* Asym cipher parameters */
+#define OSSL_ASYM_CIPHER_PARAM_PAD_MODE "pad-mode"
+#define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST OSSL_ALG_PARAM_DIGEST
+#define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS "digest-props"
+#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST "mgf1-digest"
+#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS "mgf1-digest-props"
+#define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL "oaep-label"
+#define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN "oaep-label-len"
+
# ifdef __cplusplus
}
# endif
# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME
# endif
-# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
- RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL)
-
-# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
- RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)
+int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode);
+int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode);
# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes, NULL)
-# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \
- 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);
+int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
+int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
+ size_t namelen);
+
# define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx, md) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \
EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md))
-# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \
- EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md))
-
-# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \
- RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
- EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(pmd))
-
-# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \
- EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)(pmd))
-
-# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \
- EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)(l))
-
-# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \
- EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)(l))
+int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
+ const char *mdprops);
+int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
+int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name,
+ size_t namelen);
+int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label,
+ int llen);
+int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label);
# define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \
EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, \
0, (void *)(md))
+
# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2)
{ NULL, NULL, NULL }
};
+static const OSSL_ALGORITHM deflt_asym_cipher[] = {
+ { "RSA:rsaEncryption", "default=yes", rsa_asym_cipher_functions },
+ { NULL, NULL, NULL }
+};
static const OSSL_ALGORITHM deflt_keymgmt[] = {
#ifndef OPENSSL_NO_DH
return deflt_keyexch;
case OSSL_OP_SIGNATURE:
return deflt_signature;
+ case OSSL_OP_ASYM_CIPHER:
+ return deflt_asym_cipher;
}
return NULL;
}
--- /dev/null
+LIBS=../../../libcrypto
+SOURCE[../../../libcrypto]=rsa_enc.c
+
+
--- /dev/null
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/rsa.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#include "internal/constant_time.h"
+#include "prov/providercommonerr.h"
+#include "prov/provider_ctx.h"
+#include "prov/implementations.h"
+
+#include <stdlib.h>
+
+static OSSL_OP_asym_cipher_newctx_fn rsa_newctx;
+static OSSL_OP_asym_cipher_encrypt_init_fn rsa_init;
+static OSSL_OP_asym_cipher_encrypt_fn rsa_encrypt;
+static OSSL_OP_asym_cipher_decrypt_init_fn rsa_init;
+static OSSL_OP_asym_cipher_decrypt_fn rsa_decrypt;
+static OSSL_OP_asym_cipher_freectx_fn rsa_freectx;
+static OSSL_OP_asym_cipher_dupctx_fn rsa_dupctx;
+static OSSL_OP_asym_cipher_get_ctx_params_fn rsa_get_ctx_params;
+static OSSL_OP_asym_cipher_gettable_ctx_params_fn rsa_gettable_ctx_params;
+static OSSL_OP_asym_cipher_set_ctx_params_fn rsa_set_ctx_params;
+static OSSL_OP_asym_cipher_settable_ctx_params_fn rsa_settable_ctx_params;
+
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ * We happen to know that our KEYMGMT simply passes RSA structures, so
+ * we use that here too.
+ */
+
+typedef struct {
+ OPENSSL_CTX *libctx;
+ RSA *rsa;
+ int pad_mode;
+ /* OAEP message digest */
+ EVP_MD *oaep_md;
+ /* message digest for MGF1 */
+ EVP_MD *mgf1_md;
+ /* OAEP label */
+ unsigned char *oaep_label;
+ size_t oaep_labellen;
+} PROV_RSA_CTX;
+
+static void *rsa_newctx(void *provctx)
+{
+ PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX));
+
+ if (prsactx == NULL)
+ return NULL;
+ prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+
+ return prsactx;
+}
+
+static int rsa_init(void *vprsactx, void *vrsa)
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+
+ if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa))
+ return 0;
+ RSA_free(prsactx->rsa);
+ prsactx->rsa = vrsa;
+ prsactx->pad_mode = RSA_PKCS1_PADDING;
+ return 1;
+}
+
+static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,
+ size_t outsize, const unsigned char *in, size_t inlen)
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+ int ret;
+
+ if (out == NULL) {
+ size_t len = RSA_size(prsactx->rsa);
+
+ if (len == 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+ return 0;
+ }
+ *outlen = len;
+ return 1;
+ }
+
+ if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int rsasize = RSA_size(prsactx->rsa);
+ unsigned char *tbuf;
+
+ if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) {
+ PROVerr(0, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ret = RSA_padding_add_PKCS1_OAEP_mgf1(tbuf, rsasize, in, inlen,
+ prsactx->oaep_label,
+ prsactx->oaep_labellen,
+ prsactx->oaep_md,
+ prsactx->mgf1_md);
+
+ if (!ret) {
+ OPENSSL_free(tbuf);
+ return 0;
+ }
+ ret = RSA_public_encrypt(rsasize, tbuf, out, prsactx->rsa,
+ RSA_NO_PADDING);
+ OPENSSL_free(tbuf);
+ } else {
+ ret = RSA_public_encrypt(inlen, in, out, prsactx->rsa,
+ prsactx->pad_mode);
+ }
+ /* A ret value of 0 is not an error */
+ if (ret < 0)
+ return ret;
+ *outlen = ret;
+ return 1;
+}
+
+static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen,
+ size_t outsize, const unsigned char *in, size_t inlen)
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+ int ret;
+
+ if (out == NULL) {
+ size_t len = RSA_size(prsactx->rsa);
+
+ if (len == 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+ return 0;
+ }
+ *outlen = len;
+ return 1;
+ }
+
+ if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+ int rsasize = RSA_size(prsactx->rsa);
+ unsigned char *tbuf;
+
+ if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) {
+ PROVerr(0, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ret = RSA_private_decrypt(inlen, in, tbuf, prsactx->rsa,
+ RSA_NO_PADDING);
+ if (ret <= 0) {
+ OPENSSL_free(tbuf);
+ return 0;
+ }
+ ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, tbuf,
+ ret, ret,
+ prsactx->oaep_label,
+ prsactx->oaep_labellen,
+ prsactx->oaep_md,
+ prsactx->mgf1_md);
+ OPENSSL_free(tbuf);
+ } else {
+ ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa,
+ prsactx->pad_mode);
+ }
+ *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret);
+ ret = constant_time_select_int(constant_time_msb(ret), 0, 1);
+ return ret;
+}
+
+static void rsa_freectx(void *vprsactx)
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+
+ RSA_free(prsactx->rsa);
+
+ EVP_MD_free(prsactx->oaep_md);
+ EVP_MD_free(prsactx->mgf1_md);
+
+ OPENSSL_free(prsactx);
+}
+
+static void *rsa_dupctx(void *vprsactx)
+{
+ PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx;
+ PROV_RSA_CTX *dstctx;
+
+ dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+ if (dstctx == NULL)
+ return NULL;
+
+ *dstctx = *srcctx;
+ if (dstctx->rsa != NULL && !RSA_up_ref(dstctx->rsa)) {
+ OPENSSL_free(dstctx);
+ return NULL;
+ }
+
+ if (dstctx->oaep_md != NULL && !EVP_MD_up_ref(dstctx->oaep_md)) {
+ RSA_free(dstctx->rsa);
+ OPENSSL_free(dstctx);
+ return NULL;
+ }
+
+ if (dstctx->mgf1_md != NULL && !EVP_MD_up_ref(dstctx->mgf1_md)) {
+ RSA_free(dstctx->rsa);
+ EVP_MD_free(dstctx->oaep_md);
+ OPENSSL_free(dstctx);
+ return NULL;
+ }
+
+ return dstctx;
+}
+
+static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+ OSSL_PARAM *p;
+
+ if (prsactx == NULL || params == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE);
+ if (p != NULL && !OSSL_PARAM_set_int(p, prsactx->pad_mode))
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST);
+ if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->oaep_md == NULL
+ ? ""
+ : EVP_MD_name(prsactx->oaep_md)))
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST);
+ if (p != NULL) {
+ EVP_MD *mgf1_md = prsactx->mgf1_md == NULL ? prsactx->oaep_md
+ : prsactx->mgf1_md;
+
+ if (!OSSL_PARAM_set_utf8_string(p, mgf1_md == NULL
+ ? ""
+ : EVP_MD_name(mgf1_md)))
+ return 0;
+ }
+
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL);
+ if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, prsactx->oaep_label, 0))
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN);
+ if (p != NULL && !OSSL_PARAM_set_size_t(p, prsactx->oaep_labellen))
+ return 0;
+
+ return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
+ OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
+ OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR,
+ NULL, 0),
+ OSSL_PARAM_size_t(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN, NULL),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *rsa_gettable_ctx_params(void)
+{
+ return known_gettable_ctx_params;
+}
+
+static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
+{
+ PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+ const OSSL_PARAM *p;
+ /* Should be big enough */
+ char mdname[80], mdprops[80] = { '\0' };
+ char *str = mdname;
+ int pad_mode;
+
+ if (prsactx == NULL || params == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST);
+ if (p != NULL) {
+ if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname)))
+ return 0;
+
+ str = mdprops;
+ p = OSSL_PARAM_locate_const(params,
+ OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS);
+ if (p != NULL) {
+ if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops)))
+ return 0;
+ }
+
+ EVP_MD_free(prsactx->oaep_md);
+ prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, mdname, mdprops);
+
+ if (prsactx->oaep_md == NULL)
+ return 0;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE);
+ if (p != NULL) {
+ if (!OSSL_PARAM_get_int(p, &pad_mode))
+ return 0;
+ /*
+ * PSS padding is for signatures only so is not compatible with
+ * asymmetric cipher use.
+ */
+ if (pad_mode == RSA_PKCS1_PSS_PADDING)
+ return 0;
+ if (pad_mode == RSA_PKCS1_OAEP_PADDING && prsactx->oaep_md == NULL) {
+ prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA1", mdprops);
+ if (prsactx->oaep_md == NULL)
+ return 0;
+ }
+ prsactx->pad_mode = pad_mode;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST);
+ if (p != NULL) {
+ if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname)))
+ return 0;
+
+ str = mdprops;
+ p = OSSL_PARAM_locate_const(params,
+ OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS);
+ if (p != NULL) {
+ if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops)))
+ return 0;
+ } else {
+ str = NULL;
+ }
+
+ EVP_MD_free(prsactx->mgf1_md);
+ prsactx->mgf1_md = EVP_MD_fetch(prsactx->libctx, mdname, str);
+
+ if (prsactx->mgf1_md == NULL)
+ return 0;
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL);
+ if (p != NULL) {
+ void *tmp_label = NULL;
+ size_t tmp_labellen;
+
+ if (!OSSL_PARAM_get_octet_string(p, &tmp_label, 0, &tmp_labellen))
+ return 0;
+ OPENSSL_free(prsactx->oaep_label);
+ prsactx->oaep_label = (unsigned char *)tmp_label;
+ prsactx->oaep_labellen = tmp_labellen;
+ }
+
+ return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0),
+ OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL),
+ OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0),
+ OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *rsa_settable_ctx_params(void)
+{
+ return known_settable_ctx_params;
+}
+
+const OSSL_DISPATCH rsa_asym_cipher_functions[] = {
+ { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx },
+ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_init },
+ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt },
+ { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_init },
+ { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt },
+ { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx },
+ { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx },
+ { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS,
+ (void (*)(void))rsa_get_ctx_params },
+ { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS,
+ (void (*)(void))rsa_gettable_ctx_params },
+ { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS,
+ (void (*)(void))rsa_set_ctx_params },
+ { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS,
+ (void (*)(void))rsa_settable_ctx_params },
+ { 0, NULL }
+};
-SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature
+SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature asymciphers
/* Signature */
extern const OSSL_DISPATCH dsa_signature_functions[];
+
+/* Asym Cipher */
+extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
EVP_ASYM_CIPHER_number ? 3_0_0 EXIST::FUNCTION:
EVP_ASYM_CIPHER_do_all_provided ? 3_0_0 EXIST::FUNCTION:
EVP_ASYM_CIPHER_names_do_all ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_set_rsa_padding ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get_rsa_padding ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_set_rsa_mgf1_md ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_set_rsa_mgf1_md_name ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get_rsa_mgf1_md ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_set_rsa_oaep_md ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_set_rsa_oaep_md_name ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get_rsa_oaep_md ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_set0_rsa_oaep_label ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get0_rsa_oaep_label ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get_rsa_mgf1_md_name ? 3_0_0 EXIST::FUNCTION:RSA
+EVP_PKEY_CTX_get_rsa_oaep_md_name ? 3_0_0 EXIST::FUNCTION:RSA