mirror of
https://github.com/openssl/openssl.git
synced 2024-12-03 05:41:46 +08:00
PROV: Add RSA functionality for key generation
This includes added support in legacy controls Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10289)
This commit is contained in:
parent
6292475573
commit
2972af109e
@ -951,6 +951,12 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL;
|
||||
else if (strcmp(name, "rsa_pss_saltlen") == 0)
|
||||
name = OSSL_SIGNATURE_PARAM_PSS_SALTLEN;
|
||||
else if (strcmp(name, "rsa_keygen_bits") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_BITS;
|
||||
else if (strcmp(name, "rsa_keygen_pubexp") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_E;
|
||||
else if (strcmp(name, "rsa_keygen_primes") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_PRIMES;
|
||||
# ifndef OPENSSL_NO_DH
|
||||
else if (strcmp(name, "dh_pad") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_PAD;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/param_build.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/rsa.h"
|
||||
@ -1266,4 +1267,94 @@ int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits)
|
||||
{
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
size_t bits2 = bits;
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
|
||||
EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp);
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, pubexp)
|
||||
|| (params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
return 0;
|
||||
|
||||
ret = EVP_PKEY_CTX_set_params(ctx, params);
|
||||
ossl_param_bld_free(params);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes)
|
||||
{
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
size_t primes2 = primes;
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
@ -221,7 +221,7 @@ extern "C" {
|
||||
#define OSSL_PKEY_PARAM_RSA_EXPONENT "rsa-exponent"
|
||||
#define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient"
|
||||
/* Key generation parameters */
|
||||
#define OSSL_PKEY_PARAM_RSA_BITS "bits"
|
||||
#define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS
|
||||
#define OSSL_PKEY_PARAM_RSA_PRIMES "primes"
|
||||
|
||||
/* Key Exchange parameters */
|
||||
|
@ -111,6 +111,10 @@ int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode);
|
||||
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen);
|
||||
int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen);
|
||||
|
||||
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits);
|
||||
int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
|
||||
int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes);
|
||||
|
||||
/* Salt length matches digest */
|
||||
# define RSA_PSS_SALTLEN_DIGEST -1
|
||||
/* Verify only: auto detect salt length */
|
||||
@ -124,18 +128,6 @@ int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen);
|
||||
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \
|
||||
EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL)
|
||||
|
||||
# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
|
||||
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \
|
||||
EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
|
||||
|
||||
# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
|
||||
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \
|
||||
EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
|
||||
|
||||
# define EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) \
|
||||
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \
|
||||
EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes, NULL)
|
||||
|
||||
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);
|
||||
|
@ -28,6 +28,11 @@
|
||||
#include "crypto/rsa.h"
|
||||
|
||||
static OSSL_OP_keymgmt_new_fn rsa_newdata;
|
||||
static OSSL_OP_keymgmt_gen_init_fn rsa_gen_init;
|
||||
static OSSL_OP_keymgmt_gen_set_params_fn rsa_gen_set_params;
|
||||
static OSSL_OP_keymgmt_gen_settable_params_fn rsa_gen_settable_params;
|
||||
static OSSL_OP_keymgmt_gen_fn rsa_gen;
|
||||
static OSSL_OP_keymgmt_gen_cleanup_fn rsa_gen_cleanup;
|
||||
static OSSL_OP_keymgmt_free_fn rsa_freedata;
|
||||
static OSSL_OP_keymgmt_get_params_fn rsa_get_params;
|
||||
static OSSL_OP_keymgmt_gettable_params_fn rsa_gettable_params;
|
||||
@ -409,8 +414,127 @@ static int rsa_validate(void *keydata, int selection)
|
||||
return ok;
|
||||
}
|
||||
|
||||
struct rsa_gen_ctx {
|
||||
OPENSSL_CTX *libctx;
|
||||
|
||||
size_t nbits;
|
||||
BIGNUM *pub_exp;
|
||||
size_t primes;
|
||||
|
||||
/* For generation callback */
|
||||
OSSL_CALLBACK *cb;
|
||||
void *cbarg;
|
||||
};
|
||||
|
||||
static int rsa_gencb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
struct rsa_gen_ctx *gctx = BN_GENCB_get_arg(cb);
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);
|
||||
params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
|
||||
|
||||
return gctx->cb(params, gctx->cbarg);
|
||||
}
|
||||
|
||||
static void *rsa_gen_init(void *provctx, int selection)
|
||||
{
|
||||
OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
|
||||
struct rsa_gen_ctx *gctx = NULL;
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
|
||||
return NULL;
|
||||
|
||||
if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
|
||||
gctx->libctx = libctx;
|
||||
if ((gctx->pub_exp = BN_new()) == NULL
|
||||
|| !BN_set_word(gctx->pub_exp, RSA_F4)) {
|
||||
BN_free(gctx->pub_exp);
|
||||
gctx = NULL;
|
||||
} else {
|
||||
gctx->nbits = 2048;
|
||||
gctx->primes = RSA_DEFAULT_PRIME_NUM;
|
||||
}
|
||||
}
|
||||
return gctx;
|
||||
}
|
||||
|
||||
static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
|
||||
{
|
||||
struct rsa_gen_ctx *gctx = genctx;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_BITS)) != NULL
|
||||
&& !OSSL_PARAM_get_size_t(p, &gctx->nbits))
|
||||
return 0;
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PRIMES)) != NULL
|
||||
&& !OSSL_PARAM_get_size_t(p, &gctx->primes))
|
||||
return 0;
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E)) != NULL
|
||||
&& !OSSL_PARAM_get_BN(p, &gctx->pub_exp))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *rsa_gen_settable_params(void *provctx)
|
||||
{
|
||||
static OSSL_PARAM settable[] = {
|
||||
OSSL_PARAM_size_t(OSSL_PKEY_PARAM_RSA_BITS, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, NULL),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
return settable;
|
||||
}
|
||||
|
||||
static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
|
||||
{
|
||||
struct rsa_gen_ctx *gctx = genctx;
|
||||
RSA *rsa = NULL;
|
||||
BN_GENCB *gencb = NULL;
|
||||
|
||||
if (gctx == NULL
|
||||
|| (rsa = rsa_new_with_ctx(gctx->libctx)) == NULL)
|
||||
return NULL;
|
||||
|
||||
gctx->cb = osslcb;
|
||||
gctx->cbarg = cbarg;
|
||||
gencb = BN_GENCB_new();
|
||||
if (gencb != NULL)
|
||||
BN_GENCB_set(gencb, rsa_gencb, genctx);
|
||||
|
||||
if (!RSA_generate_multi_prime_key(rsa, (int)gctx->nbits, (int)gctx->primes,
|
||||
gctx->pub_exp, gencb)) {
|
||||
RSA_free(rsa);
|
||||
rsa = NULL;
|
||||
}
|
||||
|
||||
BN_GENCB_free(gencb);
|
||||
|
||||
return rsa;
|
||||
}
|
||||
|
||||
static void rsa_gen_cleanup(void *genctx)
|
||||
{
|
||||
struct rsa_gen_ctx *gctx = genctx;
|
||||
|
||||
if (gctx == NULL)
|
||||
return;
|
||||
|
||||
BN_clear_free(gctx->pub_exp);
|
||||
OPENSSL_free(gctx);
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH rsa_keymgmt_functions[] = {
|
||||
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))rsa_newdata },
|
||||
{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))rsa_gen_init },
|
||||
{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS,
|
||||
(void (*)(void))rsa_gen_set_params },
|
||||
{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
|
||||
(void (*)(void))rsa_gen_settable_params },
|
||||
{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))rsa_gen },
|
||||
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))rsa_gen_cleanup },
|
||||
{ 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 },
|
||||
|
@ -4981,3 +4981,6 @@ OSSL_CMP_SRV_CTX_set_accept_unprotected ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_SRV_CTX_set_accept_raverified ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_SRV_CTX_set_grant_implicit_confirm ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
EVP_PKEY_gen ? 3_0_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_set_rsa_keygen_bits ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
EVP_PKEY_CTX_set_rsa_keygen_pubexp ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
EVP_PKEY_CTX_set_rsa_keygen_primes ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
|
Loading…
Reference in New Issue
Block a user