Compare commits

...
Sign in to create a new pull request.

28 commits

Author SHA1 Message Date
Andrew Dinh
42f8690c2c Add freeze functionality to EVP_SKEYMGMT_fetch
Some checks failed
Run-checker CI / run-checker (no-tls1_3) (push) Has been cancelled
Run-checker CI / run-checker (no-ui) (push) Has been cancelled
Run-checker merge / run-checker (enable-asan enable-ubsan no-shared no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Has been cancelled
Run-checker merge / run-checker (enable-pie) (push) Has been cancelled
Run-checker merge / run-checker (enable-ubsan no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Has been cancelled
Run-checker merge / run-checker (enable-weak-ssl-ciphers) (push) Has been cancelled
Run-checker merge / run-checker (enable-zlib) (push) Has been cancelled
Run-checker merge / run-checker (no-dso) (push) Has been cancelled
Run-checker merge / run-checker (no-ec2m enable-fips) (push) Has been cancelled
Run-checker merge / run-checker (no-err) (push) Has been cancelled
Run-checker merge / run-checker (no-filenames) (push) Has been cancelled
Run-checker merge / run-checker (no-integrity-only-ciphers) (push) Has been cancelled
Run-checker merge / run-checker (no-module) (push) Has been cancelled
Run-checker merge / run-checker (no-ocsp) (push) Has been cancelled
Run-checker merge / run-checker (no-pinshared) (push) Has been cancelled
Run-checker merge / run-checker (no-shared) (push) Has been cancelled
Run-checker merge / run-checker (no-srp) (push) Has been cancelled
Run-checker merge / run-checker (no-srtp) (push) Has been cancelled
Run-checker merge / run-checker (no-ts) (push) Has been cancelled
Run-checker merge / jitter (push) Has been cancelled
Run-checker merge / threads_sanitizer_atomic_fallback (push) Has been cancelled
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips no-thread-pool no-quic os:windows-2025 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Has been cancelled
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Has been cancelled
Windows GitHub CI / shared (map[arch:x86 config:no-fips enable-lms os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat]) (push) Has been cancelled
Windows GitHub CI / plain (push) Has been cancelled
Windows GitHub CI / minimal (push) Has been cancelled
Windows GitHub CI / cygwin (windows-2022, map[arch:win64 config:-DCMAKE_C_COMPILER=gcc --strict-warnings enable-demos no-fips]) (push) Has been cancelled
Windows Compression GitHub CI / zstd (push) Has been cancelled
Windows Compression GitHub CI / brotli (push) Has been cancelled
Run-checker CI / run-checker (no-threads) (push) Failing after 8s
Add unit tests to check functionality

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Fri Apr 17 11:12:10 2026
(Merged from https://github.com/openssl/openssl/pull/30642)
2026-04-17 13:12:08 +02:00
Andrew Dinh
d1cae65c4a Add freeze functionality to EVP_KEYEXCH_fetch
Add unit tests to check functionality

Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
MergeDate: Fri Mar 27 16:28:10 2026
(Merged from https://github.com/openssl/openssl/pull/30462)
2026-03-27 17:27:50 +01:00
Andrew Dinh
fd185f596f Fix unit test with FIPS install
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Tue Mar 17 09:54:33 2026
(Merged from https://github.com/openssl/openssl/pull/30357)
2026-03-17 10:54:29 +01:00
Andrew Dinh
79439ccba0 Update test for EVP_ASYM_CIPHER freeze
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Tue Mar 17 09:54:32 2026
(Merged from https://github.com/openssl/openssl/pull/30357)
2026-03-17 10:54:29 +01:00
Andrew Dinh
b9970647df Add freeze functionality to EVP_ASYM_CIPHER_fetch
Add unit tests to check functionality

Fixes https://github.com/openssl/project/issues/1888

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Tue Mar 17 09:54:30 2026
(Merged from https://github.com/openssl/openssl/pull/30357)
2026-03-11 09:09:53 -07:00
Nikola Pajkovsky
a21cbce238 evp: freeze KDF fetch cache and expand KDF fetch tests
Add frozen-method support for EVP_KDF fetches by wiring dup/free
callbacks and populating KDF entries during OSSL_LIB_CTX_freeze().

perftools shows no performance gains

  $ ./evp_kdf -o evp_isolated 64 -f
  Average time per computation: 8181.213888us
  $ ./evp_kdf -o evp_isolated 64
  Average time per computation: 8307.157135us

Resolves https://github.com/openssl/project/issues/1834
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Wed Mar 11 12:15:18 2026
(Merged from https://github.com/openssl/openssl/pull/30081)
2026-03-06 14:26:49 +01:00
Nikola Pajkovsky
19056245f5 evp: freeze KEM fetch cache and expand KEM fetch tests
Add frozen-method support for EVP_KEM fetches by wiring dup/free
callbacks and populating KEM entries during OSSL_LIB_CTX_freeze().

https://github.com/openssl/project/issues/1833
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Thu Mar  5 17:21:25 2026
(Merged from https://github.com/openssl/openssl/pull/30078)
2026-03-05 18:21:04 +01:00
Nikola Pajkovsky
6441e227f6 evp: freeze KEYMGMT fetch cache and expand kmgmt fetch tests
Add frozen-method support for EVP_KEYMGMT fetches by wiring dup/free
callbacks and populating KEYMGMT entries during OSSL_LIB_CTX_freeze().

Resolves https://github.com/openssl/project/issues/1876
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Thu Mar  5 17:21:24 2026
(Merged from https://github.com/openssl/openssl/pull/30078)
2026-03-05 18:21:04 +01:00
Nikola Pajkovsky
f457bd93c5 Add operation_id to frozen method store cache key
The frozen method store cache was keyed only by algorithm name and
property query, which could cause incorrect cache hits when different
operation types (e.g., KEM vs signature) share the same algorithm name.

Include the operation_id in the FROZEN_CACHE_KEY and thread it through
ossl_frozen_method_store_cache_get(), freeze_alg(), and alg_freeze()
so that lookups correctly distinguish between operations on identically
named algorithms.

Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Thu Mar  5 17:21:22 2026
(Merged from https://github.com/openssl/openssl/pull/30078)
2026-03-05 18:21:04 +01:00
Bob Beck
302edc39e0 OSSL_LIB_CTX.pod: Tweak the docs for libcontext freeze
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Wed Mar  4 17:40:10 2026
(Merged from https://github.com/openssl/openssl/pull/30168)
2026-03-04 18:39:36 +01:00
Nikola Pajkovsky
9200ab5c15 evp: freeze MAC fetch cache and expand MAC fetch tests
Add frozen-method support for EVP_MAC fetches by wiring dup/free
callbacks and populating MAC entries during OSSL_LIB_CTX_freeze().

Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
MergeDate: Sat Feb 28 13:21:07 2026
(Merged from https://github.com/openssl/openssl/pull/30142)
2026-02-28 08:19:29 -05:00
Andrew Dinh
ccd9445247 Add freeze functionality to EVP_RAND_fetch
Add unit tests to check functionality

Move EVP_RAND to evp_local.h

Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
MergeDate: Fri Feb 27 17:24:53 2026
(Merged from https://github.com/openssl/openssl/pull/30151)
2026-02-27 12:24:49 -05:00
Nikola Pajkovsky
e77def380a evp: fix refcount leak in frozen digest/cipher dup error paths
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Thu Feb 26 15:10:57 2026
(Merged from https://github.com/openssl/openssl/pull/30154)
2026-02-24 14:13:27 +01:00
Nikola Pajkovsky
37bb988a0e evp: add freeze callbacks to evp_generic_fetch_from_prov
when RAND_bytes() is called before the freeze it tries to fetch
AES-256-CTR via evp_generic_fetch_from_prov without passing freezing
callbacks.

Stacktrace:
  inner_evp_generic_fetch (operation_id=2, name=0xfffff7744ae8 "AES-256-CTR", dup_method=0x0, dup_free_method=0x0)
  evp_generic_fetch_from_prov
  evp_cipher_fetch_from_prov (prov=0xfd0ff57e0540, algorithm=0xfffff7744ae8 "AES-256-CTR"
  drbg_ctr_set_ctx_params_locked
  drbg_ctr_instantiate_wrapper
  evp_rand_instantiate_locked
  EVP_RAND_instantiate
  rand_new_drbg
  rand_get0_primary
  rand_get0_public
  RAND_bytes_ex
  RAND_bytes

Calling evp_cipher_fetch_all() does not have any effects once method
store is filled for operations, and therefore freezing ciphers fails
because freezing filters dup_method == NULL || dup_free_method == NULL.

Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Feb 18 10:13:47 2026
(Merged from https://github.com/openssl/openssl/pull/30002)
2026-02-18 11:13:41 +01:00
Andrew Dinh
aa70893e25 Add freeze functionality to EVP_CIPHER_fetch
Add unit test to check functionality

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Feb 18 10:13:45 2026
(Merged from https://github.com/openssl/openssl/pull/30002)
2026-02-18 11:13:41 +01:00
Nikola Pajkovsky
901e728fda EVP_CIPHER: add required freezing callbacks
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Feb 18 10:13:43 2026
(Merged from https://github.com/openssl/openssl/pull/30002)
2026-02-11 09:58:01 +01:00
Nikola Pajkovsky
ca5f693271 evp: freezing method store
The METHOD struct contains two new callback. One that can duplicate a
given object from cache, and store it into HT, and the second for
freeing objects when HT is freed. frozen_algs maps

   (alg name, propq) -> method.

OSSL_LIB_CTX_freeze() freezes the method store associated with the
library context. A frozen context will speed up ONLY isolated,
uncached algorithm lookups. This is specifically designed to benefit
legacy high-throughput applications with worker threads doing isolated
computations, without requiring a code restructuring. Existing and new
applications are generally recommended to not use this feature and
instead structure the application to pre-initialize contexts where
possible. This function should only be called from a non-threaded
context, before any worker threads have been dispatched.

If propq is NULL, it will only speed up method store operations with a NULL
property query. If propq is not NULL, it will also speed up method store
operations when given that exact property query. Other property queries will go
through the normal, slower lookup method. When ctx is not NULL, and propq is NULL,
default context is frozen as well.

Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Feb 11 07:17:29 2026
(Merged from https://github.com/openssl/openssl/pull/29433)
2026-02-11 08:17:25 +01:00
Nikola Pajkovsky
de60bf9091 property: split ossl_method_store_fetch
freezing needs access to the IMPLEMENTATION but
ossl_method_store_fetch() does not returns it.

Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Feb 11 07:17:27 2026
(Merged from https://github.com/openssl/openssl/pull/29433)
2026-01-20 11:14:48 +01:00
Andrew Dinh
9d4f44f3e7 Remove frozen store. This is a mock up that will be replaced with the real implementation.
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-21 02:51:40 +07:00
Andrew Dinh
5844109177 Update documentation to only call freeze in non-threaded context
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-21 02:51:40 +07:00
Andrew Dinh
8a17b8ee9e Fix temporary freeze implementation
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-21 02:51:40 +07:00
Andrew Dinh
f174d994ef Add documentation for OSSL_LIB_CTX_freeze
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-21 02:51:30 +07:00
Andrew Dinh
d65db7f0e1 Add freeze functionality to EVP_MD_fetch()
Added freeze function for OSSL_LIB_CTX

Freeze implementation is just global variables. This will be fixed in a separate PR.

Added unit test to ensure correct methods are fetched. This unit test should work even when actual freeze implementation is added

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-19 01:09:14 +07:00
Andrew Dinh
ba4fce934a Remove prop_query for ossl_method_store_freeze
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29331)
2025-12-19 01:09:13 +07:00
Andrew Dinh
cb97cc61e0 Remove prop_query for ossl_method_store_freeze
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29265)
2025-12-15 00:34:48 +04:00
Andrew Dinh
8220d3664d Remove frozen_propq from ossl_method_store_st
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29265)
2025-12-15 00:34:38 +04:00
Andrew Dinh
cbb3db48ac Test that adding provider after freeze will fail
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29265)
2025-12-15 00:34:38 +04:00
Andrew Dinh
f5877a9d04 Add freeze flag to method store
Add unit test to check that after freeze, method store cannot be modified and still works as expected.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29265)
2025-12-15 00:34:37 +04:00
27 changed files with 2798 additions and 178 deletions

View file

@ -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));

View file

@ -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;
}

View file

@ -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);
}
/*

View file

@ -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);
}
/*

View file

@ -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)

View file

@ -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 {

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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);
}

View file

@ -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)

View file

@ -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)

View file

@ -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;
}

View file

@ -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);
}
/*

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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"),

View file

@ -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: