Compare commits
28 commits
master
...
feature/me
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42f8690c2c | ||
|
|
d1cae65c4a | ||
|
|
fd185f596f | ||
|
|
79439ccba0 | ||
|
|
b9970647df | ||
|
|
a21cbce238 | ||
|
|
19056245f5 | ||
|
|
6441e227f6 | ||
|
|
f457bd93c5 | ||
|
|
302edc39e0 | ||
|
|
9200ab5c15 | ||
|
|
ccd9445247 | ||
|
|
e77def380a | ||
|
|
37bb988a0e | ||
|
|
aa70893e25 | ||
|
|
901e728fda | ||
|
|
ca5f693271 | ||
|
|
de60bf9091 | ||
|
|
9d4f44f3e7 | ||
|
|
5844109177 | ||
|
|
8a17b8ee9e | ||
|
|
f174d994ef | ||
|
|
d65db7f0e1 | ||
|
|
ba4fce934a | ||
|
|
cb97cc61e0 | ||
|
|
8220d3664d | ||
|
|
cbb3db48ac | ||
|
|
f5877a9d04 |
27 changed files with 2798 additions and 178 deletions
|
|
@ -461,6 +461,19 @@ static int set_default_context(OSSL_LIB_CTX *defctx)
|
|||
}
|
||||
#endif
|
||||
|
||||
int OSSL_LIB_CTX_freeze(OSSL_LIB_CTX *ctx, const char *propq)
|
||||
{
|
||||
OSSL_METHOD_STORE *store;
|
||||
|
||||
store = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX);
|
||||
if (store == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ossl_method_store_freeze_cache(store, propq);
|
||||
}
|
||||
|
||||
OSSL_LIB_CTX *OSSL_LIB_CTX_new(void)
|
||||
{
|
||||
OSSL_LIB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||
|
|
|
|||
|
|
@ -162,14 +162,16 @@ void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id,
|
|||
ossl_method_construct_postcondition,
|
||||
&cbdata);
|
||||
|
||||
/* If there is a temporary store, try there first */
|
||||
if (cbdata.store != NULL)
|
||||
method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
|
||||
mcm_data);
|
||||
if (mcm->get != NULL) {
|
||||
/* If there is a temporary store, try there first */
|
||||
if (cbdata.store != NULL)
|
||||
method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
|
||||
mcm_data);
|
||||
|
||||
/* If no method was found yet, try the global store */
|
||||
if (method == NULL)
|
||||
method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
|
||||
/* If no method was found yet, try the global store */
|
||||
if (method == NULL)
|
||||
method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ static int put_decoder_in_store(void *store, void *method,
|
|||
|
||||
return ossl_method_store_add(store, prov, id, propdef, method,
|
||||
ossl_decoder_up_ref,
|
||||
ossl_decoder_free);
|
||||
ossl_decoder_free, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Create and populate a decoder method */
|
||||
|
|
@ -396,7 +396,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata,
|
|||
id = ossl_namemap_name2num(namemap, name);
|
||||
if (id != 0)
|
||||
ossl_method_store_cache_set(store, prov, id, propq, method,
|
||||
up_ref_decoder, free_decoder);
|
||||
up_ref_decoder, free_decoder, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ static int put_encoder_in_store(void *store, void *method,
|
|||
|
||||
return ossl_method_store_add(store, prov, id, propdef, method,
|
||||
ossl_encoder_up_ref,
|
||||
ossl_encoder_free);
|
||||
ossl_encoder_free, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Create and populate a encoder method */
|
||||
|
|
@ -401,7 +401,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata,
|
|||
if (id == 0)
|
||||
id = ossl_namemap_name2num(namemap, name);
|
||||
ossl_method_store_cache_set(store, prov, id, propq, method,
|
||||
up_ref_encoder, free_encoder);
|
||||
up_ref_encoder, free_encoder, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -17,6 +17,14 @@
|
|||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
static void evp_asym_cipher_free_int(EVP_ASYM_CIPHER *cipher)
|
||||
{
|
||||
OPENSSL_free(cipher->type_name);
|
||||
ossl_provider_free(cipher->prov);
|
||||
CRYPTO_FREE_REF(&cipher->refcnt);
|
||||
OPENSSL_free(cipher);
|
||||
}
|
||||
|
||||
static void evp_asym_cipher_free(void *data)
|
||||
{
|
||||
EVP_ASYM_CIPHER_free(data);
|
||||
|
|
@ -363,6 +371,47 @@ static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
|
|||
return cipher;
|
||||
}
|
||||
|
||||
static void *evp_asym_cipher_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_ASYM_CIPHER *in = vin;
|
||||
EVP_ASYM_CIPHER *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_asym_cipher_frozen_free(void *vin)
|
||||
{
|
||||
EVP_ASYM_CIPHER *rand = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (rand == NULL || rand->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&rand->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_asym_cipher_free_int(rand);
|
||||
}
|
||||
|
||||
static void *evp_asym_cipher_from_algorithm(int name_id,
|
||||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov)
|
||||
|
|
@ -484,22 +533,20 @@ void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (cipher == NULL)
|
||||
if (cipher == NULL || cipher->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
CRYPTO_DOWN_REF(&cipher->refcnt, &i);
|
||||
if (i > 0)
|
||||
return;
|
||||
OPENSSL_free(cipher->type_name);
|
||||
ossl_provider_free(cipher->prov);
|
||||
CRYPTO_FREE_REF(&cipher->refcnt);
|
||||
OPENSSL_free(cipher);
|
||||
evp_asym_cipher_free_int(cipher);
|
||||
}
|
||||
|
||||
int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&cipher->refcnt, &ref);
|
||||
if (cipher->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&cipher->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -511,10 +558,26 @@ OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher)
|
|||
EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties,
|
||||
return evp_generic_fetch(ctx,
|
||||
OSSL_OP_ASYM_CIPHER,
|
||||
algorithm,
|
||||
properties,
|
||||
evp_asym_cipher_from_algorithm,
|
||||
evp_asym_cipher_up_ref,
|
||||
evp_asym_cipher_free);
|
||||
evp_asym_cipher_free,
|
||||
evp_asym_cipher_dup_frozen,
|
||||
evp_asym_cipher_frozen_free);
|
||||
}
|
||||
|
||||
int evp_asym_cipher_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx,
|
||||
OSSL_OP_ASYM_CIPHER,
|
||||
evp_asym_cipher_from_algorithm,
|
||||
evp_asym_cipher_up_ref,
|
||||
evp_asym_cipher_free,
|
||||
evp_asym_cipher_dup_frozen,
|
||||
evp_asym_cipher_frozen_free);
|
||||
}
|
||||
|
||||
EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
|
||||
|
|
@ -525,7 +588,9 @@ EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_asym_cipher_from_algorithm,
|
||||
evp_asym_cipher_up_ref,
|
||||
evp_asym_cipher_free);
|
||||
evp_asym_cipher_free,
|
||||
evp_asym_cipher_dup_frozen,
|
||||
evp_asym_cipher_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "internal/common.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
#include "openssl/crypto.h"
|
||||
|
||||
static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
|
||||
{
|
||||
|
|
@ -1075,11 +1076,66 @@ static void evp_md_free(void *md)
|
|||
EVP_MD_free(md);
|
||||
}
|
||||
|
||||
static void *evp_md_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_MD *in = vin;
|
||||
EVP_MD *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (!ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return out;
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_md_frozen_free(EVP_MD *md)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (md == NULL || md->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&md->refcnt, &i);
|
||||
if (i > 0)
|
||||
return;
|
||||
evp_md_free_int(md);
|
||||
}
|
||||
|
||||
int evp_md_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
int ret = evp_generic_fetch_all(ctx, OSSL_OP_DIGEST,
|
||||
evp_md_from_algorithm,
|
||||
evp_md_up_ref,
|
||||
evp_md_free,
|
||||
evp_md_dup_frozen,
|
||||
(void (*)(void *))evp_md_frozen_free);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
EVP_MD *md = evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
||||
evp_md_from_algorithm, evp_md_up_ref, evp_md_free);
|
||||
evp_md_from_algorithm,
|
||||
evp_md_up_ref,
|
||||
evp_md_free,
|
||||
evp_md_dup_frozen,
|
||||
(void (*)(void *))evp_md_frozen_free);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
|
@ -1123,7 +1179,9 @@ EVP_MD *evp_digest_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_md_from_algorithm,
|
||||
evp_md_up_ref,
|
||||
evp_md_free);
|
||||
evp_md_free,
|
||||
evp_md_dup_frozen,
|
||||
(void (*)(void *))evp_md_frozen_free);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -1989,14 +1989,69 @@ static void evp_cipher_free(void *cipher)
|
|||
EVP_CIPHER_free(cipher);
|
||||
}
|
||||
|
||||
static void *evp_cipher_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_CIPHER *in = vin;
|
||||
EVP_CIPHER *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (!ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_cipher_frozen_free(void *vin)
|
||||
{
|
||||
EVP_CIPHER *cipher = vin;
|
||||
int i;
|
||||
|
||||
if (cipher == NULL || cipher->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&cipher->refcnt, &i);
|
||||
if (i > 0)
|
||||
return;
|
||||
evp_cipher_free_int(cipher);
|
||||
}
|
||||
|
||||
int evp_cipher_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
int ret = evp_generic_fetch_all(ctx,
|
||||
OSSL_OP_CIPHER,
|
||||
evp_cipher_from_algorithm,
|
||||
evp_cipher_up_ref,
|
||||
evp_cipher_free,
|
||||
evp_cipher_dup_frozen,
|
||||
evp_cipher_frozen_free);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
EVP_CIPHER *cipher = evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
|
||||
evp_cipher_from_algorithm, evp_cipher_up_ref,
|
||||
evp_cipher_free);
|
||||
|
||||
return cipher;
|
||||
return evp_generic_fetch(ctx, OSSL_OP_CIPHER,
|
||||
algorithm, properties,
|
||||
evp_cipher_from_algorithm,
|
||||
evp_cipher_up_ref,
|
||||
evp_cipher_free,
|
||||
evp_cipher_dup_frozen,
|
||||
evp_cipher_frozen_free);
|
||||
}
|
||||
|
||||
EVP_CIPHER *evp_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
|
||||
|
|
@ -2007,7 +2062,9 @@ EVP_CIPHER *evp_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_cipher_from_algorithm,
|
||||
evp_cipher_up_ref,
|
||||
evp_cipher_free);
|
||||
evp_cipher_free,
|
||||
evp_cipher_dup_frozen,
|
||||
evp_cipher_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_CIPHER_can_pipeline(const EVP_CIPHER *cipher, int enc)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ struct evp_method_data_st {
|
|||
OSSL_PROVIDER *);
|
||||
int (*refcnt_up_method)(void *method);
|
||||
void (*destruct_method)(void *method);
|
||||
void *(*dup_method)(void *method);
|
||||
void (*free_frozen_method)(void *method);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -123,6 +125,37 @@ static uint32_t evp_method_id(int name_id, unsigned int operation_id)
|
|||
| (operation_id & METHOD_ID_OPERATION_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* Reverse of evp_method_id().
|
||||
*
|
||||
* Returns 1 on success and fills in |*name_id| and |*operation_id|.
|
||||
* Returns 0 on invalid input.
|
||||
*/
|
||||
int evp_method_id2name_id_op_id(uint32_t meth_id, int *name_id,
|
||||
unsigned int *operation_id)
|
||||
{
|
||||
int n;
|
||||
unsigned int op;
|
||||
|
||||
/* Top bit must be zero (see evp_method_id() comment) */
|
||||
if ((meth_id & 0x80000000u) != 0)
|
||||
return 0;
|
||||
|
||||
op = (unsigned int)(meth_id & METHOD_ID_OPERATION_MASK);
|
||||
n = (int)((meth_id & METHOD_ID_NAME_MASK) >> METHOD_ID_NAME_OFFSET);
|
||||
|
||||
/* Sanity checks to match evp_method_id() requirements */
|
||||
if (op == 0 || op > METHOD_ID_OPERATION_MAX || n > METHOD_ID_NAME_MAX)
|
||||
return 0;
|
||||
|
||||
if (operation_id != NULL)
|
||||
*operation_id = op;
|
||||
if (name_id != NULL)
|
||||
*name_id = n;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *get_evp_method_from_store(void *store, const OSSL_PROVIDER **prov,
|
||||
void *data)
|
||||
{
|
||||
|
|
@ -200,7 +233,9 @@ static int put_evp_method_in_store(void *store, void *method,
|
|||
store, names, methdata->operation_id, meth_id, propdef ? propdef : "<null>");
|
||||
return ossl_method_store_add(store, prov, meth_id, propdef, method,
|
||||
methdata->refcnt_up_method,
|
||||
methdata->destruct_method);
|
||||
methdata->destruct_method,
|
||||
methdata->dup_method,
|
||||
methdata->free_frozen_method);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -247,6 +282,38 @@ static void destruct_evp_method(void *method, void *data)
|
|||
methdata->destruct_method(method);
|
||||
}
|
||||
|
||||
static int
|
||||
inner_evp_generic_fetch_all(struct evp_method_data_st *methdata,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
OSSL_METHOD_STORE *store = get_evp_method_store(methdata->libctx);
|
||||
|
||||
if (store == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
|
||||
get_tmp_evp_method_store,
|
||||
reserve_evp_method_store,
|
||||
unreserve_evp_method_store,
|
||||
NULL,
|
||||
put_evp_method_in_store,
|
||||
construct_evp_method,
|
||||
destruct_evp_method
|
||||
};
|
||||
|
||||
ossl_method_construct(methdata->libctx, methdata->operation_id,
|
||||
&prov, 0 /* !force_cache */,
|
||||
&mcm, methdata);
|
||||
if (methdata->flag_construct_error_occurred != 0) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|
||||
OSSL_PROVIDER *prov, int operation_id,
|
||||
|
|
@ -255,7 +322,9 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|
|||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *))
|
||||
{
|
||||
OSSL_METHOD_STORE *store = get_evp_method_store(methdata->libctx);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
|
||||
|
|
@ -288,6 +357,15 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (ossl_method_store_is_frozen(store)) {
|
||||
const char *store_propq = ossl_method_store_frozen_propq(store);
|
||||
|
||||
if (*propq == '\0' || strcmp(store_propq, propq) == 0) {
|
||||
ossl_frozen_method_store_cache_get(store, name, propq, operation_id, &method);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we haven't received a name id yet, try to get one for the name */
|
||||
name_id = name != NULL ? ossl_namemap_name2num(namemap, name) : 0;
|
||||
|
||||
|
|
@ -329,6 +407,8 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|
|||
methdata->method_from_algorithm = new_method;
|
||||
methdata->refcnt_up_method = up_ref_method;
|
||||
methdata->destruct_method = free_method;
|
||||
methdata->free_frozen_method = dup_free_method;
|
||||
methdata->dup_method = dup_method;
|
||||
methdata->flag_construct_error_occurred = 0;
|
||||
if ((method = ossl_method_construct(methdata->libctx, operation_id,
|
||||
&prov, 0 /* !force_cache */,
|
||||
|
|
@ -357,7 +437,10 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|
|||
meth_id = evp_method_id(name_id, operation_id);
|
||||
if (meth_id != 0)
|
||||
ossl_method_store_cache_set(store, prov, meth_id, propq,
|
||||
method, up_ref_method, free_method);
|
||||
method,
|
||||
up_ref_method,
|
||||
free_method,
|
||||
dup_method, dup_free_method);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +477,9 @@ void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
|
|||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *))
|
||||
{
|
||||
struct evp_method_data_st methdata;
|
||||
void *method;
|
||||
|
|
@ -403,11 +488,41 @@ void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
|
|||
methdata.tmp_store = NULL;
|
||||
method = inner_evp_generic_fetch(&methdata, NULL, operation_id,
|
||||
name, properties,
|
||||
new_method, up_ref_method, free_method);
|
||||
new_method,
|
||||
up_ref_method,
|
||||
free_method,
|
||||
dup_method,
|
||||
dup_free_method);
|
||||
dealloc_tmp_evp_method_store(methdata.tmp_store);
|
||||
return method;
|
||||
}
|
||||
|
||||
int evp_generic_fetch_all(OSSL_LIB_CTX *libctx, int operation_id,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *))
|
||||
{
|
||||
int ret;
|
||||
struct evp_method_data_st methdata = {
|
||||
.libctx = libctx,
|
||||
.name_id = -1,
|
||||
.method_from_algorithm = new_method,
|
||||
.refcnt_up_method = up_ref_method,
|
||||
.destruct_method = free_method,
|
||||
.dup_method = dup_method,
|
||||
.free_frozen_method = dup_free_method,
|
||||
.operation_id = operation_id,
|
||||
};
|
||||
|
||||
ret = inner_evp_generic_fetch_all(&methdata, NULL);
|
||||
dealloc_tmp_evp_method_store(methdata.tmp_store);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* evp_generic_fetch_from_prov() is special, and only returns methods from
|
||||
* the given provider.
|
||||
|
|
@ -420,7 +535,9 @@ void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
|
|||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *))
|
||||
{
|
||||
struct evp_method_data_st methdata;
|
||||
void *method;
|
||||
|
|
@ -429,7 +546,11 @@ void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
|
|||
methdata.tmp_store = NULL;
|
||||
method = inner_evp_generic_fetch(&methdata, prov, operation_id,
|
||||
name, properties,
|
||||
new_method, up_ref_method, free_method);
|
||||
new_method,
|
||||
up_ref_method,
|
||||
free_method,
|
||||
dup_method,
|
||||
dup_free_method);
|
||||
dealloc_tmp_evp_method_store(methdata.tmp_store);
|
||||
return method;
|
||||
}
|
||||
|
|
@ -642,7 +763,7 @@ void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id,
|
|||
methdata.libctx = libctx;
|
||||
methdata.tmp_store = NULL;
|
||||
(void)inner_evp_generic_fetch(&methdata, NULL, operation_id, NULL, NULL,
|
||||
new_method, up_ref_method, free_method);
|
||||
new_method, up_ref_method, free_method, NULL, NULL);
|
||||
|
||||
data.operation_id = operation_id;
|
||||
data.user_fn = user_fn;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ struct evp_keymgmt_st {
|
|||
const char *description;
|
||||
OSSL_PROVIDER *prov;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
int origin;
|
||||
|
||||
/* Constructor(s), destructor, information */
|
||||
OSSL_FUNC_keymgmt_new_fn *new;
|
||||
|
|
@ -136,6 +137,7 @@ struct evp_keymgmt_st {
|
|||
|
||||
struct evp_keyexch_st {
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
OSSL_PROVIDER *prov;
|
||||
|
|
@ -197,8 +199,39 @@ struct evp_signature_st {
|
|||
OSSL_FUNC_signature_query_key_types_fn *query_key_types;
|
||||
} /* EVP_SIGNATURE */;
|
||||
|
||||
struct evp_rand_st {
|
||||
OSSL_PROVIDER *prov;
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
|
||||
const OSSL_DISPATCH *dispatch;
|
||||
OSSL_FUNC_rand_newctx_fn *newctx;
|
||||
OSSL_FUNC_rand_freectx_fn *freectx;
|
||||
OSSL_FUNC_rand_instantiate_fn *instantiate;
|
||||
OSSL_FUNC_rand_uninstantiate_fn *uninstantiate;
|
||||
OSSL_FUNC_rand_generate_fn *generate;
|
||||
OSSL_FUNC_rand_reseed_fn *reseed;
|
||||
OSSL_FUNC_rand_nonce_fn *nonce;
|
||||
OSSL_FUNC_rand_enable_locking_fn *enable_locking;
|
||||
OSSL_FUNC_rand_lock_fn *lock;
|
||||
OSSL_FUNC_rand_unlock_fn *unlock;
|
||||
OSSL_FUNC_rand_gettable_params_fn *gettable_params;
|
||||
OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params;
|
||||
OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params;
|
||||
OSSL_FUNC_rand_get_params_fn *get_params;
|
||||
OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params;
|
||||
OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params;
|
||||
OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization;
|
||||
OSSL_FUNC_rand_get_seed_fn *get_seed;
|
||||
OSSL_FUNC_rand_clear_seed_fn *clear_seed;
|
||||
} /* EVP_RAND */;
|
||||
|
||||
struct evp_skeymgmt_st {
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
OSSL_PROVIDER *prov;
|
||||
|
|
@ -222,6 +255,7 @@ struct evp_skeymgmt_st {
|
|||
|
||||
struct evp_asym_cipher_st {
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
OSSL_PROVIDER *prov;
|
||||
|
|
@ -242,6 +276,7 @@ struct evp_asym_cipher_st {
|
|||
|
||||
struct evp_kem_st {
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
OSSL_PROVIDER *prov;
|
||||
|
|
@ -301,14 +336,26 @@ void *evp_generic_fetch(OSSL_LIB_CTX *ctx, int operation_id,
|
|||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *));
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *));
|
||||
int evp_generic_fetch_all(OSSL_LIB_CTX *ctx, int operation_id,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *));
|
||||
void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *));
|
||||
void (*free_method)(void *),
|
||||
void *(*dup_method)(void *),
|
||||
void (*dup_free_method)(void *));
|
||||
void evp_generic_do_all_prefetched(OSSL_LIB_CTX *libctx, int operation_id,
|
||||
void (*user_fn)(void *method, void *arg),
|
||||
void *user_arg);
|
||||
|
|
@ -410,3 +457,15 @@ int evp_names_do_all(OSSL_PROVIDER *prov, int number,
|
|||
void (*fn)(const char *name, void *data),
|
||||
void *data);
|
||||
int evp_cipher_cache_constants(EVP_CIPHER *cipher);
|
||||
int evp_method_id2name_id_op_id(uint32_t meth_id, int *name_id,
|
||||
unsigned int *operation_id);
|
||||
int evp_md_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_cipher_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_kdf_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_rand_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_mac_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_keymgmt_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_kem_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_asym_cipher_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_keyexch_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
int evp_skeymgmt_fetch_all(OSSL_LIB_CTX *ctx);
|
||||
|
|
|
|||
|
|
@ -21,41 +21,20 @@
|
|||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
struct evp_rand_st {
|
||||
OSSL_PROVIDER *prov;
|
||||
int name_id;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
|
||||
const OSSL_DISPATCH *dispatch;
|
||||
OSSL_FUNC_rand_newctx_fn *newctx;
|
||||
OSSL_FUNC_rand_freectx_fn *freectx;
|
||||
OSSL_FUNC_rand_instantiate_fn *instantiate;
|
||||
OSSL_FUNC_rand_uninstantiate_fn *uninstantiate;
|
||||
OSSL_FUNC_rand_generate_fn *generate;
|
||||
OSSL_FUNC_rand_reseed_fn *reseed;
|
||||
OSSL_FUNC_rand_nonce_fn *nonce;
|
||||
OSSL_FUNC_rand_enable_locking_fn *enable_locking;
|
||||
OSSL_FUNC_rand_lock_fn *lock;
|
||||
OSSL_FUNC_rand_unlock_fn *unlock;
|
||||
OSSL_FUNC_rand_gettable_params_fn *gettable_params;
|
||||
OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params;
|
||||
OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params;
|
||||
OSSL_FUNC_rand_get_params_fn *get_params;
|
||||
OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params;
|
||||
OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params;
|
||||
OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization;
|
||||
OSSL_FUNC_rand_get_seed_fn *get_seed;
|
||||
OSSL_FUNC_rand_clear_seed_fn *clear_seed;
|
||||
} /* EVP_RAND */;
|
||||
static void evp_rand_free_int(EVP_RAND *rand)
|
||||
{
|
||||
OPENSSL_free(rand->type_name);
|
||||
ossl_provider_free(rand->prov);
|
||||
CRYPTO_FREE_REF(&rand->refcnt);
|
||||
OPENSSL_free(rand);
|
||||
}
|
||||
|
||||
static int evp_rand_up_ref(void *vrand)
|
||||
{
|
||||
EVP_RAND *rand = (EVP_RAND *)vrand;
|
||||
int ref = 0;
|
||||
|
||||
if (rand != NULL)
|
||||
if (rand != NULL && rand->origin == EVP_ORIG_DYNAMIC)
|
||||
return CRYPTO_UP_REF(&rand->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -65,15 +44,12 @@ static void evp_rand_free(void *vrand)
|
|||
EVP_RAND *rand = (EVP_RAND *)vrand;
|
||||
int ref = 0;
|
||||
|
||||
if (rand == NULL)
|
||||
if (rand == NULL || rand->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
CRYPTO_DOWN_REF(&rand->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
OPENSSL_free(rand->type_name);
|
||||
ossl_provider_free(rand->prov);
|
||||
CRYPTO_FREE_REF(&rand->refcnt);
|
||||
OPENSSL_free(rand);
|
||||
evp_rand_free_int(rand);
|
||||
}
|
||||
|
||||
static void *evp_rand_new(void)
|
||||
|
|
@ -90,6 +66,47 @@ static void *evp_rand_new(void)
|
|||
return rand;
|
||||
}
|
||||
|
||||
static void *evp_rand_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_RAND *in = vin;
|
||||
EVP_RAND *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_rand_frozen_free(void *vin)
|
||||
{
|
||||
EVP_RAND *rand = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (rand == NULL || rand->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&rand->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_rand_free_int(rand);
|
||||
}
|
||||
|
||||
/* Enable locking of the underlying DRBG/RAND if available */
|
||||
int EVP_RAND_enable_locking(EVP_RAND_CTX *rand)
|
||||
{
|
||||
|
|
@ -282,9 +299,23 @@ static void *evp_rand_from_algorithm(int name_id,
|
|||
EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
|
||||
evp_rand_from_algorithm, evp_rand_up_ref,
|
||||
evp_rand_free);
|
||||
return evp_generic_fetch(libctx, OSSL_OP_RAND,
|
||||
algorithm, properties,
|
||||
evp_rand_from_algorithm,
|
||||
evp_rand_up_ref,
|
||||
evp_rand_free,
|
||||
evp_rand_dup_frozen,
|
||||
evp_rand_frozen_free);
|
||||
}
|
||||
|
||||
int evp_rand_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx, OSSL_OP_RAND,
|
||||
evp_rand_from_algorithm,
|
||||
evp_rand_up_ref,
|
||||
evp_rand_free,
|
||||
evp_rand_dup_frozen,
|
||||
evp_rand_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_RAND_up_ref(EVP_RAND *rand)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@
|
|||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
static void evp_keyexch_free_int(EVP_KEYEXCH *exchange)
|
||||
{
|
||||
OPENSSL_free(exchange->type_name);
|
||||
ossl_provider_free(exchange->prov);
|
||||
CRYPTO_FREE_REF(&exchange->refcnt);
|
||||
OPENSSL_free(exchange);
|
||||
}
|
||||
|
||||
static void evp_keyexch_free(void *data)
|
||||
{
|
||||
EVP_KEYEXCH_free(data);
|
||||
|
|
@ -47,6 +55,47 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
|
|||
return exchange;
|
||||
}
|
||||
|
||||
static void *evp_keyexch_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_KEYEXCH *in = vin;
|
||||
EVP_KEYEXCH *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_keyexch_frozen_free(void *vin)
|
||||
{
|
||||
EVP_KEYEXCH *rand = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (rand == NULL || rand->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&rand->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_keyexch_free_int(rand);
|
||||
}
|
||||
|
||||
static void *evp_keyexch_from_algorithm(int name_id,
|
||||
const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov)
|
||||
|
|
@ -162,22 +211,20 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (exchange == NULL)
|
||||
if (exchange == NULL || exchange->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
CRYPTO_DOWN_REF(&exchange->refcnt, &i);
|
||||
if (i > 0)
|
||||
return;
|
||||
OPENSSL_free(exchange->type_name);
|
||||
ossl_provider_free(exchange->prov);
|
||||
CRYPTO_FREE_REF(&exchange->refcnt);
|
||||
OPENSSL_free(exchange);
|
||||
evp_keyexch_free_int(exchange);
|
||||
}
|
||||
|
||||
int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&exchange->refcnt, &ref);
|
||||
if (exchange->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&exchange->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -189,10 +236,26 @@ OSSL_PROVIDER *EVP_KEYEXCH_get0_provider(const EVP_KEYEXCH *exchange)
|
|||
EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
|
||||
return evp_generic_fetch(ctx,
|
||||
OSSL_OP_KEYEXCH,
|
||||
algorithm,
|
||||
properties,
|
||||
evp_keyexch_from_algorithm,
|
||||
evp_keyexch_up_ref,
|
||||
evp_keyexch_free);
|
||||
evp_keyexch_free,
|
||||
evp_keyexch_dup_frozen,
|
||||
evp_keyexch_frozen_free);
|
||||
}
|
||||
|
||||
int evp_keyexch_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx,
|
||||
OSSL_OP_KEYEXCH,
|
||||
evp_keyexch_from_algorithm,
|
||||
evp_keyexch_up_ref,
|
||||
evp_keyexch_free,
|
||||
evp_keyexch_dup_frozen,
|
||||
evp_keyexch_frozen_free);
|
||||
}
|
||||
|
||||
EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov,
|
||||
|
|
@ -203,7 +266,9 @@ EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_keyexch_from_algorithm,
|
||||
evp_keyexch_up_ref,
|
||||
evp_keyexch_free);
|
||||
evp_keyexch_free,
|
||||
evp_keyexch_dup_frozen,
|
||||
evp_keyexch_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
|
|
|
|||
|
|
@ -12,17 +12,27 @@
|
|||
#include <openssl/core.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <string.h>
|
||||
#include "internal/provider.h"
|
||||
#include "internal/core.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
static void evp_kdf_free_int(EVP_KDF *kdf)
|
||||
{
|
||||
OPENSSL_free(kdf->type_name);
|
||||
ossl_provider_free(kdf->prov);
|
||||
CRYPTO_FREE_REF(&kdf->refcnt);
|
||||
OPENSSL_free(kdf);
|
||||
}
|
||||
|
||||
static int evp_kdf_up_ref(void *vkdf)
|
||||
{
|
||||
EVP_KDF *kdf = (EVP_KDF *)vkdf;
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&kdf->refcnt, &ref);
|
||||
if (kdf->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&kdf->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -31,16 +41,52 @@ static void evp_kdf_free(void *vkdf)
|
|||
EVP_KDF *kdf = (EVP_KDF *)vkdf;
|
||||
int ref = 0;
|
||||
|
||||
if (kdf == NULL)
|
||||
if (kdf == NULL || kdf->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&kdf->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
OPENSSL_free(kdf->type_name);
|
||||
ossl_provider_free(kdf->prov);
|
||||
CRYPTO_FREE_REF(&kdf->refcnt);
|
||||
OPENSSL_free(kdf);
|
||||
evp_kdf_free_int(kdf);
|
||||
}
|
||||
|
||||
static void *evp_kdf_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_KDF *in = vin;
|
||||
EVP_KDF *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_kdf_frozen_free(EVP_KDF *kdf)
|
||||
{
|
||||
int ref;
|
||||
|
||||
if (kdf == NULL || kdf->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&kdf->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_kdf_free_int(kdf);
|
||||
}
|
||||
|
||||
static void *evp_kdf_new(void)
|
||||
|
|
@ -171,7 +217,18 @@ EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
|
|||
{
|
||||
return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties,
|
||||
evp_kdf_from_algorithm, evp_kdf_up_ref,
|
||||
evp_kdf_free);
|
||||
evp_kdf_free, evp_kdf_dup_frozen,
|
||||
(void (*)(void *))evp_kdf_frozen_free);
|
||||
}
|
||||
|
||||
int evp_kdf_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx, OSSL_OP_KDF,
|
||||
evp_kdf_from_algorithm,
|
||||
evp_kdf_up_ref,
|
||||
evp_kdf_free,
|
||||
evp_kdf_dup_frozen,
|
||||
(void (*)(void *))evp_kdf_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_KDF_up_ref(EVP_KDF *kdf)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
|
@ -22,11 +23,60 @@ static void evp_kem_free(void *data)
|
|||
EVP_KEM_free(data);
|
||||
}
|
||||
|
||||
static void evp_kem_free_int(EVP_KEM *kem)
|
||||
{
|
||||
OPENSSL_free(kem->type_name);
|
||||
ossl_provider_free(kem->prov);
|
||||
CRYPTO_FREE_REF(&kem->refcnt);
|
||||
OPENSSL_free(kem);
|
||||
}
|
||||
|
||||
static int evp_kem_up_ref(void *data)
|
||||
{
|
||||
return EVP_KEM_up_ref(data);
|
||||
}
|
||||
|
||||
static void *evp_kem_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_KEM *in = vin;
|
||||
EVP_KEM *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov != NULL && !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_kem_frozen_free(void *vin)
|
||||
{
|
||||
EVP_KEM *kem = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (kem == NULL || kem->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&kem->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_kem_free_int(kem);
|
||||
}
|
||||
|
||||
static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation,
|
||||
const OSSL_PARAM params[], EVP_PKEY *authkey)
|
||||
{
|
||||
|
|
@ -432,23 +482,21 @@ void EVP_KEM_free(EVP_KEM *kem)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (kem == NULL)
|
||||
if (kem == NULL || kem->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&kem->refcnt, &i);
|
||||
if (i > 0)
|
||||
return;
|
||||
OPENSSL_free(kem->type_name);
|
||||
ossl_provider_free(kem->prov);
|
||||
CRYPTO_FREE_REF(&kem->refcnt);
|
||||
OPENSSL_free(kem);
|
||||
evp_kem_free_int(kem);
|
||||
}
|
||||
|
||||
int EVP_KEM_up_ref(EVP_KEM *kem)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&kem->refcnt, &ref);
|
||||
if (kem->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&kem->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -463,7 +511,9 @@ EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
|||
return evp_generic_fetch(ctx, OSSL_OP_KEM, algorithm, properties,
|
||||
evp_kem_from_algorithm,
|
||||
evp_kem_up_ref,
|
||||
evp_kem_free);
|
||||
evp_kem_free,
|
||||
evp_kem_dup_frozen,
|
||||
evp_kem_frozen_free);
|
||||
}
|
||||
|
||||
EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm,
|
||||
|
|
@ -472,7 +522,19 @@ EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm,
|
|||
return evp_generic_fetch_from_prov(prov, OSSL_OP_KEM, algorithm, properties,
|
||||
evp_kem_from_algorithm,
|
||||
evp_kem_up_ref,
|
||||
evp_kem_free);
|
||||
evp_kem_free,
|
||||
evp_kem_dup_frozen,
|
||||
evp_kem_frozen_free);
|
||||
}
|
||||
|
||||
int evp_kem_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx, OSSL_OP_KEM,
|
||||
evp_kem_from_algorithm,
|
||||
evp_kem_up_ref,
|
||||
evp_kem_free,
|
||||
evp_kem_dup_frozen,
|
||||
evp_kem_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_KEM_is_a(const EVP_KEM *kem, const char *name)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/evp.h>
|
||||
|
|
@ -22,11 +23,59 @@ static void evp_keymgmt_free(void *data)
|
|||
EVP_KEYMGMT_free(data);
|
||||
}
|
||||
|
||||
static void evp_keymgmt_free_int(EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
OPENSSL_free(keymgmt->type_name);
|
||||
ossl_provider_free(keymgmt->prov);
|
||||
CRYPTO_FREE_REF(&keymgmt->refcnt);
|
||||
OPENSSL_free(keymgmt);
|
||||
}
|
||||
|
||||
static int evp_keymgmt_up_ref(void *data)
|
||||
{
|
||||
return EVP_KEYMGMT_up_ref(data);
|
||||
}
|
||||
|
||||
static void *evp_keymgmt_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_KEYMGMT *in = vin;
|
||||
EVP_KEYMGMT *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov != NULL && !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_keymgmt_frozen_free(void *vin)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (keymgmt == NULL || keymgmt->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_keymgmt_free_int(keymgmt);
|
||||
}
|
||||
|
||||
static void *keymgmt_new(void)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
|
|
@ -274,7 +323,19 @@ EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
name, properties,
|
||||
keymgmt_from_algorithm,
|
||||
evp_keymgmt_up_ref,
|
||||
evp_keymgmt_free);
|
||||
evp_keymgmt_free,
|
||||
evp_keymgmt_dup_frozen,
|
||||
evp_keymgmt_frozen_free);
|
||||
}
|
||||
|
||||
int evp_keymgmt_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx, OSSL_OP_KEYMGMT,
|
||||
keymgmt_from_algorithm,
|
||||
evp_keymgmt_up_ref,
|
||||
evp_keymgmt_free,
|
||||
evp_keymgmt_dup_frozen,
|
||||
evp_keymgmt_frozen_free);
|
||||
}
|
||||
|
||||
EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
|
|
@ -283,14 +344,17 @@ EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
|||
return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
|
||||
keymgmt_from_algorithm,
|
||||
evp_keymgmt_up_ref,
|
||||
evp_keymgmt_free);
|
||||
evp_keymgmt_free,
|
||||
evp_keymgmt_dup_frozen,
|
||||
evp_keymgmt_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&keymgmt->refcnt, &ref);
|
||||
if (keymgmt->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&keymgmt->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -298,16 +362,13 @@ void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
|
|||
{
|
||||
int ref = 0;
|
||||
|
||||
if (keymgmt == NULL)
|
||||
if (keymgmt == NULL || keymgmt->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
OPENSSL_free(keymgmt->type_name);
|
||||
ossl_provider_free(keymgmt->prov);
|
||||
CRYPTO_FREE_REF(&keymgmt->refcnt);
|
||||
OPENSSL_free(keymgmt);
|
||||
evp_keymgmt_free_int(keymgmt);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_KEYMGMT_get0_provider(const EVP_KEYMGMT *keymgmt)
|
||||
|
|
|
|||
|
|
@ -11,17 +11,27 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <string.h>
|
||||
#include "internal/provider.h"
|
||||
#include "internal/core.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
static void evp_mac_free_int(EVP_MAC *mac)
|
||||
{
|
||||
OPENSSL_free(mac->type_name);
|
||||
ossl_provider_free(mac->prov);
|
||||
CRYPTO_FREE_REF(&mac->refcnt);
|
||||
OPENSSL_free(mac);
|
||||
}
|
||||
|
||||
static int evp_mac_up_ref(void *vmac)
|
||||
{
|
||||
EVP_MAC *mac = vmac;
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&mac->refcnt, &ref);
|
||||
if (mac->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&mac->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -30,16 +40,54 @@ static void evp_mac_free(void *vmac)
|
|||
EVP_MAC *mac = vmac;
|
||||
int ref = 0;
|
||||
|
||||
if (mac == NULL)
|
||||
if (mac == NULL || mac->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&mac->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
OPENSSL_free(mac->type_name);
|
||||
ossl_provider_free(mac->prov);
|
||||
CRYPTO_FREE_REF(&mac->refcnt);
|
||||
OPENSSL_free(mac);
|
||||
evp_mac_free_int(mac);
|
||||
}
|
||||
|
||||
static void *evp_mac_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_MAC *in = vin;
|
||||
EVP_MAC *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_mac_frozen_free(void *vin)
|
||||
{
|
||||
EVP_MAC *mac = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (mac == NULL || mac->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&mac->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_mac_free_int(mac);
|
||||
}
|
||||
|
||||
static void *evp_mac_new(void)
|
||||
|
|
@ -175,9 +223,23 @@ err:
|
|||
EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
|
||||
evp_mac_from_algorithm, evp_mac_up_ref,
|
||||
evp_mac_free);
|
||||
return evp_generic_fetch(libctx, OSSL_OP_MAC,
|
||||
algorithm, properties,
|
||||
evp_mac_from_algorithm,
|
||||
evp_mac_up_ref,
|
||||
evp_mac_free,
|
||||
evp_mac_dup_frozen,
|
||||
evp_mac_frozen_free);
|
||||
}
|
||||
|
||||
int evp_mac_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx, OSSL_OP_MAC,
|
||||
evp_mac_from_algorithm,
|
||||
evp_mac_up_ref,
|
||||
evp_mac_free,
|
||||
evp_mac_dup_frozen,
|
||||
evp_mac_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_MAC_up_ref(EVP_MAC *mac)
|
||||
|
|
@ -259,5 +321,7 @@ EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_mac_from_algorithm,
|
||||
evp_mac_up_ref,
|
||||
evp_mac_free);
|
||||
evp_mac_free,
|
||||
evp_mac_dup_frozen,
|
||||
evp_mac_frozen_free);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -486,7 +486,7 @@ EVP_SIGNATURE *EVP_SIGNATURE_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
|||
return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties,
|
||||
evp_signature_from_algorithm,
|
||||
evp_signature_up_ref,
|
||||
evp_signature_free);
|
||||
evp_signature_free, NULL, NULL);
|
||||
}
|
||||
|
||||
EVP_SIGNATURE *evp_signature_fetch_from_prov(OSSL_PROVIDER *prov,
|
||||
|
|
@ -497,7 +497,9 @@ EVP_SIGNATURE *evp_signature_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
algorithm, properties,
|
||||
evp_signature_from_algorithm,
|
||||
evp_signature_up_ref,
|
||||
evp_signature_free);
|
||||
evp_signature_free,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/evp.h>
|
||||
|
|
@ -17,6 +18,55 @@
|
|||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
static void evp_skeymgmt_free_int(EVP_SKEYMGMT *skeymgmt)
|
||||
{
|
||||
OPENSSL_free(skeymgmt->type_name);
|
||||
ossl_provider_free(skeymgmt->prov);
|
||||
CRYPTO_FREE_REF(&skeymgmt->refcnt);
|
||||
OPENSSL_free(skeymgmt);
|
||||
}
|
||||
|
||||
static void *evp_skeymgmt_dup_frozen(void *vin)
|
||||
{
|
||||
EVP_SKEYMGMT *in = vin;
|
||||
EVP_SKEYMGMT *out;
|
||||
|
||||
out = OPENSSL_malloc(sizeof(*out));
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
memcpy(out, in, sizeof(*out));
|
||||
if (!CRYPTO_NEW_REF(&out->refcnt, 1))
|
||||
goto err;
|
||||
out->type_name = OPENSSL_strdup(in->type_name);
|
||||
if (out->type_name == NULL)
|
||||
goto err;
|
||||
out->origin = EVP_ORIG_FROZEN;
|
||||
if (out->prov == NULL || !ossl_provider_up_ref(out->prov)) {
|
||||
OPENSSL_free(out->type_name);
|
||||
goto err;
|
||||
}
|
||||
return out;
|
||||
|
||||
err:
|
||||
CRYPTO_FREE_REF(&out->refcnt);
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void evp_skeymgmt_frozen_free(void *vin)
|
||||
{
|
||||
EVP_SKEYMGMT *skeymgmt = vin;
|
||||
int ref = 0;
|
||||
|
||||
if (skeymgmt == NULL || skeymgmt->origin != EVP_ORIG_FROZEN)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&skeymgmt->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
evp_skeymgmt_free_int(skeymgmt);
|
||||
}
|
||||
|
||||
void *evp_skeymgmt_generate(const EVP_SKEYMGMT *skeymgmt, const OSSL_PARAM params[])
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt));
|
||||
|
|
@ -136,7 +186,9 @@ EVP_SKEYMGMT *evp_skeymgmt_fetch_from_prov(OSSL_PROVIDER *prov,
|
|||
name, properties,
|
||||
skeymgmt_from_algorithm,
|
||||
(int (*)(void *))EVP_SKEYMGMT_up_ref,
|
||||
(void (*)(void *))EVP_SKEYMGMT_free);
|
||||
(void (*)(void *))EVP_SKEYMGMT_free,
|
||||
evp_skeymgmt_dup_frozen,
|
||||
evp_skeymgmt_frozen_free);
|
||||
}
|
||||
|
||||
EVP_SKEYMGMT *EVP_SKEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||
|
|
@ -145,14 +197,28 @@ EVP_SKEYMGMT *EVP_SKEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
|||
return evp_generic_fetch(ctx, OSSL_OP_SKEYMGMT, algorithm, properties,
|
||||
skeymgmt_from_algorithm,
|
||||
(int (*)(void *))EVP_SKEYMGMT_up_ref,
|
||||
(void (*)(void *))EVP_SKEYMGMT_free);
|
||||
(void (*)(void *))EVP_SKEYMGMT_free,
|
||||
evp_skeymgmt_dup_frozen,
|
||||
evp_skeymgmt_frozen_free);
|
||||
}
|
||||
|
||||
int evp_skeymgmt_fetch_all(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return evp_generic_fetch_all(ctx,
|
||||
OSSL_OP_SKEYMGMT,
|
||||
skeymgmt_from_algorithm,
|
||||
(int (*)(void *))EVP_SKEYMGMT_up_ref,
|
||||
(void (*)(void *))EVP_SKEYMGMT_free,
|
||||
evp_skeymgmt_dup_frozen,
|
||||
evp_skeymgmt_frozen_free);
|
||||
}
|
||||
|
||||
int EVP_SKEYMGMT_up_ref(EVP_SKEYMGMT *skeymgmt)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&skeymgmt->refcnt, &ref);
|
||||
if (skeymgmt->origin == EVP_ORIG_DYNAMIC)
|
||||
CRYPTO_UP_REF(&skeymgmt->refcnt, &ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -160,16 +226,13 @@ void EVP_SKEYMGMT_free(EVP_SKEYMGMT *skeymgmt)
|
|||
{
|
||||
int ref = 0;
|
||||
|
||||
if (skeymgmt == NULL)
|
||||
if (skeymgmt == NULL || skeymgmt->origin != EVP_ORIG_DYNAMIC)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&skeymgmt->refcnt, &ref);
|
||||
if (ref > 0)
|
||||
return;
|
||||
OPENSSL_free(skeymgmt->type_name);
|
||||
ossl_provider_free(skeymgmt->prov);
|
||||
CRYPTO_FREE_REF(&skeymgmt->refcnt);
|
||||
OPENSSL_free(skeymgmt);
|
||||
evp_skeymgmt_free_int(skeymgmt);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_SKEYMGMT_get0_provider(const EVP_SKEYMGMT *skeymgmt)
|
||||
|
|
|
|||
|
|
@ -12,19 +12,20 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/core.h"
|
||||
#include "internal/property.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/core.h"
|
||||
#include "internal/tsan_assist.h"
|
||||
#include "crypto/ctype.h"
|
||||
#include "internal/hashtable.h"
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/trace.h>
|
||||
#include "internal/thread_once.h"
|
||||
#include "crypto/lhash.h"
|
||||
#include "crypto/sparse_array.h"
|
||||
#include "property_local.h"
|
||||
#include "crypto/context.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/evp/evp_local.h"
|
||||
#include "internal/namemap.h"
|
||||
|
||||
/*
|
||||
* The number of elements in the query cache before we initiate a flush.
|
||||
|
|
@ -37,6 +38,8 @@ typedef struct {
|
|||
void *method;
|
||||
int (*up_ref)(void *);
|
||||
void (*free)(void *);
|
||||
void *(*dup)(void *);
|
||||
void (*free_dup)(void *);
|
||||
} METHOD;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -65,6 +68,9 @@ typedef struct {
|
|||
struct ossl_method_store_st {
|
||||
OSSL_LIB_CTX *ctx;
|
||||
SPARSE_ARRAY_OF(ALGORITHM) * algs;
|
||||
|
||||
/* (nid, propq) -> method */
|
||||
HT *frozen_algs;
|
||||
/*
|
||||
* Lock to protect the |algs| array from concurrent writing, when
|
||||
* individual implementations or queries are inserted. This is used
|
||||
|
|
@ -86,6 +92,12 @@ struct ossl_method_store_st {
|
|||
|
||||
/* Flag: 1 if query cache entries for all algs need flushing */
|
||||
int cache_need_flush;
|
||||
|
||||
/* Flag: 1 if method store is frozen */
|
||||
int frozen;
|
||||
|
||||
/* Property query associated with frozen state */
|
||||
char *frozen_propq;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -99,6 +111,13 @@ DEFINE_SPARSE_ARRAY_OF(ALGORITHM);
|
|||
|
||||
DEFINE_STACK_OF(ALGORITHM)
|
||||
|
||||
HT_START_KEY_DEFN(frozen_cache_key)
|
||||
HT_DEF_KEY_FIELD_CHAR_ARRAY(name, 64)
|
||||
/* TODO(FREEZE): allow variable length propq */
|
||||
HT_DEF_KEY_FIELD_CHAR_ARRAY(propq, 64)
|
||||
HT_DEF_KEY_FIELD(op_id, unsigned int)
|
||||
HT_END_KEY_DEFN(FROZEN_CACHE_KEY)
|
||||
|
||||
typedef struct ossl_global_properties_st {
|
||||
OSSL_PROPERTY_LIST *list;
|
||||
#ifndef FIPS_MODULE
|
||||
|
|
@ -169,6 +188,30 @@ static void ossl_method_free(METHOD *method)
|
|||
(*method->free)(method->method);
|
||||
}
|
||||
|
||||
static void ossl_method_free_frozen(METHOD *method)
|
||||
{
|
||||
(*method->free_dup)(method->method);
|
||||
}
|
||||
|
||||
static METHOD *ossl_method_dup(METHOD *method)
|
||||
{
|
||||
METHOD *dup;
|
||||
|
||||
dup = OPENSSL_zalloc(sizeof(*dup));
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(dup, method, sizeof(*dup));
|
||||
|
||||
dup->method = (*method->dup)(method->method);
|
||||
if (dup->method == NULL) {
|
||||
OPENSSL_free(dup);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
static __owur int ossl_property_read_lock(OSSL_METHOD_STORE *p)
|
||||
{
|
||||
return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0;
|
||||
|
|
@ -262,9 +305,12 @@ void ossl_method_store_free(OSSL_METHOD_STORE *store)
|
|||
if (store != NULL) {
|
||||
if (store->algs != NULL)
|
||||
ossl_sa_ALGORITHM_doall_arg(store->algs, &alg_cleanup, store);
|
||||
if (store->frozen_algs != NULL)
|
||||
ossl_ht_free(store->frozen_algs);
|
||||
ossl_sa_ALGORITHM_free(store->algs);
|
||||
CRYPTO_THREAD_lock_free(store->lock);
|
||||
CRYPTO_THREAD_lock_free(store->biglock);
|
||||
OPENSSL_free(store->frozen_propq);
|
||||
OPENSSL_free(store);
|
||||
}
|
||||
}
|
||||
|
|
@ -317,14 +363,16 @@ static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg)
|
|||
int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
|
||||
int nid, const char *properties, void *method,
|
||||
int (*method_up_ref)(void *),
|
||||
void (*method_destruct)(void *))
|
||||
void (*method_destruct)(void *),
|
||||
void *(*method_dup)(void *),
|
||||
void (*free_frozen)(void *))
|
||||
{
|
||||
ALGORITHM *alg = NULL;
|
||||
IMPLEMENTATION *impl;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (nid <= 0 || method == NULL || store == NULL)
|
||||
if (nid <= 0 || method == NULL || store == NULL || store->frozen == 1)
|
||||
return 0;
|
||||
|
||||
if (properties == NULL)
|
||||
|
|
@ -340,6 +388,8 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
|
|||
impl->method.method = method;
|
||||
impl->method.up_ref = method_up_ref;
|
||||
impl->method.free = method_destruct;
|
||||
impl->method.dup = method_dup;
|
||||
impl->method.free_dup = free_frozen;
|
||||
if (!ossl_method_up_ref(&impl->method)) {
|
||||
OPENSSL_free(impl);
|
||||
return 0;
|
||||
|
|
@ -438,7 +488,7 @@ int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid,
|
|||
ALGORITHM *alg = NULL;
|
||||
int i;
|
||||
|
||||
if (nid <= 0 || method == NULL || store == NULL)
|
||||
if (nid <= 0 || method == NULL || store == NULL || store->frozen == 1)
|
||||
return 0;
|
||||
|
||||
if (!ossl_property_write_lock(store))
|
||||
|
|
@ -540,7 +590,7 @@ int ossl_method_store_remove_all_provided(OSSL_METHOD_STORE *store,
|
|||
{
|
||||
struct alg_cleanup_by_provider_data_st data;
|
||||
|
||||
if (!ossl_property_write_lock(store))
|
||||
if (store == NULL || store->frozen == 1 || !ossl_property_write_lock(store))
|
||||
return 0;
|
||||
data.prov = prov;
|
||||
data.store = store;
|
||||
|
|
@ -609,32 +659,9 @@ void ossl_method_store_do_all(OSSL_METHOD_STORE *store,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetches a method from the method store matching the given properties.
|
||||
*
|
||||
* This function searches the method store for an implementation of a specified
|
||||
* method, identified by its id (nid), and matching the given property query. If
|
||||
* successful, it returns the method and its associated provider.
|
||||
*
|
||||
* @param store Pointer to the OSSL_METHOD_STORE from which to fetch the method.
|
||||
* Must be non-null.
|
||||
* @param nid (identifier) of the method to be fetched. Must be > 0
|
||||
* @param prop_query String containing the property query to match against.
|
||||
* @param prov_rw Pointer to the OSSL_PROVIDER to restrict the search to, or
|
||||
* to receive the matched provider.
|
||||
* @param method Pointer to receive the fetched method. Must be non-null.
|
||||
*
|
||||
* @return 1 if the method is successfully fetched, 0 on failure.
|
||||
*
|
||||
* If tracing is enabled, a message is printed indicating the property query and
|
||||
* the resolved provider.
|
||||
*
|
||||
* NOTE: The nid parameter here is _not_ a NID in the sense of the NID_* macros.
|
||||
* It is a unique internal identifier value.
|
||||
*/
|
||||
int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
|
||||
static int ossl_method_store_fetch_best_impl(OSSL_METHOD_STORE *store,
|
||||
int nid, const char *prop_query,
|
||||
const OSSL_PROVIDER **prov_rw, void **method)
|
||||
const OSSL_PROVIDER **prov_rw, IMPLEMENTATION **rbest_impl)
|
||||
{
|
||||
OSSL_PROPERTY_LIST **plp;
|
||||
ALGORITHM *alg;
|
||||
|
|
@ -644,7 +671,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
|
|||
int ret = 0;
|
||||
int j, best = -1, score, optional;
|
||||
|
||||
if (nid <= 0 || method == NULL || store == NULL)
|
||||
if (nid <= 0 || store == NULL || rbest_impl == NULL)
|
||||
return 0;
|
||||
|
||||
#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_AUTOLOAD_CONFIG)
|
||||
|
|
@ -729,8 +756,8 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
|
|||
}
|
||||
}
|
||||
fin:
|
||||
if (ret && ossl_method_up_ref(&best_impl->method)) {
|
||||
*method = best_impl->method.method;
|
||||
if (ret) {
|
||||
*rbest_impl = best_impl;
|
||||
if (prov_rw != NULL)
|
||||
*prov_rw = best_impl->provider;
|
||||
} else {
|
||||
|
|
@ -757,6 +784,48 @@ fin:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetches a method from the method store matching the given properties.
|
||||
*
|
||||
* This function searches the method store for an implementation of a specified
|
||||
* method, identified by its id (nid), and matching the given property query. If
|
||||
* successful, it returns the method and its associated provider.
|
||||
*
|
||||
* @param store Pointer to the OSSL_METHOD_STORE from which to fetch the method.
|
||||
* Must be non-null.
|
||||
* @param nid (identifier) of the method to be fetched. Must be > 0
|
||||
* @param prop_query String containing the property query to match against.
|
||||
* @param prov_rw Pointer to the OSSL_PROVIDER to restrict the search to, or
|
||||
* to receive the matched provider.
|
||||
* @param method Pointer to receive the fetched method. Must be non-null.
|
||||
*
|
||||
* @return 1 if the method is successfully fetched, 0 on failure.
|
||||
*
|
||||
* If tracing is enabled, a message is printed indicating the property query and
|
||||
* the resolved provider.
|
||||
*
|
||||
* NOTE: The nid parameter here is _not_ a NID in the sense of the NID_* macros.
|
||||
* It is a unique internal identifier value.
|
||||
*/
|
||||
int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
|
||||
int nid, const char *prop_query,
|
||||
const OSSL_PROVIDER **prov_rw, void **method)
|
||||
{
|
||||
IMPLEMENTATION *best_impl = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (nid <= 0 || store == NULL || method == NULL)
|
||||
return 0;
|
||||
|
||||
ret = ossl_method_store_fetch_best_impl(store, nid, prop_query, prov_rw, &best_impl);
|
||||
if (ret && ossl_method_up_ref(&best_impl->method))
|
||||
*method = best_impl->method.method;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ossl_method_cache_flush_alg(OSSL_METHOD_STORE *store,
|
||||
ALGORITHM *alg)
|
||||
{
|
||||
|
|
@ -774,7 +843,7 @@ static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid)
|
|||
|
||||
int ossl_method_store_cache_flush_all(OSSL_METHOD_STORE *store)
|
||||
{
|
||||
if (!ossl_property_write_lock(store))
|
||||
if (store == NULL || store->frozen == 1 || !ossl_property_write_lock(store))
|
||||
return 0;
|
||||
ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg);
|
||||
store->cache_nelem = 0;
|
||||
|
|
@ -889,7 +958,9 @@ err:
|
|||
int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
|
||||
int nid, const char *prop_query, void *method,
|
||||
int (*method_up_ref)(void *),
|
||||
void (*method_destruct)(void *))
|
||||
void (*method_destruct)(void *),
|
||||
void *(*method_dup)(void *),
|
||||
void (*free_dup)(void *))
|
||||
{
|
||||
QUERY elem, *old, *p = NULL;
|
||||
ALGORITHM *alg;
|
||||
|
|
@ -926,6 +997,8 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
|
|||
p->method.method = method;
|
||||
p->method.up_ref = method_up_ref;
|
||||
p->method.free = method_destruct;
|
||||
p->method.dup = method_dup;
|
||||
p->method.free_dup = free_dup;
|
||||
if (!ossl_method_up_ref(&p->method))
|
||||
goto err;
|
||||
memcpy((char *)p->query, prop_query, len + 1);
|
||||
|
|
@ -947,3 +1020,193 @@ end:
|
|||
ossl_property_unlock(store);
|
||||
return res;
|
||||
}
|
||||
|
||||
int ossl_frozen_method_store_cache_get(OSSL_METHOD_STORE *store,
|
||||
const char *alg_name, const char *prop_query, unsigned int operation_id,
|
||||
void **method)
|
||||
{
|
||||
FROZEN_CACHE_KEY key;
|
||||
HT_VALUE *val;
|
||||
|
||||
if (store == NULL
|
||||
|| alg_name == NULL
|
||||
|| prop_query == NULL
|
||||
|| store->frozen_algs == NULL)
|
||||
return 0;
|
||||
|
||||
HT_INIT_KEY(&key);
|
||||
HT_SET_KEY_STRING_CASE(&key, name, alg_name);
|
||||
HT_SET_KEY_STRING(&key, propq, prop_query);
|
||||
HT_SET_KEY_FIELD(&key, op_id, operation_id);
|
||||
|
||||
val = ossl_ht_get(store->frozen_algs, TO_HT_KEY(&key));
|
||||
if (val == NULL)
|
||||
return 1;
|
||||
*method = ((METHOD *)val->value)->method;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct alg_freeze_st {
|
||||
OSSL_METHOD_STORE *store;
|
||||
int nid;
|
||||
|
||||
int ret;
|
||||
};
|
||||
|
||||
static void frozen_cache_free(HT_VALUE *val)
|
||||
{
|
||||
METHOD *method = (METHOD *)val->value;
|
||||
if (method == NULL || method->free_dup == NULL)
|
||||
return;
|
||||
ossl_method_free_frozen(method);
|
||||
|
||||
OPENSSL_free(method);
|
||||
}
|
||||
|
||||
static int freeze_alg(OSSL_METHOD_STORE *store, ALGORITHM *alg,
|
||||
const char *propq, const char *alg_name, int operation_id)
|
||||
{
|
||||
int ret = 0;
|
||||
IMPLEMENTATION *best_impl = NULL;
|
||||
FROZEN_CACHE_KEY key;
|
||||
HT_VALUE val = { 0 };
|
||||
const OSSL_PROVIDER *prov = NULL;
|
||||
|
||||
HT_INIT_KEY(&key);
|
||||
HT_SET_KEY_STRING_CASE(&key, name, alg_name);
|
||||
HT_SET_KEY_STRING(&key, propq, propq);
|
||||
HT_SET_KEY_FIELD(&key, op_id, operation_id);
|
||||
|
||||
if (ossl_ht_get(store->frozen_algs, TO_HT_KEY(&key)) != NULL)
|
||||
return 1;
|
||||
|
||||
ret = ossl_method_store_fetch_best_impl(store,
|
||||
alg->nid, propq, &prov, &best_impl);
|
||||
if (ret == 0 || best_impl == NULL
|
||||
|| best_impl->method.dup == NULL
|
||||
|| best_impl->method.free_dup == NULL)
|
||||
return 1;
|
||||
|
||||
val.value = ossl_method_dup(&best_impl->method);
|
||||
if (val.value == NULL)
|
||||
return ret;
|
||||
|
||||
ret = ossl_ht_insert(store->frozen_algs, TO_HT_KEY(&key), &val, NULL);
|
||||
if (ret <= 0) {
|
||||
frozen_cache_free(&val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void alg_freeze(ossl_uintmax_t idx, ALGORITHM *alg, void *arg)
|
||||
{
|
||||
struct alg_freeze_st *af = arg;
|
||||
OSSL_NAMEMAP *nm = ossl_namemap_stored(af->store->ctx);
|
||||
int name_id;
|
||||
unsigned int op_id;
|
||||
const char *name;
|
||||
int i = 0;
|
||||
|
||||
if (alg == NULL
|
||||
|| !evp_method_id2name_id_op_id(alg->nid, &name_id, &op_id)) {
|
||||
af->ret = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
name = ossl_namemap_num2name(nm, name_id, i++);
|
||||
if (name == NULL)
|
||||
break;
|
||||
if (*af->store->frozen_propq != '\0') {
|
||||
af->ret = freeze_alg(af->store, alg, af->store->frozen_propq, name, op_id);
|
||||
if (!af->ret)
|
||||
return;
|
||||
}
|
||||
af->ret = freeze_alg(af->store, alg, "", name, op_id);
|
||||
if (!af->ret)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Freezes the method store's cache into a hash table.
|
||||
*
|
||||
* This function creates a frozen copy of the method store's cache, storing it
|
||||
* in a hash table for efficient retrieval. Each entry in the cache is duplicated
|
||||
* to ensure that the frozen cache is independent of the original store.
|
||||
*
|
||||
* @param store Pointer to the OSSL_METHOD_STORE to be frozen.
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*
|
||||
* If the store is NULL or if any duplication fails, the function returns 0.
|
||||
* On success, it returns 1 after populating the frozen cache.
|
||||
*/
|
||||
int ossl_method_store_freeze_cache(OSSL_METHOD_STORE *store, const char *propq)
|
||||
{
|
||||
HT_CONFIG ht_conf = {
|
||||
.ht_free_fn = frozen_cache_free,
|
||||
.init_neighborhoods = store->cache_nelem,
|
||||
.collision_check = 1,
|
||||
.no_rcu = 1,
|
||||
};
|
||||
struct alg_freeze_st af = {
|
||||
.store = store,
|
||||
.ret = 1,
|
||||
};
|
||||
propq = propq != NULL ? propq : "";
|
||||
|
||||
if (store == NULL || store->frozen == 1)
|
||||
return 0;
|
||||
|
||||
store->frozen_propq = OPENSSL_strdup(propq);
|
||||
if (store->frozen_propq == NULL)
|
||||
goto err;
|
||||
|
||||
store->frozen_algs = ossl_ht_new(&ht_conf);
|
||||
if (store->frozen_algs == NULL)
|
||||
goto err;
|
||||
|
||||
if (evp_md_fetch_all(store->ctx) <= 0
|
||||
|| evp_cipher_fetch_all(store->ctx) <= 0
|
||||
|| evp_rand_fetch_all(store->ctx) <= 0
|
||||
|| evp_mac_fetch_all(store->ctx) <= 0
|
||||
|| evp_keymgmt_fetch_all(store->ctx) <= 0
|
||||
|| evp_kdf_fetch_all(store->ctx) <= 0
|
||||
|| evp_kem_fetch_all(store->ctx) <= 0
|
||||
|| evp_asym_cipher_fetch_all(store->ctx) <= 0
|
||||
|| evp_keyexch_fetch_all(store->ctx) <= 0
|
||||
|| evp_skeymgmt_fetch_all(store->ctx) <= 0)
|
||||
goto err;
|
||||
|
||||
ossl_sa_ALGORITHM_doall_arg(store->algs, &alg_freeze, &af);
|
||||
if (af.ret <= 0)
|
||||
goto err;
|
||||
|
||||
store->frozen = 1;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(store->frozen_propq);
|
||||
ossl_ht_free(store->frozen_algs);
|
||||
store->frozen_algs = NULL;
|
||||
store->frozen_propq = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_method_store_is_frozen(OSSL_METHOD_STORE *store)
|
||||
{
|
||||
return store != NULL && store->frozen == 1;
|
||||
}
|
||||
|
||||
const char *ossl_method_store_frozen_propq(OSSL_METHOD_STORE *store)
|
||||
{
|
||||
if (store == NULL)
|
||||
return NULL;
|
||||
return store->frozen_propq;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ static int put_loader_in_store(void *store, void *method,
|
|||
return 0;
|
||||
|
||||
return ossl_method_store_add(store, prov, id, propdef, method,
|
||||
up_ref_loader, free_loader);
|
||||
up_ref_loader, free_loader, NULL, NULL);
|
||||
}
|
||||
|
||||
static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef,
|
||||
|
|
@ -339,7 +339,7 @@ inner_loader_fetch(struct loader_data_st *methdata,
|
|||
if (id == 0)
|
||||
id = ossl_namemap_name2num(namemap, scheme);
|
||||
ossl_method_store_cache_set(store, prov, id, propq, method,
|
||||
up_ref_loader, free_loader);
|
||||
up_ref_loader, free_loader, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
OSSL_LIB_CTX, OSSL_LIB_CTX_get_data, OSSL_LIB_CTX_new,
|
||||
OSSL_LIB_CTX_new_from_dispatch, OSSL_LIB_CTX_new_child,
|
||||
OSSL_LIB_CTX_free, OSSL_LIB_CTX_load_config,
|
||||
OSSL_LIB_CTX_get0_global_default, OSSL_LIB_CTX_set0_default
|
||||
OSSL_LIB_CTX_get0_global_default, OSSL_LIB_CTX_set0_default,
|
||||
OSSL_LIB_CTX_freeze
|
||||
- OpenSSL library context
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
|
@ -24,6 +25,7 @@ OSSL_LIB_CTX_get0_global_default, OSSL_LIB_CTX_set0_default
|
|||
OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void);
|
||||
OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *ctx);
|
||||
void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index);
|
||||
void *OSSL_LIB_CTX_freeze(OSSL_LIB_CTX *ctx, const char *propq);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
|
@ -121,6 +123,32 @@ If ctx is NULL then the function operates on the default library context.
|
|||
OSSL_LIB_CTX_get_data() returns a memory address whose interpretation
|
||||
depends on the index.
|
||||
|
||||
OSSL_LIB_CTX_freeze() freezes the method store associated with the
|
||||
library context, and builds a fast lookup cache which will be used by
|
||||
subsequent EVP calls to fetch implementations. A frozen method store
|
||||
may no longer be modified, and operations attempting to do so (such as
|
||||
loading a new provider) will fail. This function must only be called
|
||||
from a non-threaded context, before any worker threads have been
|
||||
dispatched. A frozen method store can not be un-frozen, or frozen again.
|
||||
|
||||
OSSL_LIB_CTX_freeze() builds the lookup cache using an optional propq
|
||||
query string argument. OSSL_LIB_CTX_freeze() will build a cache of
|
||||
methods for all algorithms for the NULL property query, and if propq
|
||||
is non-NULL, it will also cache the methods for all algorithms
|
||||
matching the propq query string. Once frozen, future method store
|
||||
lookups using the the NULL propq or the provided propq will be
|
||||
answered from the cache. Any method store lookups for an algorithm
|
||||
using a different propq query string will not be answered from the
|
||||
cache, and will be looked up by the normal slower method.
|
||||
|
||||
OSSL_LIB_CTX_freeze() is intended for use where applications with
|
||||
worker threads are not able to be structured to pre-fetch and retain
|
||||
the algorithm methods from the method store prior to use, and which
|
||||
therefore may pay a considerable performance penalty for the method
|
||||
store lookup every time an algorithm is used. Applications which can
|
||||
pre-fetch the methods they need before their use should not use
|
||||
OSSL_LIB_CTX_freeze().
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_LIB_CTX_new(), OSSL_LIB_CTX_get0_global_default() and
|
||||
|
|
@ -134,15 +162,20 @@ OSSL_LIB_CTX_load_config() returns 1 on success, 0 on error.
|
|||
OSSL_LIB_CTX_get_data() returns a memory address whose interpretation
|
||||
depends on the index.
|
||||
|
||||
OSSL_LIB_CTX_freeze() returns 1 on success, 0 on error. A frozen library context
|
||||
cannot be frozen again.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
All of the functions described on this page were added in OpenSSL 3.0.
|
||||
|
||||
OSSL_LIB_CTX_get_data() was introduced in OpenSSL 3.4.
|
||||
|
||||
OSSL_LIB_CTX_freeze() was introduced in OpenSSL 4.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2019-2025 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
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ const EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void);
|
|||
struct evp_mac_st {
|
||||
OSSL_PROVIDER *prov;
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
|
||||
|
|
@ -230,6 +231,7 @@ struct evp_mac_st {
|
|||
struct evp_kdf_st {
|
||||
OSSL_PROVIDER *prov;
|
||||
int name_id;
|
||||
int origin;
|
||||
char *type_name;
|
||||
const char *description;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
|
|
@ -252,6 +254,7 @@ struct evp_kdf_st {
|
|||
#define EVP_ORIG_DYNAMIC 0
|
||||
#define EVP_ORIG_GLOBAL 1
|
||||
#define EVP_ORIG_METH 2
|
||||
#define EVP_ORIG_FROZEN 3
|
||||
|
||||
struct evp_md_st {
|
||||
/* nid */
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ int ossl_method_unlock_store(OSSL_METHOD_STORE *store);
|
|||
int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
|
||||
int nid, const char *properties, void *method,
|
||||
int (*method_up_ref)(void *),
|
||||
void (*method_destruct)(void *));
|
||||
void (*method_destruct)(void *),
|
||||
void *(*method_dup)(void *),
|
||||
void (*free_frozen)(void *));
|
||||
int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid,
|
||||
const void *method);
|
||||
void ossl_method_store_do_all(OSSL_METHOD_STORE *store,
|
||||
|
|
@ -81,7 +83,9 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
|
|||
int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
|
||||
int nid, const char *prop_query, void *result,
|
||||
int (*method_up_ref)(void *),
|
||||
void (*method_destruct)(void *));
|
||||
void (*method_destruct)(void *),
|
||||
void *(*method_dup)(void *),
|
||||
void (*free_frozen)(void *));
|
||||
|
||||
__owur int ossl_method_store_cache_flush_all(OSSL_METHOD_STORE *store);
|
||||
|
||||
|
|
@ -96,4 +100,12 @@ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
|
|||
int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx);
|
||||
void ossl_global_properties_stop_mirroring(OSSL_LIB_CTX *libctx);
|
||||
|
||||
int ossl_method_store_freeze_cache(OSSL_METHOD_STORE *store, const char *propq);
|
||||
int ossl_frozen_method_store_cache_get(OSSL_METHOD_STORE *store,
|
||||
const char *name, const char *prop_query, unsigned int operation_id,
|
||||
void **result);
|
||||
|
||||
int ossl_method_store_is_frozen(OSSL_METHOD_STORE *store);
|
||||
const char *ossl_method_store_frozen_propq(OSSL_METHOD_STORE *store);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -586,6 +586,7 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void);
|
|||
OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx);
|
||||
int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX *ctx);
|
||||
void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX *ctx, int value);
|
||||
int OSSL_LIB_CTX_freeze(OSSL_LIB_CTX *ctx, const char *propq);
|
||||
|
||||
void OSSL_sleep(uint64_t millis);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -392,7 +392,7 @@ static int test_register_deregister(void)
|
|||
for (i = 0; i < OSSL_NELEM(impls); i++)
|
||||
if (!TEST_true(ossl_method_store_add(store, &prov, impls[i].nid,
|
||||
impls[i].prop, impls[i].impl,
|
||||
&up_ref, &down_ref))) {
|
||||
&up_ref, &down_ref, NULL, NULL))) {
|
||||
TEST_note("iteration %zd", i + 1);
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -417,6 +417,41 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int test_freeze_flag(void)
|
||||
{
|
||||
int ret = 0, nid = 6;
|
||||
const char *prop = "position=1", *prop2 = "position=2";
|
||||
char *impl = "a", *impl2 = "b";
|
||||
OSSL_METHOD_STORE *store;
|
||||
OSSL_PROVIDER prov = { 1 };
|
||||
const OSSL_PROVIDER *fetched_prov = NULL;
|
||||
void *fetched_meth = NULL;
|
||||
|
||||
if (!TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
|| !TEST_true(add_property_names("position", NULL))
|
||||
|| !TEST_true(ossl_method_store_add(store, &prov, nid, prop, impl, &up_ref, &down_ref, NULL, NULL))
|
||||
|| !TEST_true(ossl_method_store_fetch(store, nid, prop, &fetched_prov, &fetched_meth))
|
||||
|| !TEST_ptr_eq(&prov, fetched_prov)
|
||||
|| !TEST_str_eq((char *)fetched_meth, impl)
|
||||
|| !TEST_true(ossl_method_store_freeze_cache(store, NULL))
|
||||
|| !TEST_false(ossl_method_store_remove(store, nid, impl))
|
||||
|| !TEST_true(ossl_method_store_fetch(store, nid, prop, &fetched_prov, &fetched_meth))
|
||||
|| !TEST_ptr_eq(&prov, fetched_prov)
|
||||
|| !TEST_str_eq((char *)fetched_meth, impl)
|
||||
|| !TEST_false(ossl_method_store_remove_all_provided(store, fetched_prov))
|
||||
|| !TEST_true(ossl_method_store_fetch(store, nid, prop, &fetched_prov, &fetched_meth))
|
||||
|| !TEST_ptr_eq(&prov, fetched_prov)
|
||||
|| !TEST_str_eq((char *)fetched_meth, impl)
|
||||
|| !TEST_false(ossl_method_store_add(store, &prov, nid, prop2, impl2, &up_ref, &down_ref, NULL, NULL))
|
||||
|| !TEST_false(ossl_method_store_freeze_cache(store, NULL)))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
ossl_method_store_free(store);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_property(void)
|
||||
{
|
||||
static OSSL_PROVIDER fake_provider1 = { 1 };
|
||||
|
|
@ -467,7 +502,7 @@ static int test_property(void)
|
|||
if (!TEST_true(ossl_method_store_add(store, *impls[i].prov,
|
||||
impls[i].nid, impls[i].prop,
|
||||
impls[i].impl,
|
||||
&up_ref, &down_ref))) {
|
||||
&up_ref, &down_ref, NULL, NULL))) {
|
||||
TEST_note("iteration %zd", i + 1);
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -578,13 +613,13 @@ static int test_query_cache_stochastic(void)
|
|||
v[i] = 2 * i;
|
||||
BIO_snprintf(buf, sizeof(buf), "n=%d\n", i);
|
||||
if (!TEST_true(ossl_method_store_add(store, &prov, i, buf, "abc",
|
||||
&up_ref, &down_ref))
|
||||
&up_ref, &down_ref, NULL, NULL))
|
||||
|| !TEST_true(ossl_method_store_cache_set(store, &prov, i,
|
||||
buf, v + i,
|
||||
&up_ref, &down_ref))
|
||||
&up_ref, &down_ref, NULL, NULL))
|
||||
|| !TEST_true(ossl_method_store_cache_set(store, &prov, i,
|
||||
"n=1234", "miss",
|
||||
&up_ref, &down_ref))) {
|
||||
&up_ref, &down_ref, NULL, NULL))) {
|
||||
TEST_note("iteration %d", i);
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -713,6 +748,7 @@ int setup_tests(void)
|
|||
ADD_TEST(test_property_defn_cache);
|
||||
ADD_ALL_TESTS(test_definition_compares, OSSL_NELEM(definition_tests));
|
||||
ADD_TEST(test_register_deregister);
|
||||
ADD_TEST(test_freeze_flag);
|
||||
ADD_TEST(test_property);
|
||||
ADD_TEST(test_query_cache_stochastic);
|
||||
ADD_TEST(test_fips_mode);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use lib bldtop_dir('.');
|
|||
|
||||
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
|
||||
|
||||
my @types = ( "digest", "cipher" );
|
||||
my @types = ( "digest", "cipher", "rand", "mac", "kmgmt", "kem", "kdf", "asymcipher", "evp_keyexch", "skeymgmt" );
|
||||
|
||||
my @testdata = (
|
||||
{ config => srctop_file("test", "default.cnf"),
|
||||
|
|
|
|||
|
|
@ -5815,3 +5815,4 @@ OSSL_PARAM_clear_free ? 4_0_0 EXIST::FUNCTION:
|
|||
CMS_dataFinal_ex ? 4_0_0 EXIST::FUNCTION:CMS
|
||||
CMS_SignerInfo_verify_ex ? 4_0_0 EXIST::FUNCTION:CMS
|
||||
EVP_SIGNATURE_has_message_update ? 4_0_0 EXIST::FUNCTION:
|
||||
OSSL_LIB_CTX_freeze ? 4_0_0 EXIST::FUNCTION:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue