/*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2022 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
EVP_PKEY_METHOD *pmeth;
pmeth = OPENSSL_zalloc(sizeof(*pmeth));
- if (pmeth == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ if (pmeth == NULL)
return NULL;
- }
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
* fetching a provider implementation.
*/
if (e == NULL && app_pmeth == NULL && keytype != NULL) {
- keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
+ /*
+ * If |pkey| is given and is provided, we take a reference to its
+ * keymgmt. Otherwise, we fetch one for the keytype we got. This
+ * is to ensure that operation init functions can access what they
+ * need through this single pointer.
+ */
+ if (pkey != NULL && pkey->keymgmt != NULL) {
+ if (!EVP_KEYMGMT_up_ref(pkey->keymgmt))
+ ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+ else
+ keymgmt = pkey->keymgmt;
+ } else {
+ keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
+ }
if (keymgmt == NULL)
return NULL; /* EVP_KEYMGMT_fetch() recorded an error */
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM);
} else {
ret = OPENSSL_zalloc(sizeof(*ret));
- if (ret == NULL)
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
}
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
}
# endif
rctx = OPENSSL_zalloc(sizeof(*rctx));
- if (rctx == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ if (rctx == NULL)
return NULL;
- }
if (pctx->pkey != NULL)
EVP_PKEY_up_ref(pctx->pkey);
if (pctx->op.kex.algctx != NULL) {
if (!ossl_assert(pctx->op.kex.exchange != NULL))
goto err;
- rctx->op.kex.algctx
- = pctx->op.kex.exchange->dupctx(pctx->op.kex.algctx);
+
+ if (pctx->op.kex.exchange->dupctx != NULL)
+ rctx->op.kex.algctx
+ = pctx->op.kex.exchange->dupctx(pctx->op.kex.algctx);
+
if (rctx->op.kex.algctx == NULL) {
EVP_KEYEXCH_free(rctx->op.kex.exchange);
+ rctx->op.kex.exchange = NULL;
goto err;
}
return rctx;
if (pctx->op.sig.algctx != NULL) {
if (!ossl_assert(pctx->op.sig.signature != NULL))
goto err;
- rctx->op.sig.algctx
- = pctx->op.sig.signature->dupctx(pctx->op.sig.algctx);
+
+ if (pctx->op.sig.signature->dupctx != NULL)
+ rctx->op.sig.algctx
+ = pctx->op.sig.signature->dupctx(pctx->op.sig.algctx);
+
if (rctx->op.sig.algctx == NULL) {
EVP_SIGNATURE_free(rctx->op.sig.signature);
+ rctx->op.sig.signature = NULL;
goto err;
}
return rctx;
if (pctx->op.ciph.algctx != NULL) {
if (!ossl_assert(pctx->op.ciph.cipher != NULL))
goto err;
- rctx->op.ciph.algctx
- = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.algctx);
+
+ if (pctx->op.ciph.cipher->dupctx != NULL)
+ rctx->op.ciph.algctx
+ = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.algctx);
+
if (rctx->op.ciph.algctx == NULL) {
EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher);
+ rctx->op.ciph.cipher = NULL;
goto err;
}
return rctx;
if (pctx->op.encap.algctx != NULL) {
if (!ossl_assert(pctx->op.encap.kem != NULL))
goto err;
- rctx->op.encap.algctx
- = pctx->op.encap.kem->dupctx(pctx->op.encap.algctx);
+
+ if (pctx->op.encap.kem->dupctx != NULL)
+ rctx->op.encap.algctx
+ = pctx->op.encap.kem->dupctx(pctx->op.encap.algctx);
+
if (rctx->op.encap.algctx == NULL) {
EVP_KEM_free(rctx->op.encap.kem);
+ rctx->op.encap.kem = NULL;
goto err;
}
return rctx;
{
if (app_pkey_methods == NULL) {
app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
- if (app_pkey_methods == NULL){
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ if (app_pkey_methods == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
return 0;
}
}
if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB);
return 0;
}
sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
for (p = params; p->key != NULL; p++) {
/* Check the ctx actually understands this parameter */
- if (OSSL_PARAM_locate_const(settable, p->key) == NULL )
+ if (OSSL_PARAM_locate_const(settable, p->key) == NULL)
return -2;
}
}
const OSSL_PARAM *gettable = EVP_PKEY_CTX_gettable_params(ctx);
const OSSL_PARAM *p;
- for (p = params; p->key != NULL; p++ ) {
+ for (p = params; p->key != NULL; p++) {
/* Check the ctx actually understands this parameter */
- if (OSSL_PARAM_locate_const(gettable, p->key) == NULL )
+ if (OSSL_PARAM_locate_const(gettable, p->key) == NULL)
return -2;
}
}
evp_pkey_ctx_free_cached_data(ctx, cmd, name);
if (name != NULL) {
ctx->cached_parameters.dist_id_name = OPENSSL_strdup(name);
- if (ctx->cached_parameters.dist_id_name == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ if (ctx->cached_parameters.dist_id_name == NULL)
return 0;
- }
}
if (data_len > 0) {
ctx->cached_parameters.dist_id = OPENSSL_memdup(data, data_len);
- if (ctx->cached_parameters.dist_id == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ if (ctx->cached_parameters.dist_id == NULL)
return 0;
- }
}
ctx->cached_parameters.dist_id_set = 1;
ctx->cached_parameters.dist_id_len = data_len;
return ctx->libctx;
}
-const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx)
+const char *EVP_PKEY_CTX_get0_propq(const EVP_PKEY_CTX *ctx)
{
return ctx->propquery;
}
+const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx)
+{
+ if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
+ if (ctx->op.sig.signature != NULL)
+ return EVP_SIGNATURE_get0_provider(ctx->op.sig.signature);
+ } else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
+ if (ctx->op.kex.exchange != NULL)
+ return EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange);
+ } else if (EVP_PKEY_CTX_IS_KEM_OP(ctx)) {
+ if (ctx->op.encap.kem != NULL)
+ return EVP_KEM_get0_provider(ctx->op.encap.kem);
+ } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
+ if (ctx->op.ciph.cipher != NULL)
+ return EVP_ASYM_CIPHER_get0_provider(ctx->op.ciph.cipher);
+ } else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+ if (ctx->keymgmt != NULL)
+ return EVP_KEYMGMT_get0_provider(ctx->keymgmt);
+ }
+
+ return NULL;
+}
+
/* Utility functions to send a string of hex string to a ctrl */
int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
*pctrl_str = pmeth->ctrl_str;
}
-void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth,
+void EVP_PKEY_meth_get_digestsign(const EVP_PKEY_METHOD *pmeth,
int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen))
{
*digestsign = pmeth->digestsign;
}
-void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth,
+void EVP_PKEY_meth_get_digestverify(const EVP_PKEY_METHOD *pmeth,
int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs,
size_t tbslen))
*pcheck = pmeth->param_check;
}
-void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
+void EVP_PKEY_meth_get_digest_custom(const EVP_PKEY_METHOD *pmeth,
int (**pdigest_custom) (EVP_PKEY_CTX *ctx,
EVP_MD_CTX *mctx))
{