mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
Replumbing: give the possibility for the provider to create a context
OSSL_provider_init() gets another output parameter, holding a pointer to a provider side context. It's entirely up to the provider to define the context and what it's being used for. This pointer is passed back to other provider functions, typically the provider global get_params and set_params functions, and also the diverse algorithm context creators, and of course, the teardown function. With this, a provider can be instantiated more than once, or be re-loaded as the case may be, while maintaining instance state. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8848)
This commit is contained in:
parent
f79858ac4d
commit
a39eb84006
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -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<cb> for each of them.
|
||||
If no providers have been "activated" yet, it tries to activate all
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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[]))
|
||||
|
||||
|
||||
|
@ -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)); \
|
||||
\
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user