#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/objects.h>
-#include <openssl/opensslv.h>
#include <openssl/rsa.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/core_names.h>
-#include <openssl/param_build.h>
-#endif
#include <isc/mem.h>
+#include <isc/ossl_wrap.h>
#include <isc/result.h>
#include <isc/safe.h>
#include <isc/string.h>
/* TODO(aydin): remove this crap */
extern EVP_MD *isc__crypto_md[];
-typedef struct rsa_components {
- bool bnfree;
- const BIGNUM *e, *n, *d, *p, *q, *dmp1, *dmq1, *iqmp;
-} rsa_components_t;
-
/* length byte + 1.2.840.113549.1.1.11 BER encoded RFC 4055 */
static unsigned char oid_rsasha256[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b };
static unsigned char oid_rsasha512[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d };
-static isc_result_t
-opensslrsa_components_get(const dst_key_t *key, rsa_components_t *c,
- bool private) {
- REQUIRE(c->e == NULL && c->n == NULL && c->d == NULL && c->p == NULL &&
- c->q == NULL && c->dmp1 == NULL && c->dmq1 == NULL &&
- c->iqmp == NULL);
-
- EVP_PKEY *pub = key->keydata.pkeypair.pub;
- EVP_PKEY *priv = key->keydata.pkeypair.priv;
-
- if (private && priv == NULL) {
- return DST_R_INVALIDPRIVATEKEY;
- }
- /*
- * NOTE: Errors regarding private compoments are ignored.
- *
- * OpenSSL allows omitting the parameters for CRT based calculations
- * (factors, exponents, coefficients). Only the 'd' parameter is
- * mandatory for software keys.
- *
- * However, for a label based keys, all private key component queries
- * can fail if they key is e.g. on a hardware device.
- */
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- if (EVP_PKEY_get_bn_param(pub, OSSL_PKEY_PARAM_RSA_E,
- (BIGNUM **)&c->e) != 1)
- {
- return dst__openssl_toresult(DST_R_OPENSSLFAILURE);
- }
-
- c->bnfree = true;
- if (EVP_PKEY_get_bn_param(pub, OSSL_PKEY_PARAM_RSA_N,
- (BIGNUM **)&c->n) != 1)
- {
- return dst__openssl_toresult(DST_R_OPENSSLFAILURE);
- }
- if (!private) {
- return ISC_R_SUCCESS;
- }
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_D,
- (BIGNUM **)&c->d);
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_FACTOR1,
- (BIGNUM **)&c->p);
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_FACTOR2,
- (BIGNUM **)&c->q);
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_EXPONENT1,
- (BIGNUM **)&c->dmp1);
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_EXPONENT2,
- (BIGNUM **)&c->dmq1);
- (void)EVP_PKEY_get_bn_param(priv, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
- (BIGNUM **)&c->iqmp);
- ERR_clear_error();
- return ISC_R_SUCCESS;
-#else
- const RSA *rsa = EVP_PKEY_get0_RSA(pub);
- if (rsa == NULL) {
- return dst__openssl_toresult(DST_R_OPENSSLFAILURE);
- }
- RSA_get0_key(rsa, &c->n, &c->e, &c->d);
- if (c->e == NULL || c->n == NULL) {
- return dst__openssl_toresult(DST_R_OPENSSLFAILURE);
- }
- if (!private) {
- return ISC_R_SUCCESS;
- }
- rsa = EVP_PKEY_get0_RSA(priv);
- if (rsa == NULL) {
- return dst__openssl_toresult(DST_R_OPENSSLFAILURE);
- }
- RSA_get0_factors(rsa, &c->p, &c->q);
- RSA_get0_crt_params(rsa, &c->dmp1, &c->dmq1, &c->iqmp);
- return ISC_R_SUCCESS;
-#endif
-}
-
-static void
-opensslrsa_components_free(rsa_components_t *c) {
- if (!c->bnfree) {
- return;
- }
- /*
- * NOTE: BN_free() frees the components of the BIGNUM, and if it was
- * created by BN_new(), also the structure itself. BN_clear_free()
- * additionally overwrites the data before the memory is returned to the
- * system. If a is NULL, nothing is done.
- */
- BN_free((BIGNUM *)c->e);
- BN_free((BIGNUM *)c->n);
- BN_clear_free((BIGNUM *)c->d);
- BN_clear_free((BIGNUM *)c->p);
- BN_clear_free((BIGNUM *)c->q);
- BN_clear_free((BIGNUM *)c->dmp1);
- BN_clear_free((BIGNUM *)c->dmq1);
- BN_clear_free((BIGNUM *)c->iqmp);
- c->bnfree = false;
-}
-
static bool
opensslrsa_valid_key_alg(unsigned int key_alg) {
switch (key_alg) {
return ISC_R_SUCCESS;
}
-static bool
-opensslrsa_check_exponent_bits(EVP_PKEY *pkey, int maxbits) {
- /* Always use the new API first with OpenSSL 3.x. */
- int bits = INT_MAX;
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- BIGNUM *e = NULL;
- if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &e) == 1) {
- bits = BN_num_bits(e);
- BN_free(e);
- }
-#else
- const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
- if (rsa != NULL) {
- const BIGNUM *ce = NULL;
- RSA_get0_key(rsa, NULL, &ce, NULL);
- if (ce != NULL) {
- bits = BN_num_bits(ce);
- }
- }
-#endif
- return bits <= maxbits;
-}
-
static isc_result_t
opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dst_key_t *key = NULL;
evp_md_ctx = dctx->ctxdata.evp_md_ctx;
pkey = key->keydata.pkeypair.pub;
- if (!opensslrsa_check_exponent_bits(pkey, OPENSSLRSA_MAX_MODULUS_BITS))
+ if (!isc_ossl_wrap_rsa_key_bits_leq(pkey, OPENSSLRSA_MAX_MODULUS_BITS))
{
return DST_R_VERIFYFAILURE;
}
}
}
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
-static int
-progress_cb(int p, int n, BN_GENCB *cb) {
- void (*fptr)(int);
-
- UNUSED(n);
-
- fptr = BN_GENCB_get_arg(cb);
- if (fptr != NULL) {
- fptr(p);
- }
- return 1;
-}
-
-static isc_result_t
-opensslrsa_generate_pkey(unsigned int key_size, const char *label, BIGNUM *e,
- void (*callback)(int), EVP_PKEY **retkey) {
- RSA *rsa = NULL;
- EVP_PKEY *pkey = NULL;
- BN_GENCB *cb = NULL;
- isc_result_t result;
-
- UNUSED(label);
-
- rsa = RSA_new();
- pkey = EVP_PKEY_new();
- if (rsa == NULL || pkey == NULL) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (EVP_PKEY_set1_RSA(pkey, rsa) != 1) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (callback != NULL) {
- cb = BN_GENCB_new();
- if (cb == NULL) {
- CLEANUP(dst__openssl_toresult(ISC_R_NOMEMORY));
- }
- BN_GENCB_set(cb, progress_cb, (void *)callback);
- }
-
- if (RSA_generate_key_ex(rsa, key_size, e, cb) != 1) {
- CLEANUP(dst__openssl_toresult2("RSA_generate_key_ex",
- DST_R_OPENSSLFAILURE));
- }
- *retkey = pkey;
- pkey = NULL;
- result = ISC_R_SUCCESS;
-
-cleanup:
- EVP_PKEY_free(pkey);
- RSA_free(rsa);
- BN_GENCB_free(cb);
- return result;
-}
-
-static isc_result_t
-opensslrsa_build_pkey(bool private, rsa_components_t *c, EVP_PKEY **retpkey) {
- isc_result_t result;
- EVP_PKEY *pkey = NULL;
- RSA *rsa = RSA_new();
- int status;
-
- REQUIRE(c->bnfree);
-
- if (c->n == NULL || c->e == NULL) {
- if (private) {
- CLEANUP(DST_R_INVALIDPRIVATEKEY);
- }
- CLEANUP(DST_R_INVALIDPUBLICKEY);
- }
-
- if (rsa == NULL) {
- CLEANUP(dst__openssl_toresult2("RSA_new",
- DST_R_OPENSSLFAILURE));
- }
-
- if (RSA_set0_key(rsa, (BIGNUM *)c->n, (BIGNUM *)c->e, (BIGNUM *)c->d) !=
- 1)
- {
- CLEANUP(dst__openssl_toresult2("RSA_set0_key",
- DST_R_OPENSSLFAILURE));
- }
- c->n = NULL;
- c->e = NULL;
- c->d = NULL;
-
- if (c->p != NULL || c->q != NULL) {
- if (RSA_set0_factors(rsa, (BIGNUM *)c->p, (BIGNUM *)c->q) != 1)
- {
- CLEANUP(dst__openssl_toresult2("RSA_set0_factors",
- DST_R_OPENSSLFAILURE));
- }
- c->p = NULL;
- c->q = NULL;
- }
-
- if (c->dmp1 != NULL || c->dmq1 != NULL || c->iqmp != NULL) {
- if (RSA_set0_crt_params(rsa, (BIGNUM *)c->dmp1,
- (BIGNUM *)c->dmq1,
- (BIGNUM *)c->iqmp) == 0)
- {
- CLEANUP(dst__openssl_toresult2("RSA_set0_crt_params",
- DST_R_OPENSSLFAILURE));
- }
- c->dmp1 = NULL;
- c->dmq1 = NULL;
- c->iqmp = NULL;
- }
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_new",
- DST_R_OPENSSLFAILURE));
- }
- status = EVP_PKEY_set1_RSA(pkey, rsa);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_set1_RSA",
- DST_R_OPENSSLFAILURE));
- }
-
- *retpkey = pkey;
- pkey = NULL;
- result = ISC_R_SUCCESS;
-
-cleanup:
- EVP_PKEY_free(pkey);
- RSA_free(rsa);
- opensslrsa_components_free(c);
- return result;
-}
-#else
-static int
-progress_cb(EVP_PKEY_CTX *ctx) {
- void (*fptr)(int);
-
- fptr = EVP_PKEY_CTX_get_app_data(ctx);
- if (fptr != NULL) {
- int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
- fptr(p);
- }
- return 1;
-}
-
-static isc_result_t
-opensslrsa_generate_pkey_with_uri(size_t key_size, const char *label,
- EVP_PKEY **retkey) {
- EVP_PKEY_CTX *ctx = NULL;
- OSSL_PARAM params[4];
- char *uri = UNCONST(label);
- isc_result_t result;
- int status;
-
- params[0] = OSSL_PARAM_construct_utf8_string("pkcs11_uri", uri, 0);
- params[1] = OSSL_PARAM_construct_utf8_string(
- "pkcs11_key_usage", (char *)"digitalSignature", 0);
- params[2] = OSSL_PARAM_construct_size_t("rsa_keygen_bits", &key_size);
- params[3] = OSSL_PARAM_construct_end();
-
- ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=pkcs11");
- if (ctx == NULL) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_CTX_new_from_name",
- DST_R_OPENSSLFAILURE));
- }
-
- status = EVP_PKEY_keygen_init(ctx);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_keygen_init",
- DST_R_OPENSSLFAILURE));
- }
-
- status = EVP_PKEY_CTX_set_params(ctx, params);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_CTX_set_params",
- DST_R_OPENSSLFAILURE));
- }
-
- status = EVP_PKEY_generate(ctx, retkey);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_generate",
- DST_R_OPENSSLFAILURE));
- }
-
- result = ISC_R_SUCCESS;
-cleanup:
- EVP_PKEY_CTX_free(ctx);
- return result;
-}
-
-static isc_result_t
-opensslrsa_generate_pkey(unsigned int key_size, const char *label, BIGNUM *e,
- void (*callback)(int), EVP_PKEY **retkey) {
- EVP_PKEY_CTX *ctx;
- isc_result_t result;
-
- if (label != NULL) {
- return opensslrsa_generate_pkey_with_uri(key_size, label,
- retkey);
- }
-
- ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
- if (ctx == NULL) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (EVP_PKEY_keygen_init(ctx) != 1) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, (int)key_size) != 1) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) != 1) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- if (callback != NULL) {
- EVP_PKEY_CTX_set_app_data(ctx, (void *)callback);
- EVP_PKEY_CTX_set_cb(ctx, progress_cb);
- }
-
- if (EVP_PKEY_keygen(ctx, retkey) != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_keygen",
- DST_R_OPENSSLFAILURE));
- }
- result = ISC_R_SUCCESS;
-cleanup:
- EVP_PKEY_CTX_free(ctx);
- return result;
-}
-
-static isc_result_t
-opensslrsa_build_pkey(bool private, rsa_components_t *c, EVP_PKEY **retpkey) {
- isc_result_t result;
- int status;
- OSSL_PARAM_BLD *bld = NULL;
- OSSL_PARAM *params = NULL;
- EVP_PKEY_CTX *ctx = NULL;
-
- bld = OSSL_PARAM_BLD_new();
- if (bld == NULL) {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_new",
- DST_R_OPENSSLFAILURE));
- }
- if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, c->n) != 1 ||
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, c->e) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
-
- if (c->d != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, c->d) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
- if (c->p != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR1, c->p) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
- if (c->q != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR2, c->q) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
- if (c->dmp1 != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1,
- c->dmp1) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
- if (c->dmq1 != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2,
- c->dmq1) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
- if (c->iqmp != NULL &&
- OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
- c->iqmp) != 1)
- {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN",
- DST_R_OPENSSLFAILURE));
- }
-
- params = OSSL_PARAM_BLD_to_param(bld);
- if (params == NULL) {
- CLEANUP(dst__openssl_toresult2("OSSL_PARAM_BLD_to_param",
- DST_R_OPENSSLFAILURE));
- }
- ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
- if (ctx == NULL) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_CTX_new_from_name",
- DST_R_OPENSSLFAILURE));
- }
- status = EVP_PKEY_fromdata_init(ctx);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_fromdata_init",
- DST_R_OPENSSLFAILURE));
- }
-
- status = EVP_PKEY_fromdata(
- ctx, retpkey, private ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY,
- params);
- if (status != 1) {
- CLEANUP(dst__openssl_toresult2("EVP_PKEY_fromdata",
- DST_R_OPENSSLFAILURE));
- }
- result = ISC_R_SUCCESS;
-
-cleanup:
- EVP_PKEY_CTX_free(ctx);
- OSSL_PARAM_free(params);
- OSSL_PARAM_BLD_free(bld);
- return result;
-}
-#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
-
static isc_result_t
opensslrsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
isc_result_t result;
- BIGNUM *e = BN_new();
EVP_PKEY *pkey = NULL;
UNUSED(unused);
- if (e == NULL) {
- CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
/*
* Reject incorrect RSA key lengths.
*/
UNREACHABLE();
}
- /* e = 65537 (0x10001, F4) */
- BN_set_bit(e, 0);
- BN_set_bit(e, 16);
-
- CHECK(opensslrsa_generate_pkey(key->key_size, key->label, e, callback,
- &pkey));
+ if (key->label != NULL) {
+ CHECK(isc_ossl_wrap_generate_pkcs11_rsa_key(
+ key->label, key->key_size, &pkey));
+ } else {
+ CHECK(isc_ossl_wrap_generate_rsa_key(callback, key->key_size,
+ &pkey));
+ }
key->keydata.pkeypair.pub = pkey;
key->keydata.pkeypair.priv = pkey;
cleanup:
EVP_PKEY_free(pkey);
- BN_free(e);
return result;
}
unsigned int e_bytes;
unsigned int mod_bytes;
isc_result_t result;
- rsa_components_t c = { 0 };
+ isc_ossl_wrap_rsa_components_t c = { 0 };
REQUIRE(key->keydata.pkeypair.pub != NULL);
break;
}
- CHECK(opensslrsa_components_get(key, &c, false));
+ CHECK(isc_ossl_wrap_rsa_public_components(key->keydata.pkeypair.pub,
+ &c));
mod_bytes = BN_num_bytes(c.n);
e_bytes = BN_num_bytes(c.e);
isc_buffer_add(data, e_bytes + mod_bytes);
- result = ISC_R_SUCCESS;
cleanup:
- opensslrsa_components_free(&c);
+ isc_ossl_wrap_rsa_components_cleanup(&c);
return result;
}
isc_region_t r;
unsigned int e_bytes;
unsigned int length;
- rsa_components_t c = { .bnfree = true };
+ isc_ossl_wrap_rsa_components_t c = { .needs_cleanup = true };
REQUIRE(opensslrsa_valid_key_alg(key->key_alg));
isc_buffer_forward(data, length);
key->key_size = BN_num_bits(c.n);
- result = opensslrsa_build_pkey(false, &c, &key->keydata.pkeypair.pub);
+ result = isc_ossl_wrap_load_rsa_public_from_components(
+ &c, &key->keydata.pkeypair.pub);
cleanup:
- opensslrsa_components_free(&c);
+ isc_ossl_wrap_rsa_components_cleanup(&c);
return result;
}
dst_private_t priv = { 0 };
unsigned char *bufs[8] = { NULL };
unsigned short i = 0;
- rsa_components_t c = { 0 };
+ isc_ossl_wrap_rsa_components_t c = { 0 };
if (key->external) {
return dst__privstruct_writefile(key, &priv, directory);
}
- CHECK(opensslrsa_components_get(key, &c, true));
+ CHECK(isc_ossl_wrap_rsa_public_components(key->keydata.pkeypair.pub,
+ &c));
+ CHECK(isc_ossl_wrap_rsa_secret_components(key->keydata.pkeypair.priv,
+ &c));
priv.elements[i].tag = TAG_RSA_MODULUS;
priv.elements[i].length = BN_num_bytes(c.n);
priv.elements[i].length);
}
}
- opensslrsa_components_free(&c);
+ isc_ossl_wrap_rsa_components_cleanup(&c);
return result;
}
isc_mem_t *mctx = NULL;
const char *label = NULL;
EVP_PKEY *pkey = NULL;
- rsa_components_t c = { .bnfree = true };
+ isc_ossl_wrap_rsa_components_t c = { .needs_cleanup = true };
REQUIRE(key != NULL);
REQUIRE(opensslrsa_valid_key_alg(key->key_alg));
}
key->key_size = BN_num_bits(c.n);
- CHECK(opensslrsa_build_pkey(true, &c, &pkey));
+
+ CHECK(isc_ossl_wrap_load_rsa_secret_from_components(&c, &pkey));
/* Check that the public component matches if given */
if (pub != NULL && EVP_PKEY_eq(pkey, pub->keydata.pkeypair.pub) != 1) {
pkey = NULL;
cleanup:
- opensslrsa_components_free(&c);
+ isc_ossl_wrap_rsa_components_cleanup(&c);
EVP_PKEY_free(pkey);
if (result != ISC_R_SUCCESS) {
key->keydata.generic = NULL;
CHECK(dst__openssl_fromlabel(EVP_PKEY_RSA, label, pin, &pubpkey,
&privpkey));
- if (!opensslrsa_check_exponent_bits(pubpkey, RSA_MAX_PUBEXP_BITS)) {
+ if (!isc_ossl_wrap_rsa_key_bits_leq(pubpkey, RSA_MAX_PUBEXP_BITS)) {
CLEANUP(ISC_R_RANGE);
}
static isc_result_t
check_algorithm(unsigned short algorithm) {
- rsa_components_t c = { .bnfree = true };
+ isc_ossl_wrap_rsa_components_t c = { .needs_cleanup = true };
EVP_MD_CTX *evp_md_ctx = EVP_MD_CTX_create();
EVP_PKEY *pkey = NULL;
const EVP_MD *type = NULL;
c.e = BN_bin2bn(e_bytes, sizeof(e_bytes) - 1, NULL);
c.n = BN_bin2bn(n_bytes, sizeof(n_bytes) - 1, NULL);
- result = opensslrsa_build_pkey(false, &c, &pkey);
+ result = isc_ossl_wrap_load_rsa_public_from_components(&c, &pkey);
INSIST(result == ISC_R_SUCCESS);
/*
}
cleanup:
- opensslrsa_components_free(&c);
+ isc_ossl_wrap_rsa_components_cleanup(&c);
EVP_PKEY_free(pkey);
EVP_MD_CTX_destroy(evp_md_ctx);
ERR_clear_error();
* information regarding copyright ownership.
*/
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
#include <isc/ossl_wrap.h>
#include <isc/util.h>
-EMPTY_TRANSLATION_UNIT;
+#define OSSL_WRAP_ERROR(fn) \
+ isc__ossl_wrap_logged_toresult( \
+ ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO, fn, \
+ ISC_R_CRYPTOFAILURE, __FILE__, __LINE__)
+
+static int
+rsa_keygen_progress_cb(int p, int n, BN_GENCB *cb) {
+ void (*fptr)(int);
+
+ UNUSED(n);
+
+ fptr = BN_GENCB_get_arg(cb);
+ if (fptr != NULL) {
+ fptr(p);
+ }
+ return 1;
+}
+
+isc_result_t
+isc_ossl_wrap_generate_rsa_key(void (*callback)(int), size_t bit_size,
+ EVP_PKEY **pkeyp) {
+ RSA *rsa = NULL;
+ EVP_PKEY *pkey = NULL;
+ BN_GENCB *cb = NULL;
+ isc_result_t result;
+ BIGNUM *e;
+
+ e = BN_new();
+
+ /* e = 65537 (0x10001, F4) */
+ BN_set_bit(e, 0);
+ BN_set_bit(e, 16);
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_new"));
+ }
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_new"));
+ }
+
+ if (EVP_PKEY_set1_RSA(pkey, rsa) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_set1_RSA"));
+ }
+
+ if (callback != NULL) {
+ cb = BN_GENCB_new();
+ if (cb == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("BN_GENCB_new"));
+ }
+
+ BN_GENCB_set(cb, rsa_keygen_progress_cb, (void *)callback);
+ }
+
+ if (RSA_generate_key_ex(rsa, bit_size, e, cb) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_generate_key_ex"));
+ }
+ *pkeyp = pkey;
+ pkey = NULL;
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_free(pkey);
+ RSA_free(rsa);
+ BN_GENCB_free(cb);
+ BN_free(e);
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_generate_pkcs11_rsa_key(char *uri, size_t bit_size,
+ EVP_PKEY **pkeyp) {
+ UNUSED(uri);
+
+ return isc_ossl_wrap_generate_rsa_key(NULL, bit_size, pkeyp);
+}
+
+bool
+isc_ossl_wrap_rsa_key_bits_leq(EVP_PKEY *pkey, size_t limit) {
+ const RSA *rsa;
+ const BIGNUM *ce;
+ size_t bits = SIZE_MAX;
+
+ REQUIRE(pkey != NULL);
+
+ rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa != NULL) {
+ ce = NULL;
+ RSA_get0_key(rsa, NULL, &ce, NULL);
+ if (ce != NULL) {
+ bits = BN_num_bits(ce);
+ }
+ }
+
+ return bits <= limit;
+}
+
+isc_result_t
+isc_ossl_wrap_rsa_public_components(EVP_PKEY *pkey,
+ isc_ossl_wrap_rsa_components_t *c) {
+ isc_result_t result;
+ const RSA *rsa;
+
+ REQUIRE(pkey != NULL);
+ REQUIRE(c != NULL && c->e == NULL && c->n == NULL);
+
+ rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_get0_RSA"));
+ }
+
+ RSA_get0_key(rsa, (const BIGNUM **)&c->n, (const BIGNUM **)&c->e, NULL);
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_rsa_secret_components(EVP_PKEY *pkey,
+ isc_ossl_wrap_rsa_components_t *c) {
+ isc_result_t result;
+ const RSA *rsa;
+
+ REQUIRE(pkey != NULL);
+ REQUIRE(c != NULL && c->d == NULL && c->p == NULL && c->q == NULL &&
+ c->dmp1 == NULL && c->dmq1 == NULL && c->iqmp == NULL);
+
+ rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_get0_RSA"));
+ }
+
+ /*
+ * We don't support PKCS11 with OpenSSL <=1.1.1a
+ * d *must* succeed.
+ */
+ RSA_get0_key(rsa, NULL, NULL, (const BIGNUM **)&c->d);
+ if (c->d == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_get0_key"));
+ }
+
+ RSA_get0_factors(rsa, (const BIGNUM **)&c->p, (const BIGNUM **)&c->q);
+ RSA_get0_crt_params(rsa, (const BIGNUM **)&c->dmp1,
+ (const BIGNUM **)&c->dmq1,
+ (const BIGNUM **)&c->iqmp);
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_load_rsa_public_from_components(isc_ossl_wrap_rsa_components_t *c,
+ EVP_PKEY **pkeyp) {
+ isc_result_t result;
+ EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL;
+
+ REQUIRE(pkeyp != NULL && *pkeyp == NULL);
+ REQUIRE(c != NULL && c->e != NULL && c->n != NULL);
+ REQUIRE(c->needs_cleanup);
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_new"));
+ }
+
+ if (RSA_set0_key(rsa, c->n, c->e, NULL) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_set0_key"));
+ }
+
+ c->n = NULL;
+ c->e = NULL;
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_new"));
+ }
+
+ if (EVP_PKEY_set1_RSA(pkey, rsa) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_set1_RSA"));
+ }
+
+ *pkeyp = pkey;
+ pkey = NULL;
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_free(pkey);
+ RSA_free(rsa);
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_load_rsa_secret_from_components(isc_ossl_wrap_rsa_components_t *c,
+ EVP_PKEY **pkeyp) {
+ isc_result_t result;
+ EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL;
+
+ REQUIRE(pkeyp != NULL && *pkeyp == NULL);
+ REQUIRE(c != NULL);
+
+ result = ISC_R_SUCCESS;
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_new"));
+ }
+
+ if (RSA_set0_key(rsa, c->n, c->e, c->d) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_set0_key"));
+ }
+
+ c->n = NULL;
+ c->e = NULL;
+ c->d = NULL;
+
+ if (c->p != NULL || c->q != NULL) {
+ if (RSA_set0_factors(rsa, c->p, c->q) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_set0_factors"));
+ }
+
+ c->p = NULL;
+ c->q = NULL;
+ }
+
+ if (c->dmp1 != NULL || c->dmq1 != NULL || c->iqmp != NULL) {
+ if (RSA_set0_crt_params(rsa, c->dmp1, c->dmq1, c->iqmp) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("RSA_set0_crt_params"));
+ }
+ c->dmp1 = NULL;
+ c->dmq1 = NULL;
+ c->iqmp = NULL;
+ }
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_new"));
+ }
+
+ if (EVP_PKEY_set1_RSA(pkey, rsa) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_set1_RSA"));
+ }
+
+ *pkeyp = pkey;
+ pkey = NULL;
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_free(pkey);
+ RSA_free(rsa);
+ isc_ossl_wrap_rsa_components_cleanup(c);
+ return result;
+}
* information regarding copyright ownership.
*/
+#include <stdbool.h>
+
+#include <openssl/bn.h>
+#include <openssl/core_names.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/param_build.h>
+#include <openssl/rsa.h>
+
#include <isc/ossl_wrap.h>
#include <isc/util.h>
-EMPTY_TRANSLATION_UNIT;
+#define OSSL_WRAP_ERROR(fn) \
+ isc__ossl_wrap_logged_toresult( \
+ ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO, fn, \
+ ISC_R_CRYPTOFAILURE, __FILE__, __LINE__)
+
+static int
+rsa_keygen_progress_cb(EVP_PKEY_CTX *ctx) {
+ void (*fptr)(int);
+
+ fptr = EVP_PKEY_CTX_get_app_data(ctx);
+ if (fptr != NULL) {
+ int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+ fptr(p);
+ }
+ return 1;
+}
+
+isc_result_t
+isc_ossl_wrap_generate_rsa_key(void (*callback)(int), size_t bit_size,
+ EVP_PKEY **pkeyp) {
+ isc_result_t result;
+ EVP_PKEY_CTX *ctx;
+ BIGNUM *e;
+
+ REQUIRE(pkeyp != NULL && *pkeyp == NULL);
+
+ e = BN_new();
+
+ /* e = 65537 (0x10001, F4) */
+ BN_set_bit(e, 0);
+ BN_set_bit(e, 16);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+ if (ctx == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_new_from_name"));
+ }
+
+ if (EVP_PKEY_keygen_init(ctx) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_keygen_init"));
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bit_size) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_set_rsa_keygen_bits"));
+ }
+
+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_set1_rsa_keygen_pubexp"));
+ }
+
+ if (callback != NULL) {
+ EVP_PKEY_CTX_set_app_data(ctx, (void *)callback);
+ EVP_PKEY_CTX_set_cb(ctx, rsa_keygen_progress_cb);
+ }
+
+ if (EVP_PKEY_keygen(ctx, pkeyp) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_keygen"));
+ }
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_CTX_free(ctx);
+ BN_free(e);
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_generate_pkcs11_rsa_key(char *uri, size_t bit_size,
+ EVP_PKEY **pkeyp) {
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM params[4];
+ isc_result_t result;
+ int status;
+
+ params[0] = OSSL_PARAM_construct_utf8_string("pkcs11_uri", uri, 0);
+ params[1] = OSSL_PARAM_construct_utf8_string(
+ "pkcs11_key_usage", (char *)"digitalSignature", 0);
+ params[2] = OSSL_PARAM_construct_size_t("rsa_keygen_bits", &bit_size);
+ params[3] = OSSL_PARAM_construct_end();
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=pkcs11");
+ if (ctx == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_new_from_name"));
+ }
+
+ status = EVP_PKEY_keygen_init(ctx);
+ if (status != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_keygen_init"));
+ }
+
+ status = EVP_PKEY_CTX_set_params(ctx, params);
+ if (status != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_set_params"));
+ }
+
+ status = EVP_PKEY_generate(ctx, pkeyp);
+ if (status != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_generate"));
+ }
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_CTX_free(ctx);
+ return result;
+}
+
+bool
+isc_ossl_wrap_rsa_key_bits_leq(EVP_PKEY *pkey, size_t limit) {
+ size_t bits = SIZE_MAX;
+ BIGNUM *e = NULL;
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &e) == 1) {
+ bits = BN_num_bits(e);
+ BN_free(e);
+ }
+ return bits <= limit;
+}
+
+isc_result_t
+isc_ossl_wrap_rsa_public_components(EVP_PKEY *pkey,
+ isc_ossl_wrap_rsa_components_t *c) {
+ isc_result_t result;
+
+ REQUIRE(pkey != NULL);
+ REQUIRE(c != NULL && c->e == NULL && c->n == NULL);
+
+ c->needs_cleanup = true;
+
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &c->e) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_get_bn_param"));
+ }
+
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &c->n) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_get_bn_param"));
+ }
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_rsa_secret_components(EVP_PKEY *pkey,
+ isc_ossl_wrap_rsa_components_t *c) {
+ REQUIRE(pkey != NULL);
+ REQUIRE(c != NULL && c->d == NULL && c->p == NULL && c->q == NULL &&
+ c->dmp1 == NULL && c->dmq1 == NULL && c->iqmp == NULL);
+
+ c->needs_cleanup = true;
+
+ /*
+ * NOTE: Errors regarding private compoments are ignored.
+ *
+ * OpenSSL allows omitting the parameters for CRT based calculations
+ * (factors, exponents, coefficients). Only the 'd' parameter is
+ * mandatory for software keys.
+ *
+ * However, for a label based keys, all private key component queries
+ * can fail if they key is e.g. on a hardware device.
+ */
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &c->d);
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &c->p);
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &c->q);
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1,
+ &c->dmp1);
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2,
+ &c->dmq1);
+ (void)EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
+ &c->iqmp);
+
+ ERR_clear_error();
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t
+isc_ossl_wrap_load_rsa_public_from_components(isc_ossl_wrap_rsa_components_t *c,
+ EVP_PKEY **pkeyp) {
+ OSSL_PARAM_BLD *bld = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+ OSSL_PARAM *params = NULL;
+ isc_result_t result;
+
+ result = ISC_R_SUCCESS;
+
+ REQUIRE(pkeyp != NULL && *pkeyp == NULL);
+ REQUIRE(c != NULL && c->n != NULL && c->e != NULL);
+
+ bld = OSSL_PARAM_BLD_new();
+ if (bld == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_new"));
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, c->n) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, c->e) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ params = OSSL_PARAM_BLD_to_param(bld);
+ if (params == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_to_param"));
+ }
+
+ pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+ if (pctx == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_new_from_name"));
+ }
+
+ if (EVP_PKEY_fromdata_init(pctx) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_fromdata_init"));
+ }
+
+ if (EVP_PKEY_fromdata(pctx, pkeyp, EVP_PKEY_PUBLIC_KEY, params) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_fromdata"));
+ }
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_CTX_free(pctx);
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(bld);
+ return result;
+}
+
+isc_result_t
+isc_ossl_wrap_load_rsa_secret_from_components(isc_ossl_wrap_rsa_components_t *c,
+ EVP_PKEY **pkeyp) {
+ isc_result_t result;
+ OSSL_PARAM_BLD *bld = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
+ OSSL_PARAM *params = NULL;
+
+ REQUIRE(pkeyp != NULL && *pkeyp == NULL);
+
+ bld = OSSL_PARAM_BLD_new();
+ if (bld == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_new"));
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, c->n) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, c->e) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->d != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, c->d) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->p != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR1, c->p) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->q != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR2, c->q) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->dmp1 != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1,
+ c->dmp1) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->dmq1 != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2,
+ c->dmq1) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ if (c->iqmp != NULL &&
+ OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
+ c->iqmp) != 1)
+ {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_push_BN"));
+ }
+
+ params = OSSL_PARAM_BLD_to_param(bld);
+ if (params == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("OSSL_PARAM_BLD_to_param"));
+ }
+
+ pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+ if (pctx == NULL) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_CTX_new_from_name"));
+ }
+
+ if (EVP_PKEY_fromdata_init(pctx) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_fromdata_init"));
+ }
+
+ if (EVP_PKEY_fromdata(pctx, pkeyp, EVP_PKEY_KEYPAIR, params) != 1) {
+ CLEANUP(OSSL_WRAP_ERROR("EVP_PKEY_fromdata"));
+ }
+
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ EVP_PKEY_CTX_free(pctx);
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(bld);
+ return result;
+}