2
0
mirror of https://github.com/openssl/openssl.git synced 2025-04-24 20:51:14 +08:00

EVP: Adapt the RSA specific EVP_PKEY_CTX setter / getter functions

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13913)
This commit is contained in:
Richard Levitte 2021-01-25 15:38:32 +01:00
parent df4592cbec
commit 13f91a7245
2 changed files with 232 additions and 485 deletions

@ -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;

@ -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) {
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);
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_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)
&& (!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);
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_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_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
{
const char *name;
if (ctx == NULL || md == 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 return error */
if (ctx->pmeth != NULL
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA
&& ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
return -1;
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;
}
/* 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);
/* 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();
name = EVP_MD_name(md);
return evp_pkey_ctx_set_params_strict(ctx, params);
}
return EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(ctx, name, NULL);
/* 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 params[2], *p = params;
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 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;
}
/* 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();
return evp_pkey_ctx_get_params_strict(ctx, params);
}
/*
* 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)
{
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;
}
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)
{
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 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
}
/*
* 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)
{
return int_set_rsa_mgf1_md(ctx, -1,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_RSA_MGF1_MD, md, NULL, NULL);
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_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,
-1, NULL, mdname, mdprops);
OSSL_PKEY_PARAM_MGF1_DIGEST, mdname,
OSSL_PKEY_PARAM_MGF1_PROPERTIES, mdprops);
}
int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
size_t namesize)
{
return int_get_rsa_md_name(ctx, -1,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
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);
}
/*
* 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)
{
/*
* 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_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
{
return int_set_rsa_pss_saltlen(ctx, saltlen, EVP_PKEY_RSA_PSS,
EVP_PKEY_OP_KEYGEN);
}
int EVP_PKEY_CTX_get_rsa_pss_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