diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 043e456297..9b10a7f3fe 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -172,7 +172,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->digest = type; if (ctx->provctx == NULL) { - ctx->provctx = ctx->digest->newctx(); + ctx->provctx = ctx->digest->newctx(ossl_provider_ctx(type->prov)); if (ctx->provctx == NULL) { EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); return 0; diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 676eaabbc4..d7ba7ddb85 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -206,7 +206,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->cipher = cipher; if (ctx->provctx == NULL) { - ctx->provctx = ctx->cipher->newctx(); + ctx->provctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov)); if (ctx->provctx == NULL) { EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); return 0; diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 9f4c017045..2d74f6dbb3 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -54,6 +54,9 @@ struct ossl_provider_st { OSSL_provider_get_param_types_fn *get_param_types; OSSL_provider_get_params_fn *get_params; OSSL_provider_query_operation_fn *query_operation; + + /* Provider side data */ + void *provctx; }; DEFINE_STACK_OF(OSSL_PROVIDER) @@ -275,7 +278,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov) */ if (ref < 2 && prov->flag_initialized) { if (prov->teardown != NULL) - prov->teardown(); + prov->teardown(prov->provctx); prov->flag_initialized = 0; } @@ -401,7 +404,8 @@ static int provider_activate(OSSL_PROVIDER *prov) } if (prov->init_function == NULL - || !prov->init_function(prov, core_dispatch, &provider_dispatch)) { + || !prov->init_function(prov, core_dispatch, &provider_dispatch, + &prov->provctx)) { CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL); ERR_add_error_data(2, "name=", prov->name); DSO_free(prov->module); @@ -448,6 +452,11 @@ int ossl_provider_activate(OSSL_PROVIDER *prov) return 0; } +void *ossl_provider_ctx(const OSSL_PROVIDER *prov) +{ + return prov->provctx; +} + static int provider_forall_loaded(struct provider_store_st *store, int *found_activated, @@ -573,18 +582,20 @@ const char *ossl_provider_module_path(OSSL_PROVIDER *prov) void ossl_provider_teardown(const OSSL_PROVIDER *prov) { if (prov->teardown != NULL) - prov->teardown(); + prov->teardown(prov->provctx); } const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov) { - return prov->get_param_types == NULL ? NULL : prov->get_param_types(prov); + return prov->get_param_types == NULL + ? NULL : prov->get_param_types(prov->provctx); } int ossl_provider_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[]) { - return prov->get_params == NULL ? 0 : prov->get_params(prov, params); + return prov->get_params == NULL + ? 0 : prov->get_params(prov->provctx, params); } @@ -592,7 +603,7 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, int *no_cache) { - return prov->query_operation(prov, operation_id, no_cache); + return prov->query_operation(prov->provctx, operation_id, no_cache); } /*- diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index aa984c93b8..04535086be 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -5,7 +5,7 @@ ossl_provider_find, ossl_provider_new, ossl_provider_upref, ossl_provider_free, ossl_provider_add_module_location, ossl_provider_set_fallback, ossl_provider_activate, -ossl_provider_forall_loaded, +ossl_provider_ctx, ossl_provider_forall_loaded, ossl_provider_name, ossl_provider_dso, ossl_provider_module_name, ossl_provider_module_path, ossl_provider_teardown, ossl_provider_get_param_types, @@ -29,6 +29,9 @@ ossl_provider_get_params, ossl_provider_query_operation /* Load and initialize the Provider */ int ossl_provider_activate(OSSL_PROVIDER *prov); + /* Return pointer to the provider's context */ + void *ossl_provider_ctx(const OSSL_PROVIDER *prov); + /* Iterate over all loaded providers */ int ossl_provider_forall_loaded(OPENSSL_CTX *, int (*cb)(OSSL_PROVIDER *provider, @@ -121,6 +124,10 @@ be located in that module, and called. =back +ossl_provider_ctx() returns a context created by the provider. +Outside of the provider, it's completely opaque, but it needs to be +passed back to some of the provider functions. + ossl_provider_forall_loaded() iterates over all the currently "activated" providers, and calls C for each of them. If no providers have been "activated" yet, it tries to activate all diff --git a/include/internal/provider.h b/include/internal/provider.h index 4966cc2595..7b0531345d 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -45,6 +45,9 @@ int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name, */ int ossl_provider_activate(OSSL_PROVIDER *prov); +/* Return pointer to the provider's context */ +void *ossl_provider_ctx(const OSSL_PROVIDER *prov); + /* Iterate over all loaded providers */ int ossl_provider_forall_loaded(OPENSSL_CTX *, int (*cb)(OSSL_PROVIDER *provider, diff --git a/include/openssl/core.h b/include/openssl/core.h index 2855b6d385..cf4d3f41de 100644 --- a/include/openssl/core.h +++ b/include/openssl/core.h @@ -157,10 +157,14 @@ struct ossl_param_st { * |in| is the array of functions that the Core passes to the provider. * |out| will be the array of base functions that the provider passes * back to the Core. + * |provctx| a provider side context object, optionally created if the + * provider needs it. This value is passed to other provider + * functions, notably other context constructors. */ typedef int (OSSL_provider_init_fn)(const OSSL_PROVIDER *provider, const OSSL_DISPATCH *in, - const OSSL_DISPATCH **out); + const OSSL_DISPATCH **out, + void **provctx); # ifdef __VMS # pragma names save # pragma names uppercase,truncated diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 74b3fdfda9..8ce00c3e6f 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -60,17 +60,16 @@ OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_PROVIDER *prov, /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */ # define OSSL_FUNC_PROVIDER_TEARDOWN 1024 -OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void)) +OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx)) # define OSSL_FUNC_PROVIDER_GET_PARAM_TYPES 1025 OSSL_CORE_MAKE_FUNC(const OSSL_ITEM *, - provider_get_param_types,(const OSSL_PROVIDER *prov)) + provider_get_param_types,(void *provctx)) # define OSSL_FUNC_PROVIDER_GET_PARAMS 1026 -OSSL_CORE_MAKE_FUNC(int,provider_get_params,(const OSSL_PROVIDER *prov, +OSSL_CORE_MAKE_FUNC(int,provider_get_params,(void *provctx, const OSSL_PARAM params[])) # define OSSL_FUNC_PROVIDER_QUERY_OPERATION 1027 OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation, - (const OSSL_PROVIDER *, int operation_id, - const int *no_store)) + (void *provctx, int operation_id, const int *no_store)) /* Digests */ @@ -87,19 +86,20 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation, # define OSSL_FUNC_DIGEST_BLOCK_SIZE 9 -OSSL_CORE_MAKE_FUNC(void *, OP_digest_newctx, (void)) -OSSL_CORE_MAKE_FUNC(int, OP_digest_init, (void *vctx)) +OSSL_CORE_MAKE_FUNC(void *, OP_digest_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, OP_digest_init, (void *dctx)) OSSL_CORE_MAKE_FUNC(int, OP_digest_update, - (void *, const unsigned char *in, size_t inl)) + (void *dctx, const unsigned char *in, size_t inl)) OSSL_CORE_MAKE_FUNC(int, OP_digest_final, - (void *, unsigned char *out, size_t *outl, size_t outsz)) + (void *dctx, + unsigned char *out, size_t *outl, size_t outsz)) OSSL_CORE_MAKE_FUNC(int, OP_digest_digest, - (const unsigned char *in, size_t inl, unsigned char *out, - size_t *out_l, size_t outsz)) + (void *provctx, const unsigned char *in, size_t inl, + unsigned char *out, size_t *out_l, size_t outsz)) -OSSL_CORE_MAKE_FUNC(void, OP_digest_cleanctx, (void *vctx)) -OSSL_CORE_MAKE_FUNC(void, OP_digest_freectx, (void *vctx)) -OSSL_CORE_MAKE_FUNC(void *, OP_digest_dupctx, (void *vctx)) +OSSL_CORE_MAKE_FUNC(void, OP_digest_cleanctx, (void *dctx)) +OSSL_CORE_MAKE_FUNC(void, OP_digest_freectx, (void *dctx)) +OSSL_CORE_MAKE_FUNC(void *, OP_digest_dupctx, (void *dctx)) OSSL_CORE_MAKE_FUNC(size_t, OP_digest_size, (void)) OSSL_CORE_MAKE_FUNC(size_t, OP_digest_block_size, (void)) @@ -123,35 +123,37 @@ OSSL_CORE_MAKE_FUNC(size_t, OP_digest_block_size, (void)) # define OSSL_FUNC_CIPHER_CTX_GET_PARAMS 13 # define OSSL_FUNC_CIPHER_CTX_SET_PARAMS 14 -OSSL_CORE_MAKE_FUNC(void *, OP_cipher_newctx, (void)) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_encrypt_init, (void *vctx, +OSSL_CORE_MAKE_FUNC(void *, OP_cipher_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, OP_cipher_encrypt_init, (void *cctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen)) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_decrypt_init, (void *vctx, +OSSL_CORE_MAKE_FUNC(int, OP_cipher_decrypt_init, (void *cctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen)) OSSL_CORE_MAKE_FUNC(int, OP_cipher_update, - (void *, unsigned char *out, size_t *outl, size_t outsize, - const unsigned char *in, size_t inl)) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_final, - (void *, unsigned char *out, size_t *outl, size_t outsize)) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher, - (void *, + (void *cctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl)) -OSSL_CORE_MAKE_FUNC(void, OP_cipher_freectx, (void *vctx)) -OSSL_CORE_MAKE_FUNC(void *, OP_cipher_dupctx, (void *vctx)) +OSSL_CORE_MAKE_FUNC(int, OP_cipher_final, + (void *cctx, + unsigned char *out, size_t *outl, size_t outsize)) +OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher, + (void *cctx, + unsigned char *out, size_t *outl, size_t outsize, + const unsigned char *in, size_t inl)) +OSSL_CORE_MAKE_FUNC(void, OP_cipher_freectx, (void *cctx)) +OSSL_CORE_MAKE_FUNC(void *, OP_cipher_dupctx, (void *cctx)) OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_key_length, (void)) OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_iv_length, (void)) OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_block_size, (void)) OSSL_CORE_MAKE_FUNC(int, OP_cipher_get_params, (const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_get_params, (void *vctx, +OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_get_params, (void *cctx, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *vctx, +OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *cctx, const OSSL_PARAM params[])) diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c index 2e93461621..8d91ff4804 100644 --- a/providers/common/ciphers/aes.c +++ b/providers/common/ciphers/aes.c @@ -270,7 +270,7 @@ static int aes_cipher(void *vctx, #define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \ static OSSL_OP_cipher_newctx_fn aes_##len##_##lcmode##_newctx; \ - static void *aes_##len##_##lcmode##_newctx(void) \ + static void *aes_##len##_##lcmode##_newctx(void *provctx) \ { \ PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ \ diff --git a/providers/common/digests/sha2.c b/providers/common/digests/sha2.c index c9f616db68..5b219ab783 100644 --- a/providers/common/digests/sha2.c +++ b/providers/common/digests/sha2.c @@ -40,7 +40,7 @@ static int sha256_final(void *ctx, return 0; } -static void *sha256_newctx(void) +static void *sha256_newctx(void *provctx) { SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c index cba2dccf03..95b2abfdb9 100644 --- a/providers/default/defltprov.c +++ b/providers/default/defltprov.c @@ -106,7 +106,8 @@ OSSL_provider_init_fn ossl_default_provider_init; int ossl_default_provider_init(const OSSL_PROVIDER *provider, const OSSL_DISPATCH *in, - const OSSL_DISPATCH **out) + const OSSL_DISPATCH **out, + void **provctx) { for (; in->function_id != 0; in++) { switch (in->function_id) { diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index d3671b5a36..1b8316388b 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -78,7 +78,8 @@ static const OSSL_DISPATCH fips_dispatch_table[] = { int OSSL_provider_init(const OSSL_PROVIDER *provider, const OSSL_DISPATCH *in, - const OSSL_DISPATCH **out) + const OSSL_DISPATCH **out, + void **provctx) { for (; in->function_id != 0; in++) { switch (in->function_id) { diff --git a/providers/legacy/legacyprov.c b/providers/legacy/legacyprov.c index 48e89338d4..2d42229fea 100644 --- a/providers/legacy/legacyprov.c +++ b/providers/legacy/legacyprov.c @@ -80,7 +80,8 @@ static const OSSL_DISPATCH legacy_dispatch_table[] = { int OSSL_provider_init(const OSSL_PROVIDER *provider, const OSSL_DISPATCH *in, - const OSSL_DISPATCH **out) + const OSSL_DISPATCH **out, + void **provctx) { for (; in->function_id != 0; in++) { switch (in->function_id) { diff --git a/test/p_test.c b/test/p_test.c index bf13a0a070..93196f74c4 100644 --- a/test/p_test.c +++ b/test/p_test.c @@ -38,13 +38,18 @@ static const OSSL_ITEM p_param_types[] = { { 0, NULL } }; -static const OSSL_ITEM *p_get_param_types(const OSSL_PROVIDER *_) +/* This is a trick to ensure we define the provider functions correctly */ +static OSSL_provider_get_param_types_fn p_get_param_types; +static OSSL_provider_get_params_fn p_get_params; + +static const OSSL_ITEM *p_get_param_types(void *_) { return p_param_types; } -static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) +static int p_get_params(void *vprov, const OSSL_PARAM params[]) { + const OSSL_PROVIDER *prov = vprov; const OSSL_PARAM *p = params; int ok = 1; @@ -101,7 +106,8 @@ static const OSSL_DISPATCH p_test_table[] = { int OSSL_provider_init(const OSSL_PROVIDER *provider, const OSSL_DISPATCH *in, - const OSSL_DISPATCH **out) + const OSSL_DISPATCH **out, + void **provctx) { for (; in->function_id != 0; in++) { switch (in->function_id) { @@ -117,6 +123,9 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, } } + /* Because we use this in get_params, we need to pass it back */ + *provctx = (void *)provider; + *out = p_test_table; return 1; }