1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <assert.h> 11e1051a39Sopenharmony_ci#include <openssl/core.h> 12e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 13e1051a39Sopenharmony_ci#include <openssl/core_names.h> 14e1051a39Sopenharmony_ci#include <openssl/provider.h> 15e1051a39Sopenharmony_ci#include <openssl/params.h> 16e1051a39Sopenharmony_ci#include <openssl/opensslv.h> 17e1051a39Sopenharmony_ci#include "crypto/cryptlib.h" 18e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 19e1051a39Sopenharmony_ci#include "crypto/decoder.h" /* ossl_decoder_store_cache_flush */ 20e1051a39Sopenharmony_ci#include "crypto/encoder.h" /* ossl_encoder_store_cache_flush */ 21e1051a39Sopenharmony_ci#include "crypto/store.h" /* ossl_store_loader_store_cache_flush */ 22e1051a39Sopenharmony_ci#endif 23e1051a39Sopenharmony_ci#include "crypto/evp.h" /* evp_method_store_cache_flush */ 24e1051a39Sopenharmony_ci#include "crypto/rand.h" 25e1051a39Sopenharmony_ci#include "internal/nelem.h" 26e1051a39Sopenharmony_ci#include "internal/thread_once.h" 27e1051a39Sopenharmony_ci#include "internal/provider.h" 28e1051a39Sopenharmony_ci#include "internal/refcount.h" 29e1051a39Sopenharmony_ci#include "internal/bio.h" 30e1051a39Sopenharmony_ci#include "internal/core.h" 31e1051a39Sopenharmony_ci#include "provider_local.h" 32e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 33e1051a39Sopenharmony_ci# include <openssl/self_test.h> 34e1051a39Sopenharmony_ci#endif 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci/* 37e1051a39Sopenharmony_ci * This file defines and uses a number of different structures: 38e1051a39Sopenharmony_ci * 39e1051a39Sopenharmony_ci * OSSL_PROVIDER (provider_st): Used to represent all information related to a 40e1051a39Sopenharmony_ci * single instance of a provider. 41e1051a39Sopenharmony_ci * 42e1051a39Sopenharmony_ci * provider_store_st: Holds information about the collection of providers that 43e1051a39Sopenharmony_ci * are available within the current library context (OSSL_LIB_CTX). It also 44e1051a39Sopenharmony_ci * holds configuration information about providers that could be loaded at some 45e1051a39Sopenharmony_ci * future point. 46e1051a39Sopenharmony_ci * 47e1051a39Sopenharmony_ci * OSSL_PROVIDER_CHILD_CB: An instance of this structure holds the callbacks 48e1051a39Sopenharmony_ci * that have been registered for a child library context and the associated 49e1051a39Sopenharmony_ci * provider that registered those callbacks. 50e1051a39Sopenharmony_ci * 51e1051a39Sopenharmony_ci * Where a child library context exists then it has its own instance of the 52e1051a39Sopenharmony_ci * provider store. Each provider that exists in the parent provider store, has 53e1051a39Sopenharmony_ci * an associated child provider in the child library context's provider store. 54e1051a39Sopenharmony_ci * As providers get activated or deactivated this needs to be mirrored in the 55e1051a39Sopenharmony_ci * associated child providers. 56e1051a39Sopenharmony_ci * 57e1051a39Sopenharmony_ci * LOCKING 58e1051a39Sopenharmony_ci * ======= 59e1051a39Sopenharmony_ci * 60e1051a39Sopenharmony_ci * There are a number of different locks used in this file and it is important 61e1051a39Sopenharmony_ci * to understand how they should be used in order to avoid deadlocks. 62e1051a39Sopenharmony_ci * 63e1051a39Sopenharmony_ci * Fields within a structure can often be "write once" on creation, and then 64e1051a39Sopenharmony_ci * "read many". Creation of a structure is done by a single thread, and 65e1051a39Sopenharmony_ci * therefore no lock is required for the "write once/read many" fields. It is 66e1051a39Sopenharmony_ci * safe for multiple threads to read these fields without a lock, because they 67e1051a39Sopenharmony_ci * will never be changed. 68e1051a39Sopenharmony_ci * 69e1051a39Sopenharmony_ci * However some fields may be changed after a structure has been created and 70e1051a39Sopenharmony_ci * shared between multiple threads. Where this is the case a lock is required. 71e1051a39Sopenharmony_ci * 72e1051a39Sopenharmony_ci * The locks available are: 73e1051a39Sopenharmony_ci * 74e1051a39Sopenharmony_ci * The provider flag_lock: Used to control updates to the various provider 75e1051a39Sopenharmony_ci * "flags" (flag_initialized, flag_activated, flag_fallback) and associated 76e1051a39Sopenharmony_ci * "counts" (activatecnt). 77e1051a39Sopenharmony_ci * 78e1051a39Sopenharmony_ci * The provider refcnt_lock: Only ever used to control updates to the provider 79e1051a39Sopenharmony_ci * refcnt value. 80e1051a39Sopenharmony_ci * 81e1051a39Sopenharmony_ci * The provider optbits_lock: Used to control access to the provider's 82e1051a39Sopenharmony_ci * operation_bits and operation_bits_sz fields. 83e1051a39Sopenharmony_ci * 84e1051a39Sopenharmony_ci * The store default_path_lock: Used to control access to the provider store's 85e1051a39Sopenharmony_ci * default search path value (default_path) 86e1051a39Sopenharmony_ci * 87e1051a39Sopenharmony_ci * The store lock: Used to control the stack of provider's held within the 88e1051a39Sopenharmony_ci * provider store, as well as the stack of registered child provider callbacks. 89e1051a39Sopenharmony_ci * 90e1051a39Sopenharmony_ci * As a general rule-of-thumb it is best to: 91e1051a39Sopenharmony_ci * - keep the scope of the code that is protected by a lock to the absolute 92e1051a39Sopenharmony_ci * minimum possible; 93e1051a39Sopenharmony_ci * - try to keep the scope of the lock to within a single function (i.e. avoid 94e1051a39Sopenharmony_ci * making calls to other functions while holding a lock); 95e1051a39Sopenharmony_ci * - try to only ever hold one lock at a time. 96e1051a39Sopenharmony_ci * 97e1051a39Sopenharmony_ci * Unfortunately, it is not always possible to stick to the above guidelines. 98e1051a39Sopenharmony_ci * Where they are not adhered to there is always a danger of inadvertently 99e1051a39Sopenharmony_ci * introducing the possibility of deadlock. The following rules MUST be adhered 100e1051a39Sopenharmony_ci * to in order to avoid that: 101e1051a39Sopenharmony_ci * - Holding multiple locks at the same time is only allowed for the 102e1051a39Sopenharmony_ci * provider store lock, the provider flag_lock and the provider refcnt_lock. 103e1051a39Sopenharmony_ci * - When holding multiple locks they must be acquired in the following order of 104e1051a39Sopenharmony_ci * precedence: 105e1051a39Sopenharmony_ci * 1) provider store lock 106e1051a39Sopenharmony_ci * 2) provider flag_lock 107e1051a39Sopenharmony_ci * 3) provider refcnt_lock 108e1051a39Sopenharmony_ci * - When releasing locks they must be released in the reverse order to which 109e1051a39Sopenharmony_ci * they were acquired 110e1051a39Sopenharmony_ci * - No locks may be held when making an upcall. NOTE: Some common functions 111e1051a39Sopenharmony_ci * can make upcalls as part of their normal operation. If you need to call 112e1051a39Sopenharmony_ci * some other function while holding a lock make sure you know whether it 113e1051a39Sopenharmony_ci * will make any upcalls or not. For example ossl_provider_up_ref() can call 114e1051a39Sopenharmony_ci * ossl_provider_up_ref_parent() which can call the c_prov_up_ref() upcall. 115e1051a39Sopenharmony_ci * - It is permissible to hold the store and flag locks when calling child 116e1051a39Sopenharmony_ci * provider callbacks. No other locks may be held during such callbacks. 117e1051a39Sopenharmony_ci */ 118e1051a39Sopenharmony_ci 119e1051a39Sopenharmony_cistatic OSSL_PROVIDER *provider_new(const char *name, 120e1051a39Sopenharmony_ci OSSL_provider_init_fn *init_function, 121e1051a39Sopenharmony_ci STACK_OF(INFOPAIR) *parameters); 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci/*- 124e1051a39Sopenharmony_ci * Provider Object structure 125e1051a39Sopenharmony_ci * ========================= 126e1051a39Sopenharmony_ci */ 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 129e1051a39Sopenharmony_citypedef struct { 130e1051a39Sopenharmony_ci OSSL_PROVIDER *prov; 131e1051a39Sopenharmony_ci int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); 132e1051a39Sopenharmony_ci int (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); 133e1051a39Sopenharmony_ci int (*global_props_cb)(const char *props, void *cbdata); 134e1051a39Sopenharmony_ci void *cbdata; 135e1051a39Sopenharmony_ci} OSSL_PROVIDER_CHILD_CB; 136e1051a39Sopenharmony_ciDEFINE_STACK_OF(OSSL_PROVIDER_CHILD_CB) 137e1051a39Sopenharmony_ci#endif 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_cistruct provider_store_st; /* Forward declaration */ 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_cistruct ossl_provider_st { 142e1051a39Sopenharmony_ci /* Flag bits */ 143e1051a39Sopenharmony_ci unsigned int flag_initialized:1; 144e1051a39Sopenharmony_ci unsigned int flag_activated:1; 145e1051a39Sopenharmony_ci unsigned int flag_fallback:1; /* Can be used as fallback */ 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci /* Getting and setting the flags require synchronization */ 148e1051a39Sopenharmony_ci CRYPTO_RWLOCK *flag_lock; 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci /* OpenSSL library side data */ 151e1051a39Sopenharmony_ci CRYPTO_REF_COUNT refcnt; 152e1051a39Sopenharmony_ci CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */ 153e1051a39Sopenharmony_ci int activatecnt; 154e1051a39Sopenharmony_ci char *name; 155e1051a39Sopenharmony_ci char *path; 156e1051a39Sopenharmony_ci DSO *module; 157e1051a39Sopenharmony_ci OSSL_provider_init_fn *init_function; 158e1051a39Sopenharmony_ci STACK_OF(INFOPAIR) *parameters; 159e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; /* The library context this instance is in */ 160e1051a39Sopenharmony_ci struct provider_store_st *store; /* The store this instance belongs to */ 161e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 162e1051a39Sopenharmony_ci /* 163e1051a39Sopenharmony_ci * In the FIPS module inner provider, this isn't needed, since the 164e1051a39Sopenharmony_ci * error upcalls are always direct calls to the outer provider. 165e1051a39Sopenharmony_ci */ 166e1051a39Sopenharmony_ci int error_lib; /* ERR library number, one for each provider */ 167e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_ERR 168e1051a39Sopenharmony_ci ERR_STRING_DATA *error_strings; /* Copy of what the provider gives us */ 169e1051a39Sopenharmony_ci# endif 170e1051a39Sopenharmony_ci#endif 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci /* Provider side functions */ 173e1051a39Sopenharmony_ci OSSL_FUNC_provider_teardown_fn *teardown; 174e1051a39Sopenharmony_ci OSSL_FUNC_provider_gettable_params_fn *gettable_params; 175e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_params_fn *get_params; 176e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_capabilities_fn *get_capabilities; 177e1051a39Sopenharmony_ci OSSL_FUNC_provider_self_test_fn *self_test; 178e1051a39Sopenharmony_ci OSSL_FUNC_provider_query_operation_fn *query_operation; 179e1051a39Sopenharmony_ci OSSL_FUNC_provider_unquery_operation_fn *unquery_operation; 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci /* 182e1051a39Sopenharmony_ci * Cache of bit to indicate of query_operation() has been called on 183e1051a39Sopenharmony_ci * a specific operation or not. 184e1051a39Sopenharmony_ci */ 185e1051a39Sopenharmony_ci unsigned char *operation_bits; 186e1051a39Sopenharmony_ci size_t operation_bits_sz; 187e1051a39Sopenharmony_ci CRYPTO_RWLOCK *opbits_lock; 188e1051a39Sopenharmony_ci 189e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 190e1051a39Sopenharmony_ci /* Whether this provider is the child of some other provider */ 191e1051a39Sopenharmony_ci const OSSL_CORE_HANDLE *handle; 192e1051a39Sopenharmony_ci unsigned int ischild:1; 193e1051a39Sopenharmony_ci#endif 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci /* Provider side data */ 196e1051a39Sopenharmony_ci void *provctx; 197e1051a39Sopenharmony_ci const OSSL_DISPATCH *dispatch; 198e1051a39Sopenharmony_ci}; 199e1051a39Sopenharmony_ciDEFINE_STACK_OF(OSSL_PROVIDER) 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_cistatic int ossl_provider_cmp(const OSSL_PROVIDER * const *a, 202e1051a39Sopenharmony_ci const OSSL_PROVIDER * const *b) 203e1051a39Sopenharmony_ci{ 204e1051a39Sopenharmony_ci return strcmp((*a)->name, (*b)->name); 205e1051a39Sopenharmony_ci} 206e1051a39Sopenharmony_ci 207e1051a39Sopenharmony_ci/*- 208e1051a39Sopenharmony_ci * Provider Object store 209e1051a39Sopenharmony_ci * ===================== 210e1051a39Sopenharmony_ci * 211e1051a39Sopenharmony_ci * The Provider Object store is a library context object, and therefore needs 212e1051a39Sopenharmony_ci * an index. 213e1051a39Sopenharmony_ci */ 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_cistruct provider_store_st { 216e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 217e1051a39Sopenharmony_ci STACK_OF(OSSL_PROVIDER) *providers; 218e1051a39Sopenharmony_ci STACK_OF(OSSL_PROVIDER_CHILD_CB) *child_cbs; 219e1051a39Sopenharmony_ci CRYPTO_RWLOCK *default_path_lock; 220e1051a39Sopenharmony_ci CRYPTO_RWLOCK *lock; 221e1051a39Sopenharmony_ci char *default_path; 222e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO *provinfo; 223e1051a39Sopenharmony_ci size_t numprovinfo; 224e1051a39Sopenharmony_ci size_t provinfosz; 225e1051a39Sopenharmony_ci unsigned int use_fallbacks:1; 226e1051a39Sopenharmony_ci unsigned int freeing:1; 227e1051a39Sopenharmony_ci}; 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci/* 230e1051a39Sopenharmony_ci * provider_deactivate_free() is a wrapper around ossl_provider_deactivate() 231e1051a39Sopenharmony_ci * and ossl_provider_free(), called as needed. 232e1051a39Sopenharmony_ci * Since this is only called when the provider store is being emptied, we 233e1051a39Sopenharmony_ci * don't need to care about any lock. 234e1051a39Sopenharmony_ci */ 235e1051a39Sopenharmony_cistatic void provider_deactivate_free(OSSL_PROVIDER *prov) 236e1051a39Sopenharmony_ci{ 237e1051a39Sopenharmony_ci if (prov->flag_activated) 238e1051a39Sopenharmony_ci ossl_provider_deactivate(prov, 1); 239e1051a39Sopenharmony_ci ossl_provider_free(prov); 240e1051a39Sopenharmony_ci} 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 243e1051a39Sopenharmony_cistatic void ossl_provider_child_cb_free(OSSL_PROVIDER_CHILD_CB *cb) 244e1051a39Sopenharmony_ci{ 245e1051a39Sopenharmony_ci OPENSSL_free(cb); 246e1051a39Sopenharmony_ci} 247e1051a39Sopenharmony_ci#endif 248e1051a39Sopenharmony_ci 249e1051a39Sopenharmony_cistatic void infopair_free(INFOPAIR *pair) 250e1051a39Sopenharmony_ci{ 251e1051a39Sopenharmony_ci OPENSSL_free(pair->name); 252e1051a39Sopenharmony_ci OPENSSL_free(pair->value); 253e1051a39Sopenharmony_ci OPENSSL_free(pair); 254e1051a39Sopenharmony_ci} 255e1051a39Sopenharmony_ci 256e1051a39Sopenharmony_cistatic INFOPAIR *infopair_copy(const INFOPAIR *src) 257e1051a39Sopenharmony_ci{ 258e1051a39Sopenharmony_ci INFOPAIR *dest = OPENSSL_zalloc(sizeof(*dest)); 259e1051a39Sopenharmony_ci 260e1051a39Sopenharmony_ci if (dest == NULL) 261e1051a39Sopenharmony_ci return NULL; 262e1051a39Sopenharmony_ci if (src->name != NULL) { 263e1051a39Sopenharmony_ci dest->name = OPENSSL_strdup(src->name); 264e1051a39Sopenharmony_ci if (dest->name == NULL) 265e1051a39Sopenharmony_ci goto err; 266e1051a39Sopenharmony_ci } 267e1051a39Sopenharmony_ci if (src->value != NULL) { 268e1051a39Sopenharmony_ci dest->value = OPENSSL_strdup(src->value); 269e1051a39Sopenharmony_ci if (dest->value == NULL) 270e1051a39Sopenharmony_ci goto err; 271e1051a39Sopenharmony_ci } 272e1051a39Sopenharmony_ci return dest; 273e1051a39Sopenharmony_ci err: 274e1051a39Sopenharmony_ci OPENSSL_free(dest->name); 275e1051a39Sopenharmony_ci OPENSSL_free(dest); 276e1051a39Sopenharmony_ci return NULL; 277e1051a39Sopenharmony_ci} 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_civoid ossl_provider_info_clear(OSSL_PROVIDER_INFO *info) 280e1051a39Sopenharmony_ci{ 281e1051a39Sopenharmony_ci OPENSSL_free(info->name); 282e1051a39Sopenharmony_ci OPENSSL_free(info->path); 283e1051a39Sopenharmony_ci sk_INFOPAIR_pop_free(info->parameters, infopair_free); 284e1051a39Sopenharmony_ci} 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_cistatic void provider_store_free(void *vstore) 287e1051a39Sopenharmony_ci{ 288e1051a39Sopenharmony_ci struct provider_store_st *store = vstore; 289e1051a39Sopenharmony_ci size_t i; 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci if (store == NULL) 292e1051a39Sopenharmony_ci return; 293e1051a39Sopenharmony_ci store->freeing = 1; 294e1051a39Sopenharmony_ci OPENSSL_free(store->default_path); 295e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_pop_free(store->providers, provider_deactivate_free); 296e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 297e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_CHILD_CB_pop_free(store->child_cbs, 298e1051a39Sopenharmony_ci ossl_provider_child_cb_free); 299e1051a39Sopenharmony_ci#endif 300e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(store->default_path_lock); 301e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(store->lock); 302e1051a39Sopenharmony_ci for (i = 0; i < store->numprovinfo; i++) 303e1051a39Sopenharmony_ci ossl_provider_info_clear(&store->provinfo[i]); 304e1051a39Sopenharmony_ci OPENSSL_free(store->provinfo); 305e1051a39Sopenharmony_ci OPENSSL_free(store); 306e1051a39Sopenharmony_ci} 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_cistatic void *provider_store_new(OSSL_LIB_CTX *ctx) 309e1051a39Sopenharmony_ci{ 310e1051a39Sopenharmony_ci struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store)); 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci if (store == NULL 313e1051a39Sopenharmony_ci || (store->providers = sk_OSSL_PROVIDER_new(ossl_provider_cmp)) == NULL 314e1051a39Sopenharmony_ci || (store->default_path_lock = CRYPTO_THREAD_lock_new()) == NULL 315e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 316e1051a39Sopenharmony_ci || (store->child_cbs = sk_OSSL_PROVIDER_CHILD_CB_new_null()) == NULL 317e1051a39Sopenharmony_ci#endif 318e1051a39Sopenharmony_ci || (store->lock = CRYPTO_THREAD_lock_new()) == NULL) { 319e1051a39Sopenharmony_ci provider_store_free(store); 320e1051a39Sopenharmony_ci return NULL; 321e1051a39Sopenharmony_ci } 322e1051a39Sopenharmony_ci store->libctx = ctx; 323e1051a39Sopenharmony_ci store->use_fallbacks = 1; 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci return store; 326e1051a39Sopenharmony_ci} 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_cistatic const OSSL_LIB_CTX_METHOD provider_store_method = { 329e1051a39Sopenharmony_ci /* Needs to be freed before the child provider data is freed */ 330e1051a39Sopenharmony_ci OSSL_LIB_CTX_METHOD_PRIORITY_1, 331e1051a39Sopenharmony_ci provider_store_new, 332e1051a39Sopenharmony_ci provider_store_free, 333e1051a39Sopenharmony_ci}; 334e1051a39Sopenharmony_ci 335e1051a39Sopenharmony_cistatic struct provider_store_st *get_provider_store(OSSL_LIB_CTX *libctx) 336e1051a39Sopenharmony_ci{ 337e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 338e1051a39Sopenharmony_ci 339e1051a39Sopenharmony_ci store = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_STORE_INDEX, 340e1051a39Sopenharmony_ci &provider_store_method); 341e1051a39Sopenharmony_ci if (store == NULL) 342e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 343e1051a39Sopenharmony_ci return store; 344e1051a39Sopenharmony_ci} 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ciint ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx) 347e1051a39Sopenharmony_ci{ 348e1051a39Sopenharmony_ci struct provider_store_st *store; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) != NULL) { 351e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 352e1051a39Sopenharmony_ci return 0; 353e1051a39Sopenharmony_ci store->use_fallbacks = 0; 354e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 355e1051a39Sopenharmony_ci return 1; 356e1051a39Sopenharmony_ci } 357e1051a39Sopenharmony_ci return 0; 358e1051a39Sopenharmony_ci} 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci#define BUILTINS_BLOCK_SIZE 10 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ciint ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx, 363e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO *entry) 364e1051a39Sopenharmony_ci{ 365e1051a39Sopenharmony_ci struct provider_store_st *store = get_provider_store(libctx); 366e1051a39Sopenharmony_ci int ret = 0; 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci if (entry->name == NULL) { 369e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); 370e1051a39Sopenharmony_ci return 0; 371e1051a39Sopenharmony_ci } 372e1051a39Sopenharmony_ci 373e1051a39Sopenharmony_ci if (store == NULL) { 374e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 375e1051a39Sopenharmony_ci return 0; 376e1051a39Sopenharmony_ci } 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 379e1051a39Sopenharmony_ci return 0; 380e1051a39Sopenharmony_ci if (store->provinfosz == 0) { 381e1051a39Sopenharmony_ci store->provinfo = OPENSSL_zalloc(sizeof(*store->provinfo) 382e1051a39Sopenharmony_ci * BUILTINS_BLOCK_SIZE); 383e1051a39Sopenharmony_ci if (store->provinfo == NULL) { 384e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 385e1051a39Sopenharmony_ci goto err; 386e1051a39Sopenharmony_ci } 387e1051a39Sopenharmony_ci store->provinfosz = BUILTINS_BLOCK_SIZE; 388e1051a39Sopenharmony_ci } else if (store->numprovinfo == store->provinfosz) { 389e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO *tmpbuiltins; 390e1051a39Sopenharmony_ci size_t newsz = store->provinfosz + BUILTINS_BLOCK_SIZE; 391e1051a39Sopenharmony_ci 392e1051a39Sopenharmony_ci tmpbuiltins = OPENSSL_realloc(store->provinfo, 393e1051a39Sopenharmony_ci sizeof(*store->provinfo) * newsz); 394e1051a39Sopenharmony_ci if (tmpbuiltins == NULL) { 395e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 396e1051a39Sopenharmony_ci goto err; 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci store->provinfo = tmpbuiltins; 399e1051a39Sopenharmony_ci store->provinfosz = newsz; 400e1051a39Sopenharmony_ci } 401e1051a39Sopenharmony_ci store->provinfo[store->numprovinfo] = *entry; 402e1051a39Sopenharmony_ci store->numprovinfo++; 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci ret = 1; 405e1051a39Sopenharmony_ci err: 406e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 407e1051a39Sopenharmony_ci return ret; 408e1051a39Sopenharmony_ci} 409e1051a39Sopenharmony_ci 410e1051a39Sopenharmony_ciOSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, 411e1051a39Sopenharmony_ci int noconfig) 412e1051a39Sopenharmony_ci{ 413e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 414e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL; 415e1051a39Sopenharmony_ci 416e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) != NULL) { 417e1051a39Sopenharmony_ci OSSL_PROVIDER tmpl = { 0, }; 418e1051a39Sopenharmony_ci int i; 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 421e1051a39Sopenharmony_ci /* 422e1051a39Sopenharmony_ci * Make sure any providers are loaded from config before we try to find 423e1051a39Sopenharmony_ci * them. 424e1051a39Sopenharmony_ci */ 425e1051a39Sopenharmony_ci if (!noconfig) { 426e1051a39Sopenharmony_ci if (ossl_lib_ctx_is_default(libctx)) 427e1051a39Sopenharmony_ci OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); 428e1051a39Sopenharmony_ci } 429e1051a39Sopenharmony_ci#endif 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci tmpl.name = (char *)name; 432e1051a39Sopenharmony_ci /* 433e1051a39Sopenharmony_ci * A "find" operation can sort the stack, and therefore a write lock is 434e1051a39Sopenharmony_ci * required. 435e1051a39Sopenharmony_ci */ 436e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 437e1051a39Sopenharmony_ci return NULL; 438e1051a39Sopenharmony_ci if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) != -1) 439e1051a39Sopenharmony_ci prov = sk_OSSL_PROVIDER_value(store->providers, i); 440e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 441e1051a39Sopenharmony_ci if (prov != NULL && !ossl_provider_up_ref(prov)) 442e1051a39Sopenharmony_ci prov = NULL; 443e1051a39Sopenharmony_ci } 444e1051a39Sopenharmony_ci 445e1051a39Sopenharmony_ci return prov; 446e1051a39Sopenharmony_ci} 447e1051a39Sopenharmony_ci 448e1051a39Sopenharmony_ci/*- 449e1051a39Sopenharmony_ci * Provider Object methods 450e1051a39Sopenharmony_ci * ======================= 451e1051a39Sopenharmony_ci */ 452e1051a39Sopenharmony_ci 453e1051a39Sopenharmony_cistatic OSSL_PROVIDER *provider_new(const char *name, 454e1051a39Sopenharmony_ci OSSL_provider_init_fn *init_function, 455e1051a39Sopenharmony_ci STACK_OF(INFOPAIR) *parameters) 456e1051a39Sopenharmony_ci{ 457e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL; 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_ci if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL 460e1051a39Sopenharmony_ci#ifndef HAVE_ATOMICS 461e1051a39Sopenharmony_ci || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL 462e1051a39Sopenharmony_ci#endif 463e1051a39Sopenharmony_ci ) { 464e1051a39Sopenharmony_ci OPENSSL_free(prov); 465e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 466e1051a39Sopenharmony_ci return NULL; 467e1051a39Sopenharmony_ci } 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ci prov->refcnt = 1; /* 1 One reference to be returned */ 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL 472e1051a39Sopenharmony_ci || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL 473e1051a39Sopenharmony_ci || (prov->name = OPENSSL_strdup(name)) == NULL 474e1051a39Sopenharmony_ci || (prov->parameters = sk_INFOPAIR_deep_copy(parameters, 475e1051a39Sopenharmony_ci infopair_copy, 476e1051a39Sopenharmony_ci infopair_free)) == NULL) { 477e1051a39Sopenharmony_ci ossl_provider_free(prov); 478e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 479e1051a39Sopenharmony_ci return NULL; 480e1051a39Sopenharmony_ci } 481e1051a39Sopenharmony_ci 482e1051a39Sopenharmony_ci prov->init_function = init_function; 483e1051a39Sopenharmony_ci 484e1051a39Sopenharmony_ci return prov; 485e1051a39Sopenharmony_ci} 486e1051a39Sopenharmony_ci 487e1051a39Sopenharmony_ciint ossl_provider_up_ref(OSSL_PROVIDER *prov) 488e1051a39Sopenharmony_ci{ 489e1051a39Sopenharmony_ci int ref = 0; 490e1051a39Sopenharmony_ci 491e1051a39Sopenharmony_ci if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) 492e1051a39Sopenharmony_ci return 0; 493e1051a39Sopenharmony_ci 494e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 495e1051a39Sopenharmony_ci if (prov->ischild) { 496e1051a39Sopenharmony_ci if (!ossl_provider_up_ref_parent(prov, 0)) { 497e1051a39Sopenharmony_ci ossl_provider_free(prov); 498e1051a39Sopenharmony_ci return 0; 499e1051a39Sopenharmony_ci } 500e1051a39Sopenharmony_ci } 501e1051a39Sopenharmony_ci#endif 502e1051a39Sopenharmony_ci 503e1051a39Sopenharmony_ci return ref; 504e1051a39Sopenharmony_ci} 505e1051a39Sopenharmony_ci 506e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 507e1051a39Sopenharmony_cistatic int provider_up_ref_intern(OSSL_PROVIDER *prov, int activate) 508e1051a39Sopenharmony_ci{ 509e1051a39Sopenharmony_ci if (activate) 510e1051a39Sopenharmony_ci return ossl_provider_activate(prov, 1, 0); 511e1051a39Sopenharmony_ci 512e1051a39Sopenharmony_ci return ossl_provider_up_ref(prov); 513e1051a39Sopenharmony_ci} 514e1051a39Sopenharmony_ci 515e1051a39Sopenharmony_cistatic int provider_free_intern(OSSL_PROVIDER *prov, int deactivate) 516e1051a39Sopenharmony_ci{ 517e1051a39Sopenharmony_ci if (deactivate) 518e1051a39Sopenharmony_ci return ossl_provider_deactivate(prov, 1); 519e1051a39Sopenharmony_ci 520e1051a39Sopenharmony_ci ossl_provider_free(prov); 521e1051a39Sopenharmony_ci return 1; 522e1051a39Sopenharmony_ci} 523e1051a39Sopenharmony_ci#endif 524e1051a39Sopenharmony_ci 525e1051a39Sopenharmony_ci/* 526e1051a39Sopenharmony_ci * We assume that the requested provider does not already exist in the store. 527e1051a39Sopenharmony_ci * The caller should check. If it does exist then adding it to the store later 528e1051a39Sopenharmony_ci * will fail. 529e1051a39Sopenharmony_ci */ 530e1051a39Sopenharmony_ciOSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, 531e1051a39Sopenharmony_ci OSSL_provider_init_fn *init_function, 532e1051a39Sopenharmony_ci int noconfig) 533e1051a39Sopenharmony_ci{ 534e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 535e1051a39Sopenharmony_ci OSSL_PROVIDER_INFO template; 536e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL; 537e1051a39Sopenharmony_ci 538e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) == NULL) 539e1051a39Sopenharmony_ci return NULL; 540e1051a39Sopenharmony_ci 541e1051a39Sopenharmony_ci memset(&template, 0, sizeof(template)); 542e1051a39Sopenharmony_ci if (init_function == NULL) { 543e1051a39Sopenharmony_ci const OSSL_PROVIDER_INFO *p; 544e1051a39Sopenharmony_ci size_t i; 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_ci /* Check if this is a predefined builtin provider */ 547e1051a39Sopenharmony_ci for (p = ossl_predefined_providers; p->name != NULL; p++) { 548e1051a39Sopenharmony_ci if (strcmp(p->name, name) == 0) { 549e1051a39Sopenharmony_ci template = *p; 550e1051a39Sopenharmony_ci break; 551e1051a39Sopenharmony_ci } 552e1051a39Sopenharmony_ci } 553e1051a39Sopenharmony_ci if (p->name == NULL) { 554e1051a39Sopenharmony_ci /* Check if this is a user added builtin provider */ 555e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 556e1051a39Sopenharmony_ci return NULL; 557e1051a39Sopenharmony_ci for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) { 558e1051a39Sopenharmony_ci if (strcmp(p->name, name) == 0) { 559e1051a39Sopenharmony_ci template = *p; 560e1051a39Sopenharmony_ci break; 561e1051a39Sopenharmony_ci } 562e1051a39Sopenharmony_ci } 563e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 564e1051a39Sopenharmony_ci } 565e1051a39Sopenharmony_ci } else { 566e1051a39Sopenharmony_ci template.init = init_function; 567e1051a39Sopenharmony_ci } 568e1051a39Sopenharmony_ci 569e1051a39Sopenharmony_ci /* provider_new() generates an error, so no need here */ 570e1051a39Sopenharmony_ci if ((prov = provider_new(name, template.init, template.parameters)) == NULL) 571e1051a39Sopenharmony_ci return NULL; 572e1051a39Sopenharmony_ci 573e1051a39Sopenharmony_ci prov->libctx = libctx; 574e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 575e1051a39Sopenharmony_ci prov->error_lib = ERR_get_next_error_library(); 576e1051a39Sopenharmony_ci#endif 577e1051a39Sopenharmony_ci 578e1051a39Sopenharmony_ci /* 579e1051a39Sopenharmony_ci * At this point, the provider is only partially "loaded". To be 580e1051a39Sopenharmony_ci * fully "loaded", ossl_provider_activate() must also be called and it must 581e1051a39Sopenharmony_ci * then be added to the provider store. 582e1051a39Sopenharmony_ci */ 583e1051a39Sopenharmony_ci 584e1051a39Sopenharmony_ci return prov; 585e1051a39Sopenharmony_ci} 586e1051a39Sopenharmony_ci 587e1051a39Sopenharmony_ci/* Assumes that the store lock is held */ 588e1051a39Sopenharmony_cistatic int create_provider_children(OSSL_PROVIDER *prov) 589e1051a39Sopenharmony_ci{ 590e1051a39Sopenharmony_ci int ret = 1; 591e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 592e1051a39Sopenharmony_ci struct provider_store_st *store = prov->store; 593e1051a39Sopenharmony_ci OSSL_PROVIDER_CHILD_CB *child_cb; 594e1051a39Sopenharmony_ci int i, max; 595e1051a39Sopenharmony_ci 596e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); 597e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 598e1051a39Sopenharmony_ci /* 599e1051a39Sopenharmony_ci * This is newly activated (activatecnt == 1), so we need to 600e1051a39Sopenharmony_ci * create child providers as necessary. 601e1051a39Sopenharmony_ci */ 602e1051a39Sopenharmony_ci child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); 603e1051a39Sopenharmony_ci ret &= child_cb->create_cb((OSSL_CORE_HANDLE *)prov, child_cb->cbdata); 604e1051a39Sopenharmony_ci } 605e1051a39Sopenharmony_ci#endif 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ci return ret; 608e1051a39Sopenharmony_ci} 609e1051a39Sopenharmony_ci 610e1051a39Sopenharmony_ciint ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov, 611e1051a39Sopenharmony_ci int retain_fallbacks) 612e1051a39Sopenharmony_ci{ 613e1051a39Sopenharmony_ci struct provider_store_st *store; 614e1051a39Sopenharmony_ci int idx; 615e1051a39Sopenharmony_ci OSSL_PROVIDER tmpl = { 0, }; 616e1051a39Sopenharmony_ci OSSL_PROVIDER *actualtmp = NULL; 617e1051a39Sopenharmony_ci 618e1051a39Sopenharmony_ci if (actualprov != NULL) 619e1051a39Sopenharmony_ci *actualprov = NULL; 620e1051a39Sopenharmony_ci 621e1051a39Sopenharmony_ci if ((store = get_provider_store(prov->libctx)) == NULL) 622e1051a39Sopenharmony_ci return 0; 623e1051a39Sopenharmony_ci 624e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 625e1051a39Sopenharmony_ci return 0; 626e1051a39Sopenharmony_ci 627e1051a39Sopenharmony_ci tmpl.name = (char *)prov->name; 628e1051a39Sopenharmony_ci idx = sk_OSSL_PROVIDER_find(store->providers, &tmpl); 629e1051a39Sopenharmony_ci if (idx == -1) 630e1051a39Sopenharmony_ci actualtmp = prov; 631e1051a39Sopenharmony_ci else 632e1051a39Sopenharmony_ci actualtmp = sk_OSSL_PROVIDER_value(store->providers, idx); 633e1051a39Sopenharmony_ci 634e1051a39Sopenharmony_ci if (idx == -1) { 635e1051a39Sopenharmony_ci if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) 636e1051a39Sopenharmony_ci goto err; 637e1051a39Sopenharmony_ci prov->store = store; 638e1051a39Sopenharmony_ci if (!create_provider_children(prov)) { 639e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_delete_ptr(store->providers, prov); 640e1051a39Sopenharmony_ci goto err; 641e1051a39Sopenharmony_ci } 642e1051a39Sopenharmony_ci if (!retain_fallbacks) 643e1051a39Sopenharmony_ci store->use_fallbacks = 0; 644e1051a39Sopenharmony_ci } 645e1051a39Sopenharmony_ci 646e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci if (actualprov != NULL) { 649e1051a39Sopenharmony_ci if (!ossl_provider_up_ref(actualtmp)) { 650e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 651e1051a39Sopenharmony_ci actualtmp = NULL; 652e1051a39Sopenharmony_ci return 0; 653e1051a39Sopenharmony_ci } 654e1051a39Sopenharmony_ci *actualprov = actualtmp; 655e1051a39Sopenharmony_ci } 656e1051a39Sopenharmony_ci 657e1051a39Sopenharmony_ci if (idx >= 0) { 658e1051a39Sopenharmony_ci /* 659e1051a39Sopenharmony_ci * The provider is already in the store. Probably two threads 660e1051a39Sopenharmony_ci * independently initialised their own provider objects with the same 661e1051a39Sopenharmony_ci * name and raced to put them in the store. This thread lost. We 662e1051a39Sopenharmony_ci * deactivate the one we just created and use the one that already 663e1051a39Sopenharmony_ci * exists instead. 664e1051a39Sopenharmony_ci * If we get here then we know we did not create provider children 665e1051a39Sopenharmony_ci * above, so we inform ossl_provider_deactivate not to attempt to remove 666e1051a39Sopenharmony_ci * any. 667e1051a39Sopenharmony_ci */ 668e1051a39Sopenharmony_ci ossl_provider_deactivate(prov, 0); 669e1051a39Sopenharmony_ci ossl_provider_free(prov); 670e1051a39Sopenharmony_ci } 671e1051a39Sopenharmony_ci 672e1051a39Sopenharmony_ci return 1; 673e1051a39Sopenharmony_ci 674e1051a39Sopenharmony_ci err: 675e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 676e1051a39Sopenharmony_ci return 0; 677e1051a39Sopenharmony_ci} 678e1051a39Sopenharmony_ci 679e1051a39Sopenharmony_civoid ossl_provider_free(OSSL_PROVIDER *prov) 680e1051a39Sopenharmony_ci{ 681e1051a39Sopenharmony_ci if (prov != NULL) { 682e1051a39Sopenharmony_ci int ref = 0; 683e1051a39Sopenharmony_ci 684e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); 685e1051a39Sopenharmony_ci 686e1051a39Sopenharmony_ci /* 687e1051a39Sopenharmony_ci * When the refcount drops to zero, we clean up the provider. 688e1051a39Sopenharmony_ci * Note that this also does teardown, which may seem late, 689e1051a39Sopenharmony_ci * considering that init happens on first activation. However, 690e1051a39Sopenharmony_ci * there may be other structures hanging on to the provider after 691e1051a39Sopenharmony_ci * the last deactivation and may therefore need full access to the 692e1051a39Sopenharmony_ci * provider's services. Therefore, we deinit late. 693e1051a39Sopenharmony_ci */ 694e1051a39Sopenharmony_ci if (ref == 0) { 695e1051a39Sopenharmony_ci if (prov->flag_initialized) { 696e1051a39Sopenharmony_ci ossl_provider_teardown(prov); 697e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ERR 698e1051a39Sopenharmony_ci# ifndef FIPS_MODULE 699e1051a39Sopenharmony_ci if (prov->error_strings != NULL) { 700e1051a39Sopenharmony_ci ERR_unload_strings(prov->error_lib, prov->error_strings); 701e1051a39Sopenharmony_ci OPENSSL_free(prov->error_strings); 702e1051a39Sopenharmony_ci prov->error_strings = NULL; 703e1051a39Sopenharmony_ci } 704e1051a39Sopenharmony_ci# endif 705e1051a39Sopenharmony_ci#endif 706e1051a39Sopenharmony_ci OPENSSL_free(prov->operation_bits); 707e1051a39Sopenharmony_ci prov->operation_bits = NULL; 708e1051a39Sopenharmony_ci prov->operation_bits_sz = 0; 709e1051a39Sopenharmony_ci prov->flag_initialized = 0; 710e1051a39Sopenharmony_ci } 711e1051a39Sopenharmony_ci 712e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 713e1051a39Sopenharmony_ci /* 714e1051a39Sopenharmony_ci * We deregister thread handling whether or not the provider was 715e1051a39Sopenharmony_ci * initialized. If init was attempted but was not successful then 716e1051a39Sopenharmony_ci * the provider may still have registered a thread handler. 717e1051a39Sopenharmony_ci */ 718e1051a39Sopenharmony_ci ossl_init_thread_deregister(prov); 719e1051a39Sopenharmony_ci DSO_free(prov->module); 720e1051a39Sopenharmony_ci#endif 721e1051a39Sopenharmony_ci OPENSSL_free(prov->name); 722e1051a39Sopenharmony_ci OPENSSL_free(prov->path); 723e1051a39Sopenharmony_ci sk_INFOPAIR_pop_free(prov->parameters, infopair_free); 724e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(prov->opbits_lock); 725e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(prov->flag_lock); 726e1051a39Sopenharmony_ci#ifndef HAVE_ATOMICS 727e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(prov->refcnt_lock); 728e1051a39Sopenharmony_ci#endif 729e1051a39Sopenharmony_ci OPENSSL_free(prov); 730e1051a39Sopenharmony_ci } 731e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 732e1051a39Sopenharmony_ci else if (prov->ischild) { 733e1051a39Sopenharmony_ci ossl_provider_free_parent(prov, 0); 734e1051a39Sopenharmony_ci } 735e1051a39Sopenharmony_ci#endif 736e1051a39Sopenharmony_ci } 737e1051a39Sopenharmony_ci} 738e1051a39Sopenharmony_ci 739e1051a39Sopenharmony_ci/* Setters */ 740e1051a39Sopenharmony_ciint ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path) 741e1051a39Sopenharmony_ci{ 742e1051a39Sopenharmony_ci OPENSSL_free(prov->path); 743e1051a39Sopenharmony_ci prov->path = NULL; 744e1051a39Sopenharmony_ci if (module_path == NULL) 745e1051a39Sopenharmony_ci return 1; 746e1051a39Sopenharmony_ci if ((prov->path = OPENSSL_strdup(module_path)) != NULL) 747e1051a39Sopenharmony_ci return 1; 748e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 749e1051a39Sopenharmony_ci return 0; 750e1051a39Sopenharmony_ci} 751e1051a39Sopenharmony_ci 752e1051a39Sopenharmony_cistatic int infopair_add(STACK_OF(INFOPAIR) **infopairsk, const char *name, 753e1051a39Sopenharmony_ci const char *value) 754e1051a39Sopenharmony_ci{ 755e1051a39Sopenharmony_ci INFOPAIR *pair = NULL; 756e1051a39Sopenharmony_ci 757e1051a39Sopenharmony_ci if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL 758e1051a39Sopenharmony_ci && (*infopairsk != NULL 759e1051a39Sopenharmony_ci || (*infopairsk = sk_INFOPAIR_new_null()) != NULL) 760e1051a39Sopenharmony_ci && (pair->name = OPENSSL_strdup(name)) != NULL 761e1051a39Sopenharmony_ci && (pair->value = OPENSSL_strdup(value)) != NULL 762e1051a39Sopenharmony_ci && sk_INFOPAIR_push(*infopairsk, pair) > 0) 763e1051a39Sopenharmony_ci return 1; 764e1051a39Sopenharmony_ci 765e1051a39Sopenharmony_ci if (pair != NULL) { 766e1051a39Sopenharmony_ci OPENSSL_free(pair->name); 767e1051a39Sopenharmony_ci OPENSSL_free(pair->value); 768e1051a39Sopenharmony_ci OPENSSL_free(pair); 769e1051a39Sopenharmony_ci } 770e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 771e1051a39Sopenharmony_ci return 0; 772e1051a39Sopenharmony_ci} 773e1051a39Sopenharmony_ci 774e1051a39Sopenharmony_ciint ossl_provider_add_parameter(OSSL_PROVIDER *prov, 775e1051a39Sopenharmony_ci const char *name, const char *value) 776e1051a39Sopenharmony_ci{ 777e1051a39Sopenharmony_ci return infopair_add(&prov->parameters, name, value); 778e1051a39Sopenharmony_ci} 779e1051a39Sopenharmony_ci 780e1051a39Sopenharmony_ciint ossl_provider_info_add_parameter(OSSL_PROVIDER_INFO *provinfo, 781e1051a39Sopenharmony_ci const char *name, 782e1051a39Sopenharmony_ci const char *value) 783e1051a39Sopenharmony_ci{ 784e1051a39Sopenharmony_ci return infopair_add(&provinfo->parameters, name, value); 785e1051a39Sopenharmony_ci} 786e1051a39Sopenharmony_ci 787e1051a39Sopenharmony_ci/* 788e1051a39Sopenharmony_ci * Provider activation. 789e1051a39Sopenharmony_ci * 790e1051a39Sopenharmony_ci * What "activation" means depends on the provider form; for built in 791e1051a39Sopenharmony_ci * providers (in the library or the application alike), the provider 792e1051a39Sopenharmony_ci * can already be considered to be loaded, all that's needed is to 793e1051a39Sopenharmony_ci * initialize it. However, for dynamically loadable provider modules, 794e1051a39Sopenharmony_ci * we must first load that module. 795e1051a39Sopenharmony_ci * 796e1051a39Sopenharmony_ci * Built in modules are distinguished from dynamically loaded modules 797e1051a39Sopenharmony_ci * with an already assigned init function. 798e1051a39Sopenharmony_ci */ 799e1051a39Sopenharmony_cistatic const OSSL_DISPATCH *core_dispatch; /* Define further down */ 800e1051a39Sopenharmony_ci 801e1051a39Sopenharmony_ciint OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, 802e1051a39Sopenharmony_ci const char *path) 803e1051a39Sopenharmony_ci{ 804e1051a39Sopenharmony_ci struct provider_store_st *store; 805e1051a39Sopenharmony_ci char *p = NULL; 806e1051a39Sopenharmony_ci 807e1051a39Sopenharmony_ci if (path != NULL) { 808e1051a39Sopenharmony_ci p = OPENSSL_strdup(path); 809e1051a39Sopenharmony_ci if (p == NULL) { 810e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 811e1051a39Sopenharmony_ci return 0; 812e1051a39Sopenharmony_ci } 813e1051a39Sopenharmony_ci } 814e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) != NULL 815e1051a39Sopenharmony_ci && CRYPTO_THREAD_write_lock(store->default_path_lock)) { 816e1051a39Sopenharmony_ci OPENSSL_free(store->default_path); 817e1051a39Sopenharmony_ci store->default_path = p; 818e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->default_path_lock); 819e1051a39Sopenharmony_ci return 1; 820e1051a39Sopenharmony_ci } 821e1051a39Sopenharmony_ci OPENSSL_free(p); 822e1051a39Sopenharmony_ci return 0; 823e1051a39Sopenharmony_ci} 824e1051a39Sopenharmony_ci 825e1051a39Sopenharmony_ci/* 826e1051a39Sopenharmony_ci * Internal version that doesn't affect the store flags, and thereby avoid 827e1051a39Sopenharmony_ci * locking. Direct callers must remember to set the store flags when 828e1051a39Sopenharmony_ci * appropriate. 829e1051a39Sopenharmony_ci */ 830e1051a39Sopenharmony_cistatic int provider_init(OSSL_PROVIDER *prov) 831e1051a39Sopenharmony_ci{ 832e1051a39Sopenharmony_ci const OSSL_DISPATCH *provider_dispatch = NULL; 833e1051a39Sopenharmony_ci void *tmp_provctx = NULL; /* safety measure */ 834e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ERR 835e1051a39Sopenharmony_ci# ifndef FIPS_MODULE 836e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_reason_strings_fn *p_get_reason_strings = NULL; 837e1051a39Sopenharmony_ci# endif 838e1051a39Sopenharmony_ci#endif 839e1051a39Sopenharmony_ci int ok = 0; 840e1051a39Sopenharmony_ci 841e1051a39Sopenharmony_ci if (!ossl_assert(!prov->flag_initialized)) { 842e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 843e1051a39Sopenharmony_ci goto end; 844e1051a39Sopenharmony_ci } 845e1051a39Sopenharmony_ci 846e1051a39Sopenharmony_ci /* 847e1051a39Sopenharmony_ci * If the init function isn't set, it indicates that this provider is 848e1051a39Sopenharmony_ci * a loadable module. 849e1051a39Sopenharmony_ci */ 850e1051a39Sopenharmony_ci if (prov->init_function == NULL) { 851e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 852e1051a39Sopenharmony_ci goto end; 853e1051a39Sopenharmony_ci#else 854e1051a39Sopenharmony_ci if (prov->module == NULL) { 855e1051a39Sopenharmony_ci char *allocated_path = NULL; 856e1051a39Sopenharmony_ci const char *module_path = NULL; 857e1051a39Sopenharmony_ci char *merged_path = NULL; 858e1051a39Sopenharmony_ci const char *load_dir = NULL; 859e1051a39Sopenharmony_ci char *allocated_load_dir = NULL; 860e1051a39Sopenharmony_ci struct provider_store_st *store; 861e1051a39Sopenharmony_ci 862e1051a39Sopenharmony_ci if ((prov->module = DSO_new()) == NULL) { 863e1051a39Sopenharmony_ci /* DSO_new() generates an error already */ 864e1051a39Sopenharmony_ci goto end; 865e1051a39Sopenharmony_ci } 866e1051a39Sopenharmony_ci 867e1051a39Sopenharmony_ci if ((store = get_provider_store(prov->libctx)) == NULL 868e1051a39Sopenharmony_ci || !CRYPTO_THREAD_read_lock(store->default_path_lock)) 869e1051a39Sopenharmony_ci goto end; 870e1051a39Sopenharmony_ci 871e1051a39Sopenharmony_ci if (store->default_path != NULL) { 872e1051a39Sopenharmony_ci allocated_load_dir = OPENSSL_strdup(store->default_path); 873e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->default_path_lock); 874e1051a39Sopenharmony_ci if (allocated_load_dir == NULL) { 875e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 876e1051a39Sopenharmony_ci goto end; 877e1051a39Sopenharmony_ci } 878e1051a39Sopenharmony_ci load_dir = allocated_load_dir; 879e1051a39Sopenharmony_ci } else { 880e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->default_path_lock); 881e1051a39Sopenharmony_ci } 882e1051a39Sopenharmony_ci 883e1051a39Sopenharmony_ci if (load_dir == NULL) { 884e1051a39Sopenharmony_ci load_dir = ossl_safe_getenv("OPENSSL_MODULES"); 885e1051a39Sopenharmony_ci if (load_dir == NULL) 886e1051a39Sopenharmony_ci load_dir = MODULESDIR; 887e1051a39Sopenharmony_ci } 888e1051a39Sopenharmony_ci 889e1051a39Sopenharmony_ci DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS, 890e1051a39Sopenharmony_ci DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL); 891e1051a39Sopenharmony_ci 892e1051a39Sopenharmony_ci module_path = prov->path; 893e1051a39Sopenharmony_ci if (module_path == NULL) 894e1051a39Sopenharmony_ci module_path = allocated_path = 895e1051a39Sopenharmony_ci DSO_convert_filename(prov->module, prov->name); 896e1051a39Sopenharmony_ci if (module_path != NULL) 897e1051a39Sopenharmony_ci merged_path = DSO_merge(prov->module, module_path, load_dir); 898e1051a39Sopenharmony_ci 899e1051a39Sopenharmony_ci if (merged_path == NULL 900e1051a39Sopenharmony_ci || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) { 901e1051a39Sopenharmony_ci DSO_free(prov->module); 902e1051a39Sopenharmony_ci prov->module = NULL; 903e1051a39Sopenharmony_ci } 904e1051a39Sopenharmony_ci 905e1051a39Sopenharmony_ci OPENSSL_free(merged_path); 906e1051a39Sopenharmony_ci OPENSSL_free(allocated_path); 907e1051a39Sopenharmony_ci OPENSSL_free(allocated_load_dir); 908e1051a39Sopenharmony_ci } 909e1051a39Sopenharmony_ci 910e1051a39Sopenharmony_ci if (prov->module == NULL) { 911e1051a39Sopenharmony_ci /* DSO has already recorded errors, this is just a tracepoint */ 912e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_DSO_LIB, 913e1051a39Sopenharmony_ci "name=%s", prov->name); 914e1051a39Sopenharmony_ci goto end; 915e1051a39Sopenharmony_ci } 916e1051a39Sopenharmony_ci 917e1051a39Sopenharmony_ci prov->init_function = (OSSL_provider_init_fn *) 918e1051a39Sopenharmony_ci DSO_bind_func(prov->module, "OSSL_provider_init"); 919e1051a39Sopenharmony_ci#endif 920e1051a39Sopenharmony_ci } 921e1051a39Sopenharmony_ci 922e1051a39Sopenharmony_ci /* Check for and call the initialise function for the provider. */ 923e1051a39Sopenharmony_ci if (prov->init_function == NULL) { 924e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED, 925e1051a39Sopenharmony_ci "name=%s, provider has no provider init function", 926e1051a39Sopenharmony_ci prov->name); 927e1051a39Sopenharmony_ci goto end; 928e1051a39Sopenharmony_ci } 929e1051a39Sopenharmony_ci 930e1051a39Sopenharmony_ci if (!prov->init_function((OSSL_CORE_HANDLE *)prov, core_dispatch, 931e1051a39Sopenharmony_ci &provider_dispatch, &tmp_provctx)) { 932e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, 933e1051a39Sopenharmony_ci "name=%s", prov->name); 934e1051a39Sopenharmony_ci goto end; 935e1051a39Sopenharmony_ci } 936e1051a39Sopenharmony_ci prov->provctx = tmp_provctx; 937e1051a39Sopenharmony_ci prov->dispatch = provider_dispatch; 938e1051a39Sopenharmony_ci 939e1051a39Sopenharmony_ci for (; provider_dispatch->function_id != 0; provider_dispatch++) { 940e1051a39Sopenharmony_ci switch (provider_dispatch->function_id) { 941e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_TEARDOWN: 942e1051a39Sopenharmony_ci prov->teardown = 943e1051a39Sopenharmony_ci OSSL_FUNC_provider_teardown(provider_dispatch); 944e1051a39Sopenharmony_ci break; 945e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: 946e1051a39Sopenharmony_ci prov->gettable_params = 947e1051a39Sopenharmony_ci OSSL_FUNC_provider_gettable_params(provider_dispatch); 948e1051a39Sopenharmony_ci break; 949e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_GET_PARAMS: 950e1051a39Sopenharmony_ci prov->get_params = 951e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_params(provider_dispatch); 952e1051a39Sopenharmony_ci break; 953e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_SELF_TEST: 954e1051a39Sopenharmony_ci prov->self_test = 955e1051a39Sopenharmony_ci OSSL_FUNC_provider_self_test(provider_dispatch); 956e1051a39Sopenharmony_ci break; 957e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_GET_CAPABILITIES: 958e1051a39Sopenharmony_ci prov->get_capabilities = 959e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_capabilities(provider_dispatch); 960e1051a39Sopenharmony_ci break; 961e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_QUERY_OPERATION: 962e1051a39Sopenharmony_ci prov->query_operation = 963e1051a39Sopenharmony_ci OSSL_FUNC_provider_query_operation(provider_dispatch); 964e1051a39Sopenharmony_ci break; 965e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION: 966e1051a39Sopenharmony_ci prov->unquery_operation = 967e1051a39Sopenharmony_ci OSSL_FUNC_provider_unquery_operation(provider_dispatch); 968e1051a39Sopenharmony_ci break; 969e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ERR 970e1051a39Sopenharmony_ci# ifndef FIPS_MODULE 971e1051a39Sopenharmony_ci case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: 972e1051a39Sopenharmony_ci p_get_reason_strings = 973e1051a39Sopenharmony_ci OSSL_FUNC_provider_get_reason_strings(provider_dispatch); 974e1051a39Sopenharmony_ci break; 975e1051a39Sopenharmony_ci# endif 976e1051a39Sopenharmony_ci#endif 977e1051a39Sopenharmony_ci } 978e1051a39Sopenharmony_ci } 979e1051a39Sopenharmony_ci 980e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ERR 981e1051a39Sopenharmony_ci# ifndef FIPS_MODULE 982e1051a39Sopenharmony_ci if (p_get_reason_strings != NULL) { 983e1051a39Sopenharmony_ci const OSSL_ITEM *reasonstrings = p_get_reason_strings(prov->provctx); 984e1051a39Sopenharmony_ci size_t cnt, cnt2; 985e1051a39Sopenharmony_ci 986e1051a39Sopenharmony_ci /* 987e1051a39Sopenharmony_ci * ERR_load_strings() handles ERR_STRING_DATA rather than OSSL_ITEM, 988e1051a39Sopenharmony_ci * although they are essentially the same type. 989e1051a39Sopenharmony_ci * Furthermore, ERR_load_strings() patches the array's error number 990e1051a39Sopenharmony_ci * with the error library number, so we need to make a copy of that 991e1051a39Sopenharmony_ci * array either way. 992e1051a39Sopenharmony_ci */ 993e1051a39Sopenharmony_ci cnt = 0; 994e1051a39Sopenharmony_ci while (reasonstrings[cnt].id != 0) { 995e1051a39Sopenharmony_ci if (ERR_GET_LIB(reasonstrings[cnt].id) != 0) 996e1051a39Sopenharmony_ci goto end; 997e1051a39Sopenharmony_ci cnt++; 998e1051a39Sopenharmony_ci } 999e1051a39Sopenharmony_ci cnt++; /* One for the terminating item */ 1000e1051a39Sopenharmony_ci 1001e1051a39Sopenharmony_ci /* Allocate one extra item for the "library" name */ 1002e1051a39Sopenharmony_ci prov->error_strings = 1003e1051a39Sopenharmony_ci OPENSSL_zalloc(sizeof(ERR_STRING_DATA) * (cnt + 1)); 1004e1051a39Sopenharmony_ci if (prov->error_strings == NULL) 1005e1051a39Sopenharmony_ci goto end; 1006e1051a39Sopenharmony_ci 1007e1051a39Sopenharmony_ci /* 1008e1051a39Sopenharmony_ci * Set the "library" name. 1009e1051a39Sopenharmony_ci */ 1010e1051a39Sopenharmony_ci prov->error_strings[0].error = ERR_PACK(prov->error_lib, 0, 0); 1011e1051a39Sopenharmony_ci prov->error_strings[0].string = prov->name; 1012e1051a39Sopenharmony_ci /* 1013e1051a39Sopenharmony_ci * Copy reasonstrings item 0..cnt-1 to prov->error_trings positions 1014e1051a39Sopenharmony_ci * 1..cnt. 1015e1051a39Sopenharmony_ci */ 1016e1051a39Sopenharmony_ci for (cnt2 = 1; cnt2 <= cnt; cnt2++) { 1017e1051a39Sopenharmony_ci prov->error_strings[cnt2].error = (int)reasonstrings[cnt2-1].id; 1018e1051a39Sopenharmony_ci prov->error_strings[cnt2].string = reasonstrings[cnt2-1].ptr; 1019e1051a39Sopenharmony_ci } 1020e1051a39Sopenharmony_ci 1021e1051a39Sopenharmony_ci ERR_load_strings(prov->error_lib, prov->error_strings); 1022e1051a39Sopenharmony_ci } 1023e1051a39Sopenharmony_ci# endif 1024e1051a39Sopenharmony_ci#endif 1025e1051a39Sopenharmony_ci 1026e1051a39Sopenharmony_ci /* With this flag set, this provider has become fully "loaded". */ 1027e1051a39Sopenharmony_ci prov->flag_initialized = 1; 1028e1051a39Sopenharmony_ci ok = 1; 1029e1051a39Sopenharmony_ci 1030e1051a39Sopenharmony_ci end: 1031e1051a39Sopenharmony_ci return ok; 1032e1051a39Sopenharmony_ci} 1033e1051a39Sopenharmony_ci 1034e1051a39Sopenharmony_ci/* 1035e1051a39Sopenharmony_ci * Deactivate a provider. If upcalls is 0 then we suppress any upcalls to a 1036e1051a39Sopenharmony_ci * parent provider. If removechildren is 0 then we suppress any calls to remove 1037e1051a39Sopenharmony_ci * child providers. 1038e1051a39Sopenharmony_ci * Return -1 on failure and the activation count on success 1039e1051a39Sopenharmony_ci */ 1040e1051a39Sopenharmony_cistatic int provider_deactivate(OSSL_PROVIDER *prov, int upcalls, 1041e1051a39Sopenharmony_ci int removechildren) 1042e1051a39Sopenharmony_ci{ 1043e1051a39Sopenharmony_ci int count; 1044e1051a39Sopenharmony_ci struct provider_store_st *store; 1045e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1046e1051a39Sopenharmony_ci int freeparent = 0; 1047e1051a39Sopenharmony_ci#endif 1048e1051a39Sopenharmony_ci int lock = 1; 1049e1051a39Sopenharmony_ci 1050e1051a39Sopenharmony_ci if (!ossl_assert(prov != NULL)) 1051e1051a39Sopenharmony_ci return -1; 1052e1051a39Sopenharmony_ci 1053e1051a39Sopenharmony_ci /* 1054e1051a39Sopenharmony_ci * No need to lock if we've got no store because we've not been shared with 1055e1051a39Sopenharmony_ci * other threads. 1056e1051a39Sopenharmony_ci */ 1057e1051a39Sopenharmony_ci store = get_provider_store(prov->libctx); 1058e1051a39Sopenharmony_ci if (store == NULL) 1059e1051a39Sopenharmony_ci lock = 0; 1060e1051a39Sopenharmony_ci 1061e1051a39Sopenharmony_ci if (lock && !CRYPTO_THREAD_read_lock(store->lock)) 1062e1051a39Sopenharmony_ci return -1; 1063e1051a39Sopenharmony_ci if (lock && !CRYPTO_THREAD_write_lock(prov->flag_lock)) { 1064e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1065e1051a39Sopenharmony_ci return -1; 1066e1051a39Sopenharmony_ci } 1067e1051a39Sopenharmony_ci 1068e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1069e1051a39Sopenharmony_ci if (prov->activatecnt >= 2 && prov->ischild && upcalls) { 1070e1051a39Sopenharmony_ci /* 1071e1051a39Sopenharmony_ci * We have had a direct activation in this child libctx so we need to 1072e1051a39Sopenharmony_ci * now down the ref count in the parent provider. We do the actual down 1073e1051a39Sopenharmony_ci * ref outside of the flag_lock, since it could involve getting other 1074e1051a39Sopenharmony_ci * locks. 1075e1051a39Sopenharmony_ci */ 1076e1051a39Sopenharmony_ci freeparent = 1; 1077e1051a39Sopenharmony_ci } 1078e1051a39Sopenharmony_ci#endif 1079e1051a39Sopenharmony_ci 1080e1051a39Sopenharmony_ci if ((count = --prov->activatecnt) < 1) 1081e1051a39Sopenharmony_ci prov->flag_activated = 0; 1082e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1083e1051a39Sopenharmony_ci else 1084e1051a39Sopenharmony_ci removechildren = 0; 1085e1051a39Sopenharmony_ci#endif 1086e1051a39Sopenharmony_ci 1087e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1088e1051a39Sopenharmony_ci if (removechildren && store != NULL) { 1089e1051a39Sopenharmony_ci int i, max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); 1090e1051a39Sopenharmony_ci OSSL_PROVIDER_CHILD_CB *child_cb; 1091e1051a39Sopenharmony_ci 1092e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 1093e1051a39Sopenharmony_ci child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); 1094e1051a39Sopenharmony_ci child_cb->remove_cb((OSSL_CORE_HANDLE *)prov, child_cb->cbdata); 1095e1051a39Sopenharmony_ci } 1096e1051a39Sopenharmony_ci } 1097e1051a39Sopenharmony_ci#endif 1098e1051a39Sopenharmony_ci if (lock) { 1099e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1100e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1101e1051a39Sopenharmony_ci } 1102e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1103e1051a39Sopenharmony_ci if (freeparent) 1104e1051a39Sopenharmony_ci ossl_provider_free_parent(prov, 1); 1105e1051a39Sopenharmony_ci#endif 1106e1051a39Sopenharmony_ci 1107e1051a39Sopenharmony_ci /* We don't deinit here, that's done in ossl_provider_free() */ 1108e1051a39Sopenharmony_ci return count; 1109e1051a39Sopenharmony_ci} 1110e1051a39Sopenharmony_ci 1111e1051a39Sopenharmony_ci/* 1112e1051a39Sopenharmony_ci * Activate a provider. 1113e1051a39Sopenharmony_ci * Return -1 on failure and the activation count on success 1114e1051a39Sopenharmony_ci */ 1115e1051a39Sopenharmony_cistatic int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls) 1116e1051a39Sopenharmony_ci{ 1117e1051a39Sopenharmony_ci int count = -1; 1118e1051a39Sopenharmony_ci struct provider_store_st *store; 1119e1051a39Sopenharmony_ci int ret = 1; 1120e1051a39Sopenharmony_ci 1121e1051a39Sopenharmony_ci store = prov->store; 1122e1051a39Sopenharmony_ci /* 1123e1051a39Sopenharmony_ci * If the provider hasn't been added to the store, then we don't need 1124e1051a39Sopenharmony_ci * any locks because we've not shared it with other threads. 1125e1051a39Sopenharmony_ci */ 1126e1051a39Sopenharmony_ci if (store == NULL) { 1127e1051a39Sopenharmony_ci lock = 0; 1128e1051a39Sopenharmony_ci if (!provider_init(prov)) 1129e1051a39Sopenharmony_ci return -1; 1130e1051a39Sopenharmony_ci } 1131e1051a39Sopenharmony_ci 1132e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1133e1051a39Sopenharmony_ci if (prov->ischild && upcalls && !ossl_provider_up_ref_parent(prov, 1)) 1134e1051a39Sopenharmony_ci return -1; 1135e1051a39Sopenharmony_ci#endif 1136e1051a39Sopenharmony_ci 1137e1051a39Sopenharmony_ci if (lock && !CRYPTO_THREAD_read_lock(store->lock)) { 1138e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1139e1051a39Sopenharmony_ci if (prov->ischild && upcalls) 1140e1051a39Sopenharmony_ci ossl_provider_free_parent(prov, 1); 1141e1051a39Sopenharmony_ci#endif 1142e1051a39Sopenharmony_ci return -1; 1143e1051a39Sopenharmony_ci } 1144e1051a39Sopenharmony_ci 1145e1051a39Sopenharmony_ci if (lock && !CRYPTO_THREAD_write_lock(prov->flag_lock)) { 1146e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1147e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1148e1051a39Sopenharmony_ci if (prov->ischild && upcalls) 1149e1051a39Sopenharmony_ci ossl_provider_free_parent(prov, 1); 1150e1051a39Sopenharmony_ci#endif 1151e1051a39Sopenharmony_ci return -1; 1152e1051a39Sopenharmony_ci } 1153e1051a39Sopenharmony_ci 1154e1051a39Sopenharmony_ci count = ++prov->activatecnt; 1155e1051a39Sopenharmony_ci prov->flag_activated = 1; 1156e1051a39Sopenharmony_ci 1157e1051a39Sopenharmony_ci if (prov->activatecnt == 1 && store != NULL) { 1158e1051a39Sopenharmony_ci ret = create_provider_children(prov); 1159e1051a39Sopenharmony_ci } 1160e1051a39Sopenharmony_ci if (lock) { 1161e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1162e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1163e1051a39Sopenharmony_ci } 1164e1051a39Sopenharmony_ci 1165e1051a39Sopenharmony_ci if (!ret) 1166e1051a39Sopenharmony_ci return -1; 1167e1051a39Sopenharmony_ci 1168e1051a39Sopenharmony_ci return count; 1169e1051a39Sopenharmony_ci} 1170e1051a39Sopenharmony_ci 1171e1051a39Sopenharmony_cistatic int provider_flush_store_cache(const OSSL_PROVIDER *prov) 1172e1051a39Sopenharmony_ci{ 1173e1051a39Sopenharmony_ci struct provider_store_st *store; 1174e1051a39Sopenharmony_ci int freeing; 1175e1051a39Sopenharmony_ci 1176e1051a39Sopenharmony_ci if ((store = get_provider_store(prov->libctx)) == NULL) 1177e1051a39Sopenharmony_ci return 0; 1178e1051a39Sopenharmony_ci 1179e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 1180e1051a39Sopenharmony_ci return 0; 1181e1051a39Sopenharmony_ci freeing = store->freeing; 1182e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1183e1051a39Sopenharmony_ci 1184e1051a39Sopenharmony_ci if (!freeing) { 1185e1051a39Sopenharmony_ci int acc 1186e1051a39Sopenharmony_ci = evp_method_store_cache_flush(prov->libctx) 1187e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1188e1051a39Sopenharmony_ci + ossl_encoder_store_cache_flush(prov->libctx) 1189e1051a39Sopenharmony_ci + ossl_decoder_store_cache_flush(prov->libctx) 1190e1051a39Sopenharmony_ci + ossl_store_loader_store_cache_flush(prov->libctx) 1191e1051a39Sopenharmony_ci#endif 1192e1051a39Sopenharmony_ci ; 1193e1051a39Sopenharmony_ci 1194e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1195e1051a39Sopenharmony_ci return acc == 4; 1196e1051a39Sopenharmony_ci#else 1197e1051a39Sopenharmony_ci return acc == 1; 1198e1051a39Sopenharmony_ci#endif 1199e1051a39Sopenharmony_ci } 1200e1051a39Sopenharmony_ci return 1; 1201e1051a39Sopenharmony_ci} 1202e1051a39Sopenharmony_ci 1203e1051a39Sopenharmony_cistatic int provider_remove_store_methods(OSSL_PROVIDER *prov) 1204e1051a39Sopenharmony_ci{ 1205e1051a39Sopenharmony_ci struct provider_store_st *store; 1206e1051a39Sopenharmony_ci int freeing; 1207e1051a39Sopenharmony_ci 1208e1051a39Sopenharmony_ci if ((store = get_provider_store(prov->libctx)) == NULL) 1209e1051a39Sopenharmony_ci return 0; 1210e1051a39Sopenharmony_ci 1211e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 1212e1051a39Sopenharmony_ci return 0; 1213e1051a39Sopenharmony_ci freeing = store->freeing; 1214e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1215e1051a39Sopenharmony_ci 1216e1051a39Sopenharmony_ci if (!freeing) { 1217e1051a39Sopenharmony_ci int acc; 1218e1051a39Sopenharmony_ci 1219e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(prov->opbits_lock)) 1220e1051a39Sopenharmony_ci return 0; 1221e1051a39Sopenharmony_ci OPENSSL_free(prov->operation_bits); 1222e1051a39Sopenharmony_ci prov->operation_bits = NULL; 1223e1051a39Sopenharmony_ci prov->operation_bits_sz = 0; 1224e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->opbits_lock); 1225e1051a39Sopenharmony_ci 1226e1051a39Sopenharmony_ci acc = evp_method_store_remove_all_provided(prov) 1227e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1228e1051a39Sopenharmony_ci + ossl_encoder_store_remove_all_provided(prov) 1229e1051a39Sopenharmony_ci + ossl_decoder_store_remove_all_provided(prov) 1230e1051a39Sopenharmony_ci + ossl_store_loader_store_remove_all_provided(prov) 1231e1051a39Sopenharmony_ci#endif 1232e1051a39Sopenharmony_ci ; 1233e1051a39Sopenharmony_ci 1234e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1235e1051a39Sopenharmony_ci return acc == 4; 1236e1051a39Sopenharmony_ci#else 1237e1051a39Sopenharmony_ci return acc == 1; 1238e1051a39Sopenharmony_ci#endif 1239e1051a39Sopenharmony_ci } 1240e1051a39Sopenharmony_ci return 1; 1241e1051a39Sopenharmony_ci} 1242e1051a39Sopenharmony_ci 1243e1051a39Sopenharmony_ciint ossl_provider_activate(OSSL_PROVIDER *prov, int upcalls, int aschild) 1244e1051a39Sopenharmony_ci{ 1245e1051a39Sopenharmony_ci int count; 1246e1051a39Sopenharmony_ci 1247e1051a39Sopenharmony_ci if (prov == NULL) 1248e1051a39Sopenharmony_ci return 0; 1249e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1250e1051a39Sopenharmony_ci /* 1251e1051a39Sopenharmony_ci * If aschild is true, then we only actually do the activation if the 1252e1051a39Sopenharmony_ci * provider is a child. If its not, this is still success. 1253e1051a39Sopenharmony_ci */ 1254e1051a39Sopenharmony_ci if (aschild && !prov->ischild) 1255e1051a39Sopenharmony_ci return 1; 1256e1051a39Sopenharmony_ci#endif 1257e1051a39Sopenharmony_ci if ((count = provider_activate(prov, 1, upcalls)) > 0) 1258e1051a39Sopenharmony_ci return count == 1 ? provider_flush_store_cache(prov) : 1; 1259e1051a39Sopenharmony_ci 1260e1051a39Sopenharmony_ci return 0; 1261e1051a39Sopenharmony_ci} 1262e1051a39Sopenharmony_ci 1263e1051a39Sopenharmony_ciint ossl_provider_deactivate(OSSL_PROVIDER *prov, int removechildren) 1264e1051a39Sopenharmony_ci{ 1265e1051a39Sopenharmony_ci int count; 1266e1051a39Sopenharmony_ci 1267e1051a39Sopenharmony_ci if (prov == NULL 1268e1051a39Sopenharmony_ci || (count = provider_deactivate(prov, 1, removechildren)) < 0) 1269e1051a39Sopenharmony_ci return 0; 1270e1051a39Sopenharmony_ci return count == 0 ? provider_remove_store_methods(prov) : 1; 1271e1051a39Sopenharmony_ci} 1272e1051a39Sopenharmony_ci 1273e1051a39Sopenharmony_civoid *ossl_provider_ctx(const OSSL_PROVIDER *prov) 1274e1051a39Sopenharmony_ci{ 1275e1051a39Sopenharmony_ci return prov != NULL ? prov->provctx : NULL; 1276e1051a39Sopenharmony_ci} 1277e1051a39Sopenharmony_ci 1278e1051a39Sopenharmony_ci/* 1279e1051a39Sopenharmony_ci * This function only does something once when store->use_fallbacks == 1, 1280e1051a39Sopenharmony_ci * and then sets store->use_fallbacks = 0, so the second call and so on is 1281e1051a39Sopenharmony_ci * effectively a no-op. 1282e1051a39Sopenharmony_ci */ 1283e1051a39Sopenharmony_cistatic int provider_activate_fallbacks(struct provider_store_st *store) 1284e1051a39Sopenharmony_ci{ 1285e1051a39Sopenharmony_ci int use_fallbacks; 1286e1051a39Sopenharmony_ci int activated_fallback_count = 0; 1287e1051a39Sopenharmony_ci int ret = 0; 1288e1051a39Sopenharmony_ci const OSSL_PROVIDER_INFO *p; 1289e1051a39Sopenharmony_ci 1290e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 1291e1051a39Sopenharmony_ci return 0; 1292e1051a39Sopenharmony_ci use_fallbacks = store->use_fallbacks; 1293e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1294e1051a39Sopenharmony_ci if (!use_fallbacks) 1295e1051a39Sopenharmony_ci return 1; 1296e1051a39Sopenharmony_ci 1297e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 1298e1051a39Sopenharmony_ci return 0; 1299e1051a39Sopenharmony_ci /* Check again, just in case another thread changed it */ 1300e1051a39Sopenharmony_ci use_fallbacks = store->use_fallbacks; 1301e1051a39Sopenharmony_ci if (!use_fallbacks) { 1302e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1303e1051a39Sopenharmony_ci return 1; 1304e1051a39Sopenharmony_ci } 1305e1051a39Sopenharmony_ci 1306e1051a39Sopenharmony_ci for (p = ossl_predefined_providers; p->name != NULL; p++) { 1307e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL; 1308e1051a39Sopenharmony_ci 1309e1051a39Sopenharmony_ci if (!p->is_fallback) 1310e1051a39Sopenharmony_ci continue; 1311e1051a39Sopenharmony_ci /* 1312e1051a39Sopenharmony_ci * We use the internal constructor directly here, 1313e1051a39Sopenharmony_ci * otherwise we get a call loop 1314e1051a39Sopenharmony_ci */ 1315e1051a39Sopenharmony_ci prov = provider_new(p->name, p->init, NULL); 1316e1051a39Sopenharmony_ci if (prov == NULL) 1317e1051a39Sopenharmony_ci goto err; 1318e1051a39Sopenharmony_ci prov->libctx = store->libctx; 1319e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1320e1051a39Sopenharmony_ci prov->error_lib = ERR_get_next_error_library(); 1321e1051a39Sopenharmony_ci#endif 1322e1051a39Sopenharmony_ci 1323e1051a39Sopenharmony_ci /* 1324e1051a39Sopenharmony_ci * We are calling provider_activate while holding the store lock. This 1325e1051a39Sopenharmony_ci * means the init function will be called while holding a lock. Normally 1326e1051a39Sopenharmony_ci * we try to avoid calling a user callback while holding a lock. 1327e1051a39Sopenharmony_ci * However, fallbacks are never third party providers so we accept this. 1328e1051a39Sopenharmony_ci */ 1329e1051a39Sopenharmony_ci if (provider_activate(prov, 0, 0) < 0) { 1330e1051a39Sopenharmony_ci ossl_provider_free(prov); 1331e1051a39Sopenharmony_ci goto err; 1332e1051a39Sopenharmony_ci } 1333e1051a39Sopenharmony_ci prov->store = store; 1334e1051a39Sopenharmony_ci if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) { 1335e1051a39Sopenharmony_ci ossl_provider_free(prov); 1336e1051a39Sopenharmony_ci goto err; 1337e1051a39Sopenharmony_ci } 1338e1051a39Sopenharmony_ci activated_fallback_count++; 1339e1051a39Sopenharmony_ci } 1340e1051a39Sopenharmony_ci 1341e1051a39Sopenharmony_ci if (activated_fallback_count > 0) { 1342e1051a39Sopenharmony_ci store->use_fallbacks = 0; 1343e1051a39Sopenharmony_ci ret = 1; 1344e1051a39Sopenharmony_ci } 1345e1051a39Sopenharmony_ci err: 1346e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1347e1051a39Sopenharmony_ci return ret; 1348e1051a39Sopenharmony_ci} 1349e1051a39Sopenharmony_ci 1350e1051a39Sopenharmony_ciint ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, 1351e1051a39Sopenharmony_ci int (*cb)(OSSL_PROVIDER *provider, 1352e1051a39Sopenharmony_ci void *cbdata), 1353e1051a39Sopenharmony_ci void *cbdata) 1354e1051a39Sopenharmony_ci{ 1355e1051a39Sopenharmony_ci int ret = 0, curr, max, ref = 0; 1356e1051a39Sopenharmony_ci struct provider_store_st *store = get_provider_store(ctx); 1357e1051a39Sopenharmony_ci STACK_OF(OSSL_PROVIDER) *provs = NULL; 1358e1051a39Sopenharmony_ci 1359e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1360e1051a39Sopenharmony_ci /* 1361e1051a39Sopenharmony_ci * Make sure any providers are loaded from config before we try to use 1362e1051a39Sopenharmony_ci * them. 1363e1051a39Sopenharmony_ci */ 1364e1051a39Sopenharmony_ci if (ossl_lib_ctx_is_default(ctx)) 1365e1051a39Sopenharmony_ci OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); 1366e1051a39Sopenharmony_ci#endif 1367e1051a39Sopenharmony_ci 1368e1051a39Sopenharmony_ci if (store == NULL) 1369e1051a39Sopenharmony_ci return 1; 1370e1051a39Sopenharmony_ci if (!provider_activate_fallbacks(store)) 1371e1051a39Sopenharmony_ci return 0; 1372e1051a39Sopenharmony_ci 1373e1051a39Sopenharmony_ci /* 1374e1051a39Sopenharmony_ci * Under lock, grab a copy of the provider list and up_ref each 1375e1051a39Sopenharmony_ci * provider so that they don't disappear underneath us. 1376e1051a39Sopenharmony_ci */ 1377e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 1378e1051a39Sopenharmony_ci return 0; 1379e1051a39Sopenharmony_ci provs = sk_OSSL_PROVIDER_dup(store->providers); 1380e1051a39Sopenharmony_ci if (provs == NULL) { 1381e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1382e1051a39Sopenharmony_ci return 0; 1383e1051a39Sopenharmony_ci } 1384e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_num(provs); 1385e1051a39Sopenharmony_ci /* 1386e1051a39Sopenharmony_ci * We work backwards through the stack so that we can safely delete items 1387e1051a39Sopenharmony_ci * as we go. 1388e1051a39Sopenharmony_ci */ 1389e1051a39Sopenharmony_ci for (curr = max - 1; curr >= 0; curr--) { 1390e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); 1391e1051a39Sopenharmony_ci 1392e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(prov->flag_lock)) 1393e1051a39Sopenharmony_ci goto err_unlock; 1394e1051a39Sopenharmony_ci if (prov->flag_activated) { 1395e1051a39Sopenharmony_ci /* 1396e1051a39Sopenharmony_ci * We call CRYPTO_UP_REF directly rather than ossl_provider_up_ref 1397e1051a39Sopenharmony_ci * to avoid upping the ref count on the parent provider, which we 1398e1051a39Sopenharmony_ci * must not do while holding locks. 1399e1051a39Sopenharmony_ci */ 1400e1051a39Sopenharmony_ci if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) { 1401e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1402e1051a39Sopenharmony_ci goto err_unlock; 1403e1051a39Sopenharmony_ci } 1404e1051a39Sopenharmony_ci /* 1405e1051a39Sopenharmony_ci * It's already activated, but we up the activated count to ensure 1406e1051a39Sopenharmony_ci * it remains activated until after we've called the user callback. 1407e1051a39Sopenharmony_ci * We do this with no locking (because we already hold the locks) 1408e1051a39Sopenharmony_ci * and no upcalls (which must not be called when locks are held). In 1409e1051a39Sopenharmony_ci * theory this could mean the parent provider goes inactive, whilst 1410e1051a39Sopenharmony_ci * still activated in the child for a short period. That's ok. 1411e1051a39Sopenharmony_ci */ 1412e1051a39Sopenharmony_ci if (provider_activate(prov, 0, 0) < 0) { 1413e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); 1414e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1415e1051a39Sopenharmony_ci goto err_unlock; 1416e1051a39Sopenharmony_ci } 1417e1051a39Sopenharmony_ci } else { 1418e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_delete(provs, curr); 1419e1051a39Sopenharmony_ci max--; 1420e1051a39Sopenharmony_ci } 1421e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1422e1051a39Sopenharmony_ci } 1423e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1424e1051a39Sopenharmony_ci 1425e1051a39Sopenharmony_ci /* 1426e1051a39Sopenharmony_ci * Now, we sweep through all providers not under lock 1427e1051a39Sopenharmony_ci */ 1428e1051a39Sopenharmony_ci for (curr = 0; curr < max; curr++) { 1429e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); 1430e1051a39Sopenharmony_ci 1431e1051a39Sopenharmony_ci if (!cb(prov, cbdata)) { 1432e1051a39Sopenharmony_ci curr = -1; 1433e1051a39Sopenharmony_ci goto finish; 1434e1051a39Sopenharmony_ci } 1435e1051a39Sopenharmony_ci } 1436e1051a39Sopenharmony_ci curr = -1; 1437e1051a39Sopenharmony_ci 1438e1051a39Sopenharmony_ci ret = 1; 1439e1051a39Sopenharmony_ci goto finish; 1440e1051a39Sopenharmony_ci 1441e1051a39Sopenharmony_ci err_unlock: 1442e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1443e1051a39Sopenharmony_ci finish: 1444e1051a39Sopenharmony_ci /* 1445e1051a39Sopenharmony_ci * The pop_free call doesn't do what we want on an error condition. We 1446e1051a39Sopenharmony_ci * either start from the first item in the stack, or part way through if 1447e1051a39Sopenharmony_ci * we only processed some of the items. 1448e1051a39Sopenharmony_ci */ 1449e1051a39Sopenharmony_ci for (curr++; curr < max; curr++) { 1450e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); 1451e1051a39Sopenharmony_ci 1452e1051a39Sopenharmony_ci provider_deactivate(prov, 0, 1); 1453e1051a39Sopenharmony_ci /* 1454e1051a39Sopenharmony_ci * As above where we did the up-ref, we don't call ossl_provider_free 1455e1051a39Sopenharmony_ci * to avoid making upcalls. There should always be at least one ref 1456e1051a39Sopenharmony_ci * to the provider in the store, so this should never drop to 0. 1457e1051a39Sopenharmony_ci */ 1458e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); 1459e1051a39Sopenharmony_ci /* 1460e1051a39Sopenharmony_ci * Not much we can do if this assert ever fails. So we don't use 1461e1051a39Sopenharmony_ci * ossl_assert here. 1462e1051a39Sopenharmony_ci */ 1463e1051a39Sopenharmony_ci assert(ref > 0); 1464e1051a39Sopenharmony_ci } 1465e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_free(provs); 1466e1051a39Sopenharmony_ci return ret; 1467e1051a39Sopenharmony_ci} 1468e1051a39Sopenharmony_ci 1469e1051a39Sopenharmony_ciint OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name) 1470e1051a39Sopenharmony_ci{ 1471e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = NULL; 1472e1051a39Sopenharmony_ci int available = 0; 1473e1051a39Sopenharmony_ci struct provider_store_st *store = get_provider_store(libctx); 1474e1051a39Sopenharmony_ci 1475e1051a39Sopenharmony_ci if (store == NULL || !provider_activate_fallbacks(store)) 1476e1051a39Sopenharmony_ci return 0; 1477e1051a39Sopenharmony_ci 1478e1051a39Sopenharmony_ci prov = ossl_provider_find(libctx, name, 0); 1479e1051a39Sopenharmony_ci if (prov != NULL) { 1480e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) 1481e1051a39Sopenharmony_ci return 0; 1482e1051a39Sopenharmony_ci available = prov->flag_activated; 1483e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1484e1051a39Sopenharmony_ci ossl_provider_free(prov); 1485e1051a39Sopenharmony_ci } 1486e1051a39Sopenharmony_ci return available; 1487e1051a39Sopenharmony_ci} 1488e1051a39Sopenharmony_ci 1489e1051a39Sopenharmony_ci/* Setters of Provider Object data */ 1490e1051a39Sopenharmony_ciint ossl_provider_set_fallback(OSSL_PROVIDER *prov) 1491e1051a39Sopenharmony_ci{ 1492e1051a39Sopenharmony_ci if (prov == NULL) 1493e1051a39Sopenharmony_ci return 0; 1494e1051a39Sopenharmony_ci 1495e1051a39Sopenharmony_ci prov->flag_fallback = 1; 1496e1051a39Sopenharmony_ci return 1; 1497e1051a39Sopenharmony_ci} 1498e1051a39Sopenharmony_ci 1499e1051a39Sopenharmony_ci/* Getters of Provider Object data */ 1500e1051a39Sopenharmony_ciconst char *ossl_provider_name(const OSSL_PROVIDER *prov) 1501e1051a39Sopenharmony_ci{ 1502e1051a39Sopenharmony_ci return prov->name; 1503e1051a39Sopenharmony_ci} 1504e1051a39Sopenharmony_ci 1505e1051a39Sopenharmony_ciconst DSO *ossl_provider_dso(const OSSL_PROVIDER *prov) 1506e1051a39Sopenharmony_ci{ 1507e1051a39Sopenharmony_ci return prov->module; 1508e1051a39Sopenharmony_ci} 1509e1051a39Sopenharmony_ci 1510e1051a39Sopenharmony_ciconst char *ossl_provider_module_name(const OSSL_PROVIDER *prov) 1511e1051a39Sopenharmony_ci{ 1512e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 1513e1051a39Sopenharmony_ci return NULL; 1514e1051a39Sopenharmony_ci#else 1515e1051a39Sopenharmony_ci return DSO_get_filename(prov->module); 1516e1051a39Sopenharmony_ci#endif 1517e1051a39Sopenharmony_ci} 1518e1051a39Sopenharmony_ci 1519e1051a39Sopenharmony_ciconst char *ossl_provider_module_path(const OSSL_PROVIDER *prov) 1520e1051a39Sopenharmony_ci{ 1521e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 1522e1051a39Sopenharmony_ci return NULL; 1523e1051a39Sopenharmony_ci#else 1524e1051a39Sopenharmony_ci /* FIXME: Ensure it's a full path */ 1525e1051a39Sopenharmony_ci return DSO_get_filename(prov->module); 1526e1051a39Sopenharmony_ci#endif 1527e1051a39Sopenharmony_ci} 1528e1051a39Sopenharmony_ci 1529e1051a39Sopenharmony_civoid *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov) 1530e1051a39Sopenharmony_ci{ 1531e1051a39Sopenharmony_ci if (prov != NULL) 1532e1051a39Sopenharmony_ci return prov->provctx; 1533e1051a39Sopenharmony_ci 1534e1051a39Sopenharmony_ci return NULL; 1535e1051a39Sopenharmony_ci} 1536e1051a39Sopenharmony_ci 1537e1051a39Sopenharmony_ciconst OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov) 1538e1051a39Sopenharmony_ci{ 1539e1051a39Sopenharmony_ci if (prov != NULL) 1540e1051a39Sopenharmony_ci return prov->dispatch; 1541e1051a39Sopenharmony_ci 1542e1051a39Sopenharmony_ci return NULL; 1543e1051a39Sopenharmony_ci} 1544e1051a39Sopenharmony_ci 1545e1051a39Sopenharmony_ciOSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov) 1546e1051a39Sopenharmony_ci{ 1547e1051a39Sopenharmony_ci return prov != NULL ? prov->libctx : NULL; 1548e1051a39Sopenharmony_ci} 1549e1051a39Sopenharmony_ci 1550e1051a39Sopenharmony_ci/* Wrappers around calls to the provider */ 1551e1051a39Sopenharmony_civoid ossl_provider_teardown(const OSSL_PROVIDER *prov) 1552e1051a39Sopenharmony_ci{ 1553e1051a39Sopenharmony_ci if (prov->teardown != NULL 1554e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1555e1051a39Sopenharmony_ci && !prov->ischild 1556e1051a39Sopenharmony_ci#endif 1557e1051a39Sopenharmony_ci ) 1558e1051a39Sopenharmony_ci prov->teardown(prov->provctx); 1559e1051a39Sopenharmony_ci} 1560e1051a39Sopenharmony_ci 1561e1051a39Sopenharmony_ciconst OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov) 1562e1051a39Sopenharmony_ci{ 1563e1051a39Sopenharmony_ci return prov->gettable_params == NULL 1564e1051a39Sopenharmony_ci ? NULL : prov->gettable_params(prov->provctx); 1565e1051a39Sopenharmony_ci} 1566e1051a39Sopenharmony_ci 1567e1051a39Sopenharmony_ciint ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) 1568e1051a39Sopenharmony_ci{ 1569e1051a39Sopenharmony_ci return prov->get_params == NULL 1570e1051a39Sopenharmony_ci ? 0 : prov->get_params(prov->provctx, params); 1571e1051a39Sopenharmony_ci} 1572e1051a39Sopenharmony_ci 1573e1051a39Sopenharmony_ciint ossl_provider_self_test(const OSSL_PROVIDER *prov) 1574e1051a39Sopenharmony_ci{ 1575e1051a39Sopenharmony_ci int ret; 1576e1051a39Sopenharmony_ci 1577e1051a39Sopenharmony_ci if (prov->self_test == NULL) 1578e1051a39Sopenharmony_ci return 1; 1579e1051a39Sopenharmony_ci ret = prov->self_test(prov->provctx); 1580e1051a39Sopenharmony_ci if (ret == 0) 1581e1051a39Sopenharmony_ci (void)provider_remove_store_methods((OSSL_PROVIDER *)prov); 1582e1051a39Sopenharmony_ci return ret; 1583e1051a39Sopenharmony_ci} 1584e1051a39Sopenharmony_ci 1585e1051a39Sopenharmony_ciint ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, 1586e1051a39Sopenharmony_ci const char *capability, 1587e1051a39Sopenharmony_ci OSSL_CALLBACK *cb, 1588e1051a39Sopenharmony_ci void *arg) 1589e1051a39Sopenharmony_ci{ 1590e1051a39Sopenharmony_ci return prov->get_capabilities == NULL 1591e1051a39Sopenharmony_ci ? 1 : prov->get_capabilities(prov->provctx, capability, cb, arg); 1592e1051a39Sopenharmony_ci} 1593e1051a39Sopenharmony_ci 1594e1051a39Sopenharmony_ciconst OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, 1595e1051a39Sopenharmony_ci int operation_id, 1596e1051a39Sopenharmony_ci int *no_cache) 1597e1051a39Sopenharmony_ci{ 1598e1051a39Sopenharmony_ci const OSSL_ALGORITHM *res; 1599e1051a39Sopenharmony_ci 1600e1051a39Sopenharmony_ci if (prov->query_operation == NULL) 1601e1051a39Sopenharmony_ci return NULL; 1602e1051a39Sopenharmony_ci res = prov->query_operation(prov->provctx, operation_id, no_cache); 1603e1051a39Sopenharmony_ci#if defined(OPENSSL_NO_CACHED_FETCH) 1604e1051a39Sopenharmony_ci /* Forcing the non-caching of queries */ 1605e1051a39Sopenharmony_ci if (no_cache != NULL) 1606e1051a39Sopenharmony_ci *no_cache = 1; 1607e1051a39Sopenharmony_ci#endif 1608e1051a39Sopenharmony_ci return res; 1609e1051a39Sopenharmony_ci} 1610e1051a39Sopenharmony_ci 1611e1051a39Sopenharmony_civoid ossl_provider_unquery_operation(const OSSL_PROVIDER *prov, 1612e1051a39Sopenharmony_ci int operation_id, 1613e1051a39Sopenharmony_ci const OSSL_ALGORITHM *algs) 1614e1051a39Sopenharmony_ci{ 1615e1051a39Sopenharmony_ci if (prov->unquery_operation != NULL) 1616e1051a39Sopenharmony_ci prov->unquery_operation(prov->provctx, operation_id, algs); 1617e1051a39Sopenharmony_ci} 1618e1051a39Sopenharmony_ci 1619e1051a39Sopenharmony_ciint ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) 1620e1051a39Sopenharmony_ci{ 1621e1051a39Sopenharmony_ci size_t byte = bitnum / 8; 1622e1051a39Sopenharmony_ci unsigned char bit = (1 << (bitnum % 8)) & 0xFF; 1623e1051a39Sopenharmony_ci 1624e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(provider->opbits_lock)) 1625e1051a39Sopenharmony_ci return 0; 1626e1051a39Sopenharmony_ci if (provider->operation_bits_sz <= byte) { 1627e1051a39Sopenharmony_ci unsigned char *tmp = OPENSSL_realloc(provider->operation_bits, 1628e1051a39Sopenharmony_ci byte + 1); 1629e1051a39Sopenharmony_ci 1630e1051a39Sopenharmony_ci if (tmp == NULL) { 1631e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(provider->opbits_lock); 1632e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 1633e1051a39Sopenharmony_ci return 0; 1634e1051a39Sopenharmony_ci } 1635e1051a39Sopenharmony_ci provider->operation_bits = tmp; 1636e1051a39Sopenharmony_ci memset(provider->operation_bits + provider->operation_bits_sz, 1637e1051a39Sopenharmony_ci '\0', byte + 1 - provider->operation_bits_sz); 1638e1051a39Sopenharmony_ci provider->operation_bits_sz = byte + 1; 1639e1051a39Sopenharmony_ci } 1640e1051a39Sopenharmony_ci provider->operation_bits[byte] |= bit; 1641e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(provider->opbits_lock); 1642e1051a39Sopenharmony_ci return 1; 1643e1051a39Sopenharmony_ci} 1644e1051a39Sopenharmony_ci 1645e1051a39Sopenharmony_ciint ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, 1646e1051a39Sopenharmony_ci int *result) 1647e1051a39Sopenharmony_ci{ 1648e1051a39Sopenharmony_ci size_t byte = bitnum / 8; 1649e1051a39Sopenharmony_ci unsigned char bit = (1 << (bitnum % 8)) & 0xFF; 1650e1051a39Sopenharmony_ci 1651e1051a39Sopenharmony_ci if (!ossl_assert(result != NULL)) { 1652e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); 1653e1051a39Sopenharmony_ci return 0; 1654e1051a39Sopenharmony_ci } 1655e1051a39Sopenharmony_ci 1656e1051a39Sopenharmony_ci *result = 0; 1657e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(provider->opbits_lock)) 1658e1051a39Sopenharmony_ci return 0; 1659e1051a39Sopenharmony_ci if (provider->operation_bits_sz > byte) 1660e1051a39Sopenharmony_ci *result = ((provider->operation_bits[byte] & bit) != 0); 1661e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(provider->opbits_lock); 1662e1051a39Sopenharmony_ci return 1; 1663e1051a39Sopenharmony_ci} 1664e1051a39Sopenharmony_ci 1665e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1666e1051a39Sopenharmony_ciconst OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov) 1667e1051a39Sopenharmony_ci{ 1668e1051a39Sopenharmony_ci return prov->handle; 1669e1051a39Sopenharmony_ci} 1670e1051a39Sopenharmony_ci 1671e1051a39Sopenharmony_ciint ossl_provider_is_child(const OSSL_PROVIDER *prov) 1672e1051a39Sopenharmony_ci{ 1673e1051a39Sopenharmony_ci return prov->ischild; 1674e1051a39Sopenharmony_ci} 1675e1051a39Sopenharmony_ci 1676e1051a39Sopenharmony_ciint ossl_provider_set_child(OSSL_PROVIDER *prov, const OSSL_CORE_HANDLE *handle) 1677e1051a39Sopenharmony_ci{ 1678e1051a39Sopenharmony_ci prov->handle = handle; 1679e1051a39Sopenharmony_ci prov->ischild = 1; 1680e1051a39Sopenharmony_ci 1681e1051a39Sopenharmony_ci return 1; 1682e1051a39Sopenharmony_ci} 1683e1051a39Sopenharmony_ci 1684e1051a39Sopenharmony_ciint ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props) 1685e1051a39Sopenharmony_ci{ 1686e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1687e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 1688e1051a39Sopenharmony_ci int i, max; 1689e1051a39Sopenharmony_ci OSSL_PROVIDER_CHILD_CB *child_cb; 1690e1051a39Sopenharmony_ci 1691e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) == NULL) 1692e1051a39Sopenharmony_ci return 0; 1693e1051a39Sopenharmony_ci 1694e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(store->lock)) 1695e1051a39Sopenharmony_ci return 0; 1696e1051a39Sopenharmony_ci 1697e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); 1698e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 1699e1051a39Sopenharmony_ci child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); 1700e1051a39Sopenharmony_ci child_cb->global_props_cb(props, child_cb->cbdata); 1701e1051a39Sopenharmony_ci } 1702e1051a39Sopenharmony_ci 1703e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1704e1051a39Sopenharmony_ci#endif 1705e1051a39Sopenharmony_ci return 1; 1706e1051a39Sopenharmony_ci} 1707e1051a39Sopenharmony_ci 1708e1051a39Sopenharmony_cistatic int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, 1709e1051a39Sopenharmony_ci int (*create_cb)( 1710e1051a39Sopenharmony_ci const OSSL_CORE_HANDLE *provider, 1711e1051a39Sopenharmony_ci void *cbdata), 1712e1051a39Sopenharmony_ci int (*remove_cb)( 1713e1051a39Sopenharmony_ci const OSSL_CORE_HANDLE *provider, 1714e1051a39Sopenharmony_ci void *cbdata), 1715e1051a39Sopenharmony_ci int (*global_props_cb)( 1716e1051a39Sopenharmony_ci const char *props, 1717e1051a39Sopenharmony_ci void *cbdata), 1718e1051a39Sopenharmony_ci void *cbdata) 1719e1051a39Sopenharmony_ci{ 1720e1051a39Sopenharmony_ci /* 1721e1051a39Sopenharmony_ci * This is really an OSSL_PROVIDER that we created and cast to 1722e1051a39Sopenharmony_ci * OSSL_CORE_HANDLE originally. Therefore it is safe to cast it back. 1723e1051a39Sopenharmony_ci */ 1724e1051a39Sopenharmony_ci OSSL_PROVIDER *thisprov = (OSSL_PROVIDER *)handle; 1725e1051a39Sopenharmony_ci OSSL_PROVIDER *prov; 1726e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = thisprov->libctx; 1727e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 1728e1051a39Sopenharmony_ci int ret = 0, i, max; 1729e1051a39Sopenharmony_ci OSSL_PROVIDER_CHILD_CB *child_cb; 1730e1051a39Sopenharmony_ci char *propsstr = NULL; 1731e1051a39Sopenharmony_ci 1732e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) == NULL) 1733e1051a39Sopenharmony_ci return 0; 1734e1051a39Sopenharmony_ci 1735e1051a39Sopenharmony_ci child_cb = OPENSSL_malloc(sizeof(*child_cb)); 1736e1051a39Sopenharmony_ci if (child_cb == NULL) 1737e1051a39Sopenharmony_ci return 0; 1738e1051a39Sopenharmony_ci child_cb->prov = thisprov; 1739e1051a39Sopenharmony_ci child_cb->create_cb = create_cb; 1740e1051a39Sopenharmony_ci child_cb->remove_cb = remove_cb; 1741e1051a39Sopenharmony_ci child_cb->global_props_cb = global_props_cb; 1742e1051a39Sopenharmony_ci child_cb->cbdata = cbdata; 1743e1051a39Sopenharmony_ci 1744e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) { 1745e1051a39Sopenharmony_ci OPENSSL_free(child_cb); 1746e1051a39Sopenharmony_ci return 0; 1747e1051a39Sopenharmony_ci } 1748e1051a39Sopenharmony_ci propsstr = evp_get_global_properties_str(libctx, 0); 1749e1051a39Sopenharmony_ci 1750e1051a39Sopenharmony_ci if (propsstr != NULL) { 1751e1051a39Sopenharmony_ci global_props_cb(propsstr, cbdata); 1752e1051a39Sopenharmony_ci OPENSSL_free(propsstr); 1753e1051a39Sopenharmony_ci } 1754e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_num(store->providers); 1755e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 1756e1051a39Sopenharmony_ci int activated; 1757e1051a39Sopenharmony_ci 1758e1051a39Sopenharmony_ci prov = sk_OSSL_PROVIDER_value(store->providers, i); 1759e1051a39Sopenharmony_ci 1760e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) 1761e1051a39Sopenharmony_ci break; 1762e1051a39Sopenharmony_ci activated = prov->flag_activated; 1763e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(prov->flag_lock); 1764e1051a39Sopenharmony_ci /* 1765e1051a39Sopenharmony_ci * We hold the store lock while calling the user callback. This means 1766e1051a39Sopenharmony_ci * that the user callback must be short and simple and not do anything 1767e1051a39Sopenharmony_ci * likely to cause a deadlock. We don't hold the flag_lock during this 1768e1051a39Sopenharmony_ci * call. In theory this means that another thread could deactivate it 1769e1051a39Sopenharmony_ci * while we are calling create. This is ok because the other thread 1770e1051a39Sopenharmony_ci * will also call remove_cb, but won't be able to do so until we release 1771e1051a39Sopenharmony_ci * the store lock. 1772e1051a39Sopenharmony_ci */ 1773e1051a39Sopenharmony_ci if (activated && !create_cb((OSSL_CORE_HANDLE *)prov, cbdata)) 1774e1051a39Sopenharmony_ci break; 1775e1051a39Sopenharmony_ci } 1776e1051a39Sopenharmony_ci if (i == max) { 1777e1051a39Sopenharmony_ci /* Success */ 1778e1051a39Sopenharmony_ci ret = sk_OSSL_PROVIDER_CHILD_CB_push(store->child_cbs, child_cb); 1779e1051a39Sopenharmony_ci } 1780e1051a39Sopenharmony_ci if (i != max || ret <= 0) { 1781e1051a39Sopenharmony_ci /* Failed during creation. Remove everything we just added */ 1782e1051a39Sopenharmony_ci for (; i >= 0; i--) { 1783e1051a39Sopenharmony_ci prov = sk_OSSL_PROVIDER_value(store->providers, i); 1784e1051a39Sopenharmony_ci remove_cb((OSSL_CORE_HANDLE *)prov, cbdata); 1785e1051a39Sopenharmony_ci } 1786e1051a39Sopenharmony_ci OPENSSL_free(child_cb); 1787e1051a39Sopenharmony_ci ret = 0; 1788e1051a39Sopenharmony_ci } 1789e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1790e1051a39Sopenharmony_ci 1791e1051a39Sopenharmony_ci return ret; 1792e1051a39Sopenharmony_ci} 1793e1051a39Sopenharmony_ci 1794e1051a39Sopenharmony_cistatic void ossl_provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle) 1795e1051a39Sopenharmony_ci{ 1796e1051a39Sopenharmony_ci /* 1797e1051a39Sopenharmony_ci * This is really an OSSL_PROVIDER that we created and cast to 1798e1051a39Sopenharmony_ci * OSSL_CORE_HANDLE originally. Therefore it is safe to cast it back. 1799e1051a39Sopenharmony_ci */ 1800e1051a39Sopenharmony_ci OSSL_PROVIDER *thisprov = (OSSL_PROVIDER *)handle; 1801e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = thisprov->libctx; 1802e1051a39Sopenharmony_ci struct provider_store_st *store = NULL; 1803e1051a39Sopenharmony_ci int i, max; 1804e1051a39Sopenharmony_ci OSSL_PROVIDER_CHILD_CB *child_cb; 1805e1051a39Sopenharmony_ci 1806e1051a39Sopenharmony_ci if ((store = get_provider_store(libctx)) == NULL) 1807e1051a39Sopenharmony_ci return; 1808e1051a39Sopenharmony_ci 1809e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(store->lock)) 1810e1051a39Sopenharmony_ci return; 1811e1051a39Sopenharmony_ci max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); 1812e1051a39Sopenharmony_ci for (i = 0; i < max; i++) { 1813e1051a39Sopenharmony_ci child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); 1814e1051a39Sopenharmony_ci if (child_cb->prov == thisprov) { 1815e1051a39Sopenharmony_ci /* Found an entry */ 1816e1051a39Sopenharmony_ci sk_OSSL_PROVIDER_CHILD_CB_delete(store->child_cbs, i); 1817e1051a39Sopenharmony_ci OPENSSL_free(child_cb); 1818e1051a39Sopenharmony_ci break; 1819e1051a39Sopenharmony_ci } 1820e1051a39Sopenharmony_ci } 1821e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(store->lock); 1822e1051a39Sopenharmony_ci} 1823e1051a39Sopenharmony_ci#endif 1824e1051a39Sopenharmony_ci 1825e1051a39Sopenharmony_ci/*- 1826e1051a39Sopenharmony_ci * Core functions for the provider 1827e1051a39Sopenharmony_ci * =============================== 1828e1051a39Sopenharmony_ci * 1829e1051a39Sopenharmony_ci * This is the set of functions that the core makes available to the provider 1830e1051a39Sopenharmony_ci */ 1831e1051a39Sopenharmony_ci 1832e1051a39Sopenharmony_ci/* 1833e1051a39Sopenharmony_ci * This returns a list of Provider Object parameters with their types, for 1834e1051a39Sopenharmony_ci * discovery. We do not expect that many providers will use this, but one 1835e1051a39Sopenharmony_ci * never knows. 1836e1051a39Sopenharmony_ci */ 1837e1051a39Sopenharmony_cistatic const OSSL_PARAM param_types[] = { 1838e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), 1839e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_PROV_NAME, OSSL_PARAM_UTF8_PTR, 1840e1051a39Sopenharmony_ci NULL, 0), 1841e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1842e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_MODULE_FILENAME, OSSL_PARAM_UTF8_PTR, 1843e1051a39Sopenharmony_ci NULL, 0), 1844e1051a39Sopenharmony_ci#endif 1845e1051a39Sopenharmony_ci OSSL_PARAM_END 1846e1051a39Sopenharmony_ci}; 1847e1051a39Sopenharmony_ci 1848e1051a39Sopenharmony_ci/* 1849e1051a39Sopenharmony_ci * Forward declare all the functions that are provided aa dispatch. 1850e1051a39Sopenharmony_ci * This ensures that the compiler will complain if they aren't defined 1851e1051a39Sopenharmony_ci * with the correct signature. 1852e1051a39Sopenharmony_ci */ 1853e1051a39Sopenharmony_cistatic OSSL_FUNC_core_gettable_params_fn core_gettable_params; 1854e1051a39Sopenharmony_cistatic OSSL_FUNC_core_get_params_fn core_get_params; 1855e1051a39Sopenharmony_cistatic OSSL_FUNC_core_get_libctx_fn core_get_libctx; 1856e1051a39Sopenharmony_cistatic OSSL_FUNC_core_thread_start_fn core_thread_start; 1857e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1858e1051a39Sopenharmony_cistatic OSSL_FUNC_core_new_error_fn core_new_error; 1859e1051a39Sopenharmony_cistatic OSSL_FUNC_core_set_error_debug_fn core_set_error_debug; 1860e1051a39Sopenharmony_cistatic OSSL_FUNC_core_vset_error_fn core_vset_error; 1861e1051a39Sopenharmony_cistatic OSSL_FUNC_core_set_error_mark_fn core_set_error_mark; 1862e1051a39Sopenharmony_cistatic OSSL_FUNC_core_clear_last_error_mark_fn core_clear_last_error_mark; 1863e1051a39Sopenharmony_cistatic OSSL_FUNC_core_pop_error_to_mark_fn core_pop_error_to_mark; 1864e1051a39Sopenharmony_ciOSSL_FUNC_BIO_new_file_fn ossl_core_bio_new_file; 1865e1051a39Sopenharmony_ciOSSL_FUNC_BIO_new_membuf_fn ossl_core_bio_new_mem_buf; 1866e1051a39Sopenharmony_ciOSSL_FUNC_BIO_read_ex_fn ossl_core_bio_read_ex; 1867e1051a39Sopenharmony_ciOSSL_FUNC_BIO_write_ex_fn ossl_core_bio_write_ex; 1868e1051a39Sopenharmony_ciOSSL_FUNC_BIO_gets_fn ossl_core_bio_gets; 1869e1051a39Sopenharmony_ciOSSL_FUNC_BIO_puts_fn ossl_core_bio_puts; 1870e1051a39Sopenharmony_ciOSSL_FUNC_BIO_up_ref_fn ossl_core_bio_up_ref; 1871e1051a39Sopenharmony_ciOSSL_FUNC_BIO_free_fn ossl_core_bio_free; 1872e1051a39Sopenharmony_ciOSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf; 1873e1051a39Sopenharmony_ciOSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf; 1874e1051a39Sopenharmony_cistatic OSSL_FUNC_self_test_cb_fn core_self_test_get_callback; 1875e1051a39Sopenharmony_ciOSSL_FUNC_get_entropy_fn ossl_rand_get_entropy; 1876e1051a39Sopenharmony_ciOSSL_FUNC_cleanup_entropy_fn ossl_rand_cleanup_entropy; 1877e1051a39Sopenharmony_ciOSSL_FUNC_get_nonce_fn ossl_rand_get_nonce; 1878e1051a39Sopenharmony_ciOSSL_FUNC_cleanup_nonce_fn ossl_rand_cleanup_nonce; 1879e1051a39Sopenharmony_ci#endif 1880e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_malloc_fn CRYPTO_malloc; 1881e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_zalloc_fn CRYPTO_zalloc; 1882e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_free_fn CRYPTO_free; 1883e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_clear_free_fn CRYPTO_clear_free; 1884e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_realloc_fn CRYPTO_realloc; 1885e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_clear_realloc_fn CRYPTO_clear_realloc; 1886e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_secure_malloc_fn CRYPTO_secure_malloc; 1887e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_secure_zalloc_fn CRYPTO_secure_zalloc; 1888e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_secure_free_fn CRYPTO_secure_free; 1889e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_secure_clear_free_fn CRYPTO_secure_clear_free; 1890e1051a39Sopenharmony_ciOSSL_FUNC_CRYPTO_secure_allocated_fn CRYPTO_secure_allocated; 1891e1051a39Sopenharmony_ciOSSL_FUNC_OPENSSL_cleanse_fn OPENSSL_cleanse; 1892e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1893e1051a39Sopenharmony_ciOSSL_FUNC_provider_register_child_cb_fn ossl_provider_register_child_cb; 1894e1051a39Sopenharmony_ciOSSL_FUNC_provider_deregister_child_cb_fn ossl_provider_deregister_child_cb; 1895e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_name_fn core_provider_get0_name; 1896e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_get0_provider_ctx_fn core_provider_get0_provider_ctx; 1897e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_get0_dispatch_fn core_provider_get0_dispatch; 1898e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_up_ref_fn core_provider_up_ref_intern; 1899e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_free_fn core_provider_free_intern; 1900e1051a39Sopenharmony_cistatic OSSL_FUNC_core_obj_add_sigid_fn core_obj_add_sigid; 1901e1051a39Sopenharmony_cistatic OSSL_FUNC_core_obj_create_fn core_obj_create; 1902e1051a39Sopenharmony_ci#endif 1903e1051a39Sopenharmony_ci 1904e1051a39Sopenharmony_cistatic const OSSL_PARAM *core_gettable_params(const OSSL_CORE_HANDLE *handle) 1905e1051a39Sopenharmony_ci{ 1906e1051a39Sopenharmony_ci return param_types; 1907e1051a39Sopenharmony_ci} 1908e1051a39Sopenharmony_ci 1909e1051a39Sopenharmony_cistatic int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]) 1910e1051a39Sopenharmony_ci{ 1911e1051a39Sopenharmony_ci int i; 1912e1051a39Sopenharmony_ci OSSL_PARAM *p; 1913e1051a39Sopenharmony_ci /* 1914e1051a39Sopenharmony_ci * We created this object originally and we know it is actually an 1915e1051a39Sopenharmony_ci * OSSL_PROVIDER *, so the cast is safe 1916e1051a39Sopenharmony_ci */ 1917e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; 1918e1051a39Sopenharmony_ci 1919e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_VERSION)) != NULL) 1920e1051a39Sopenharmony_ci OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR); 1921e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) 1922e1051a39Sopenharmony_ci OSSL_PARAM_set_utf8_ptr(p, prov->name); 1923e1051a39Sopenharmony_ci 1924e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1925e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, 1926e1051a39Sopenharmony_ci OSSL_PROV_PARAM_CORE_MODULE_FILENAME)) != NULL) 1927e1051a39Sopenharmony_ci OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov)); 1928e1051a39Sopenharmony_ci#endif 1929e1051a39Sopenharmony_ci 1930e1051a39Sopenharmony_ci if (prov->parameters == NULL) 1931e1051a39Sopenharmony_ci return 1; 1932e1051a39Sopenharmony_ci 1933e1051a39Sopenharmony_ci for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) { 1934e1051a39Sopenharmony_ci INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i); 1935e1051a39Sopenharmony_ci 1936e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL) 1937e1051a39Sopenharmony_ci OSSL_PARAM_set_utf8_ptr(p, pair->value); 1938e1051a39Sopenharmony_ci } 1939e1051a39Sopenharmony_ci return 1; 1940e1051a39Sopenharmony_ci} 1941e1051a39Sopenharmony_ci 1942e1051a39Sopenharmony_cistatic OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle) 1943e1051a39Sopenharmony_ci{ 1944e1051a39Sopenharmony_ci /* 1945e1051a39Sopenharmony_ci * We created this object originally and we know it is actually an 1946e1051a39Sopenharmony_ci * OSSL_PROVIDER *, so the cast is safe 1947e1051a39Sopenharmony_ci */ 1948e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; 1949e1051a39Sopenharmony_ci 1950e1051a39Sopenharmony_ci /* 1951e1051a39Sopenharmony_ci * Using ossl_provider_libctx would be wrong as that returns 1952e1051a39Sopenharmony_ci * NULL for |prov| == NULL and NULL libctx has a special meaning 1953e1051a39Sopenharmony_ci * that does not apply here. Here |prov| == NULL can happen only in 1954e1051a39Sopenharmony_ci * case of a coding error. 1955e1051a39Sopenharmony_ci */ 1956e1051a39Sopenharmony_ci assert(prov != NULL); 1957e1051a39Sopenharmony_ci return (OPENSSL_CORE_CTX *)prov->libctx; 1958e1051a39Sopenharmony_ci} 1959e1051a39Sopenharmony_ci 1960e1051a39Sopenharmony_cistatic int core_thread_start(const OSSL_CORE_HANDLE *handle, 1961e1051a39Sopenharmony_ci OSSL_thread_stop_handler_fn handfn, 1962e1051a39Sopenharmony_ci void *arg) 1963e1051a39Sopenharmony_ci{ 1964e1051a39Sopenharmony_ci /* 1965e1051a39Sopenharmony_ci * We created this object originally and we know it is actually an 1966e1051a39Sopenharmony_ci * OSSL_PROVIDER *, so the cast is safe 1967e1051a39Sopenharmony_ci */ 1968e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; 1969e1051a39Sopenharmony_ci 1970e1051a39Sopenharmony_ci return ossl_init_thread_start(prov, arg, handfn); 1971e1051a39Sopenharmony_ci} 1972e1051a39Sopenharmony_ci 1973e1051a39Sopenharmony_ci/* 1974e1051a39Sopenharmony_ci * The FIPS module inner provider doesn't implement these. They aren't 1975e1051a39Sopenharmony_ci * needed there, since the FIPS module upcalls are always the outer provider 1976e1051a39Sopenharmony_ci * ones. 1977e1051a39Sopenharmony_ci */ 1978e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 1979e1051a39Sopenharmony_ci/* 1980e1051a39Sopenharmony_ci * These error functions should use |handle| to select the proper 1981e1051a39Sopenharmony_ci * library context to report in the correct error stack if error 1982e1051a39Sopenharmony_ci * stacks become tied to the library context. 1983e1051a39Sopenharmony_ci * We cannot currently do that since there's no support for it in the 1984e1051a39Sopenharmony_ci * ERR subsystem. 1985e1051a39Sopenharmony_ci */ 1986e1051a39Sopenharmony_cistatic void core_new_error(const OSSL_CORE_HANDLE *handle) 1987e1051a39Sopenharmony_ci{ 1988e1051a39Sopenharmony_ci ERR_new(); 1989e1051a39Sopenharmony_ci} 1990e1051a39Sopenharmony_ci 1991e1051a39Sopenharmony_cistatic void core_set_error_debug(const OSSL_CORE_HANDLE *handle, 1992e1051a39Sopenharmony_ci const char *file, int line, const char *func) 1993e1051a39Sopenharmony_ci{ 1994e1051a39Sopenharmony_ci ERR_set_debug(file, line, func); 1995e1051a39Sopenharmony_ci} 1996e1051a39Sopenharmony_ci 1997e1051a39Sopenharmony_cistatic void core_vset_error(const OSSL_CORE_HANDLE *handle, 1998e1051a39Sopenharmony_ci uint32_t reason, const char *fmt, va_list args) 1999e1051a39Sopenharmony_ci{ 2000e1051a39Sopenharmony_ci /* 2001e1051a39Sopenharmony_ci * We created this object originally and we know it is actually an 2002e1051a39Sopenharmony_ci * OSSL_PROVIDER *, so the cast is safe 2003e1051a39Sopenharmony_ci */ 2004e1051a39Sopenharmony_ci OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; 2005e1051a39Sopenharmony_ci 2006e1051a39Sopenharmony_ci /* 2007e1051a39Sopenharmony_ci * If the uppermost 8 bits are non-zero, it's an OpenSSL library 2008e1051a39Sopenharmony_ci * error and will be treated as such. Otherwise, it's a new style 2009e1051a39Sopenharmony_ci * provider error and will be treated as such. 2010e1051a39Sopenharmony_ci */ 2011e1051a39Sopenharmony_ci if (ERR_GET_LIB(reason) != 0) { 2012e1051a39Sopenharmony_ci ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args); 2013e1051a39Sopenharmony_ci } else { 2014e1051a39Sopenharmony_ci ERR_vset_error(prov->error_lib, (int)reason, fmt, args); 2015e1051a39Sopenharmony_ci } 2016e1051a39Sopenharmony_ci} 2017e1051a39Sopenharmony_ci 2018e1051a39Sopenharmony_cistatic int core_set_error_mark(const OSSL_CORE_HANDLE *handle) 2019e1051a39Sopenharmony_ci{ 2020e1051a39Sopenharmony_ci return ERR_set_mark(); 2021e1051a39Sopenharmony_ci} 2022e1051a39Sopenharmony_ci 2023e1051a39Sopenharmony_cistatic int core_clear_last_error_mark(const OSSL_CORE_HANDLE *handle) 2024e1051a39Sopenharmony_ci{ 2025e1051a39Sopenharmony_ci return ERR_clear_last_mark(); 2026e1051a39Sopenharmony_ci} 2027e1051a39Sopenharmony_ci 2028e1051a39Sopenharmony_cistatic int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle) 2029e1051a39Sopenharmony_ci{ 2030e1051a39Sopenharmony_ci return ERR_pop_to_mark(); 2031e1051a39Sopenharmony_ci} 2032e1051a39Sopenharmony_ci 2033e1051a39Sopenharmony_cistatic void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx, 2034e1051a39Sopenharmony_ci OSSL_CALLBACK **cb, void **cbarg) 2035e1051a39Sopenharmony_ci{ 2036e1051a39Sopenharmony_ci OSSL_SELF_TEST_get_callback((OSSL_LIB_CTX *)libctx, cb, cbarg); 2037e1051a39Sopenharmony_ci} 2038e1051a39Sopenharmony_ci 2039e1051a39Sopenharmony_cistatic const char *core_provider_get0_name(const OSSL_CORE_HANDLE *prov) 2040e1051a39Sopenharmony_ci{ 2041e1051a39Sopenharmony_ci return OSSL_PROVIDER_get0_name((const OSSL_PROVIDER *)prov); 2042e1051a39Sopenharmony_ci} 2043e1051a39Sopenharmony_ci 2044e1051a39Sopenharmony_cistatic void *core_provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov) 2045e1051a39Sopenharmony_ci{ 2046e1051a39Sopenharmony_ci return OSSL_PROVIDER_get0_provider_ctx((const OSSL_PROVIDER *)prov); 2047e1051a39Sopenharmony_ci} 2048e1051a39Sopenharmony_ci 2049e1051a39Sopenharmony_cistatic const OSSL_DISPATCH * 2050e1051a39Sopenharmony_cicore_provider_get0_dispatch(const OSSL_CORE_HANDLE *prov) 2051e1051a39Sopenharmony_ci{ 2052e1051a39Sopenharmony_ci return OSSL_PROVIDER_get0_dispatch((const OSSL_PROVIDER *)prov); 2053e1051a39Sopenharmony_ci} 2054e1051a39Sopenharmony_ci 2055e1051a39Sopenharmony_cistatic int core_provider_up_ref_intern(const OSSL_CORE_HANDLE *prov, 2056e1051a39Sopenharmony_ci int activate) 2057e1051a39Sopenharmony_ci{ 2058e1051a39Sopenharmony_ci return provider_up_ref_intern((OSSL_PROVIDER *)prov, activate); 2059e1051a39Sopenharmony_ci} 2060e1051a39Sopenharmony_ci 2061e1051a39Sopenharmony_cistatic int core_provider_free_intern(const OSSL_CORE_HANDLE *prov, 2062e1051a39Sopenharmony_ci int deactivate) 2063e1051a39Sopenharmony_ci{ 2064e1051a39Sopenharmony_ci return provider_free_intern((OSSL_PROVIDER *)prov, deactivate); 2065e1051a39Sopenharmony_ci} 2066e1051a39Sopenharmony_ci 2067e1051a39Sopenharmony_cistatic int core_obj_add_sigid(const OSSL_CORE_HANDLE *prov, 2068e1051a39Sopenharmony_ci const char *sign_name, const char *digest_name, 2069e1051a39Sopenharmony_ci const char *pkey_name) 2070e1051a39Sopenharmony_ci{ 2071e1051a39Sopenharmony_ci int sign_nid = OBJ_txt2nid(sign_name); 2072e1051a39Sopenharmony_ci int digest_nid = NID_undef; 2073e1051a39Sopenharmony_ci int pkey_nid = OBJ_txt2nid(pkey_name); 2074e1051a39Sopenharmony_ci 2075e1051a39Sopenharmony_ci if (digest_name != NULL && digest_name[0] != '\0' 2076e1051a39Sopenharmony_ci && (digest_nid = OBJ_txt2nid(digest_name)) == NID_undef) 2077e1051a39Sopenharmony_ci return 0; 2078e1051a39Sopenharmony_ci 2079e1051a39Sopenharmony_ci if (sign_nid == NID_undef) 2080e1051a39Sopenharmony_ci return 0; 2081e1051a39Sopenharmony_ci 2082e1051a39Sopenharmony_ci /* 2083e1051a39Sopenharmony_ci * Check if it already exists. This is a success if so (even if we don't 2084e1051a39Sopenharmony_ci * have nids for the digest/pkey) 2085e1051a39Sopenharmony_ci */ 2086e1051a39Sopenharmony_ci if (OBJ_find_sigid_algs(sign_nid, NULL, NULL)) 2087e1051a39Sopenharmony_ci return 1; 2088e1051a39Sopenharmony_ci 2089e1051a39Sopenharmony_ci if (pkey_nid == NID_undef) 2090e1051a39Sopenharmony_ci return 0; 2091e1051a39Sopenharmony_ci 2092e1051a39Sopenharmony_ci return OBJ_add_sigid(sign_nid, digest_nid, pkey_nid); 2093e1051a39Sopenharmony_ci} 2094e1051a39Sopenharmony_ci 2095e1051a39Sopenharmony_cistatic int core_obj_create(const OSSL_CORE_HANDLE *prov, const char *oid, 2096e1051a39Sopenharmony_ci const char *sn, const char *ln) 2097e1051a39Sopenharmony_ci{ 2098e1051a39Sopenharmony_ci /* Check if it already exists and create it if not */ 2099e1051a39Sopenharmony_ci return OBJ_txt2nid(oid) != NID_undef 2100e1051a39Sopenharmony_ci || OBJ_create(oid, sn, ln) != NID_undef; 2101e1051a39Sopenharmony_ci} 2102e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 2103e1051a39Sopenharmony_ci 2104e1051a39Sopenharmony_ci/* 2105e1051a39Sopenharmony_ci * Functions provided by the core. 2106e1051a39Sopenharmony_ci */ 2107e1051a39Sopenharmony_cistatic const OSSL_DISPATCH core_dispatch_[] = { 2108e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, 2109e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, 2110e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_GET_LIBCTX, (void (*)(void))core_get_libctx }, 2111e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, 2112e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 2113e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, 2114e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug }, 2115e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error }, 2116e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_SET_ERROR_MARK, (void (*)(void))core_set_error_mark }, 2117e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK, 2118e1051a39Sopenharmony_ci (void (*)(void))core_clear_last_error_mark }, 2119e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark }, 2120e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file }, 2121e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf }, 2122e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex }, 2123e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))ossl_core_bio_write_ex }, 2124e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_GETS, (void (*)(void))ossl_core_bio_gets }, 2125e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_PUTS, (void (*)(void))ossl_core_bio_puts }, 2126e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_CTRL, (void (*)(void))ossl_core_bio_ctrl }, 2127e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_UP_REF, (void (*)(void))ossl_core_bio_up_ref }, 2128e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_FREE, (void (*)(void))ossl_core_bio_free }, 2129e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf }, 2130e1051a39Sopenharmony_ci { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, 2131e1051a39Sopenharmony_ci { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback }, 2132e1051a39Sopenharmony_ci { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy }, 2133e1051a39Sopenharmony_ci { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy }, 2134e1051a39Sopenharmony_ci { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce }, 2135e1051a39Sopenharmony_ci { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce }, 2136e1051a39Sopenharmony_ci#endif 2137e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, 2138e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, 2139e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_FREE, (void (*)(void))CRYPTO_free }, 2140e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_CLEAR_FREE, (void (*)(void))CRYPTO_clear_free }, 2141e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_REALLOC, (void (*)(void))CRYPTO_realloc }, 2142e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_CLEAR_REALLOC, (void (*)(void))CRYPTO_clear_realloc }, 2143e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_SECURE_MALLOC, (void (*)(void))CRYPTO_secure_malloc }, 2144e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_SECURE_ZALLOC, (void (*)(void))CRYPTO_secure_zalloc }, 2145e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_SECURE_FREE, (void (*)(void))CRYPTO_secure_free }, 2146e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE, 2147e1051a39Sopenharmony_ci (void (*)(void))CRYPTO_secure_clear_free }, 2148e1051a39Sopenharmony_ci { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED, 2149e1051a39Sopenharmony_ci (void (*)(void))CRYPTO_secure_allocated }, 2150e1051a39Sopenharmony_ci { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse }, 2151e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 2152e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB, 2153e1051a39Sopenharmony_ci (void (*)(void))ossl_provider_register_child_cb }, 2154e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB, 2155e1051a39Sopenharmony_ci (void (*)(void))ossl_provider_deregister_child_cb }, 2156e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_NAME, 2157e1051a39Sopenharmony_ci (void (*)(void))core_provider_get0_name }, 2158e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX, 2159e1051a39Sopenharmony_ci (void (*)(void))core_provider_get0_provider_ctx }, 2160e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_GET0_DISPATCH, 2161e1051a39Sopenharmony_ci (void (*)(void))core_provider_get0_dispatch }, 2162e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_UP_REF, 2163e1051a39Sopenharmony_ci (void (*)(void))core_provider_up_ref_intern }, 2164e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_FREE, 2165e1051a39Sopenharmony_ci (void (*)(void))core_provider_free_intern }, 2166e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_OBJ_ADD_SIGID, (void (*)(void))core_obj_add_sigid }, 2167e1051a39Sopenharmony_ci { OSSL_FUNC_CORE_OBJ_CREATE, (void (*)(void))core_obj_create }, 2168e1051a39Sopenharmony_ci#endif 2169e1051a39Sopenharmony_ci { 0, NULL } 2170e1051a39Sopenharmony_ci}; 2171e1051a39Sopenharmony_cistatic const OSSL_DISPATCH *core_dispatch = core_dispatch_; 2172