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;
#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"
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
#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 */
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 */
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);
#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;
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 },
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