1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2016-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/* We need to use some engine deprecated APIs */ 11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci#include "e_os.h" 14e1051a39Sopenharmony_ci#include "crypto/cryptlib.h" 15e1051a39Sopenharmony_ci#include <openssl/err.h> 16e1051a39Sopenharmony_ci#include "crypto/rand.h" 17e1051a39Sopenharmony_ci#include "internal/bio.h" 18e1051a39Sopenharmony_ci#include <openssl/evp.h> 19e1051a39Sopenharmony_ci#include "crypto/evp.h" 20e1051a39Sopenharmony_ci#include "internal/conf.h" 21e1051a39Sopenharmony_ci#include "crypto/async.h" 22e1051a39Sopenharmony_ci#include "crypto/engine.h" 23e1051a39Sopenharmony_ci#include "internal/comp.h" 24e1051a39Sopenharmony_ci#include "internal/err.h" 25e1051a39Sopenharmony_ci#include "crypto/err.h" 26e1051a39Sopenharmony_ci#include "crypto/objects.h" 27e1051a39Sopenharmony_ci#include <stdlib.h> 28e1051a39Sopenharmony_ci#include <assert.h> 29e1051a39Sopenharmony_ci#include "internal/thread_once.h" 30e1051a39Sopenharmony_ci#include "crypto/dso_conf.h" 31e1051a39Sopenharmony_ci#include "internal/dso.h" 32e1051a39Sopenharmony_ci#include "crypto/store.h" 33e1051a39Sopenharmony_ci#include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */ 34e1051a39Sopenharmony_ci#include <openssl/trace.h> 35e1051a39Sopenharmony_ci#include "crypto/ctype.h" 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_cistatic int stopped = 0; 38e1051a39Sopenharmony_cistatic uint64_t optsdone = 0; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_citypedef struct ossl_init_stop_st OPENSSL_INIT_STOP; 41e1051a39Sopenharmony_cistruct ossl_init_stop_st { 42e1051a39Sopenharmony_ci void (*handler)(void); 43e1051a39Sopenharmony_ci OPENSSL_INIT_STOP *next; 44e1051a39Sopenharmony_ci}; 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_cistatic OPENSSL_INIT_STOP *stop_handlers = NULL; 47e1051a39Sopenharmony_ci/* Guards access to the optsdone variable on platforms without atomics */ 48e1051a39Sopenharmony_cistatic CRYPTO_RWLOCK *optsdone_lock = NULL; 49e1051a39Sopenharmony_ci/* Guards simultaneous INIT_LOAD_CONFIG calls with non-NULL settings */ 50e1051a39Sopenharmony_cistatic CRYPTO_RWLOCK *init_lock = NULL; 51e1051a39Sopenharmony_cistatic CRYPTO_THREAD_LOCAL in_init_config_local; 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_cistatic CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; 54e1051a39Sopenharmony_cistatic int base_inited = 0; 55e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_base) 56e1051a39Sopenharmony_ci{ 57e1051a39Sopenharmony_ci /* no need to init trace */ 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n"); 60e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_CRYPTO_MDEBUG 61e1051a39Sopenharmony_ci ossl_malloc_setup_failures(); 62e1051a39Sopenharmony_ci#endif 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci if ((optsdone_lock = CRYPTO_THREAD_lock_new()) == NULL 65e1051a39Sopenharmony_ci || (init_lock = CRYPTO_THREAD_lock_new()) == NULL) 66e1051a39Sopenharmony_ci goto err; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci OPENSSL_cpuid_setup(); 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci if (!ossl_init_thread()) 71e1051a39Sopenharmony_ci goto err; 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL)) 74e1051a39Sopenharmony_ci goto err; 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci base_inited = 1; 77e1051a39Sopenharmony_ci return 1; 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_cierr: 80e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "ossl_init_base failed!\n"); 81e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(optsdone_lock); 82e1051a39Sopenharmony_ci optsdone_lock = NULL; 83e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(init_lock); 84e1051a39Sopenharmony_ci init_lock = NULL; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci return 0; 87e1051a39Sopenharmony_ci} 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_cistatic CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT; 90e1051a39Sopenharmony_ci#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32) 91e1051a39Sopenharmony_cistatic int win32atexit(void) 92e1051a39Sopenharmony_ci{ 93e1051a39Sopenharmony_ci OPENSSL_cleanup(); 94e1051a39Sopenharmony_ci return 0; 95e1051a39Sopenharmony_ci} 96e1051a39Sopenharmony_ci#endif 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci#ifdef OPENSSL_INIT_DEBUG 101e1051a39Sopenharmony_ci fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n"); 102e1051a39Sopenharmony_ci#endif 103e1051a39Sopenharmony_ci#ifndef OPENSSL_SYS_UEFI 104e1051a39Sopenharmony_ci# if defined(_WIN32) && !defined(__BORLANDC__) 105e1051a39Sopenharmony_ci /* We use _onexit() in preference because it gets called on DLL unload */ 106e1051a39Sopenharmony_ci if (_onexit(win32atexit) == NULL) 107e1051a39Sopenharmony_ci return 0; 108e1051a39Sopenharmony_ci# else 109e1051a39Sopenharmony_ci if (atexit(OPENSSL_cleanup) != 0) 110e1051a39Sopenharmony_ci return 0; 111e1051a39Sopenharmony_ci# endif 112e1051a39Sopenharmony_ci#endif 113e1051a39Sopenharmony_ci 114e1051a39Sopenharmony_ci return 1; 115e1051a39Sopenharmony_ci} 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit, 118e1051a39Sopenharmony_ci ossl_init_register_atexit) 119e1051a39Sopenharmony_ci{ 120e1051a39Sopenharmony_ci#ifdef OPENSSL_INIT_DEBUG 121e1051a39Sopenharmony_ci fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n"); 122e1051a39Sopenharmony_ci#endif 123e1051a39Sopenharmony_ci /* Do nothing in this case */ 124e1051a39Sopenharmony_ci return 1; 125e1051a39Sopenharmony_ci} 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_cistatic CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT; 128e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) 129e1051a39Sopenharmony_ci{ 130e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n"); 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ci#if !defined(OPENSSL_USE_NODELETE) \ 133e1051a39Sopenharmony_ci && !defined(OPENSSL_NO_PINSHARED) 134e1051a39Sopenharmony_ci# if defined(DSO_WIN32) && !defined(_WIN32_WCE) 135e1051a39Sopenharmony_ci { 136e1051a39Sopenharmony_ci HMODULE handle = NULL; 137e1051a39Sopenharmony_ci BOOL ret; 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci /* We don't use the DSO route for WIN32 because there is a better way */ 140e1051a39Sopenharmony_ci ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 141e1051a39Sopenharmony_ci | GET_MODULE_HANDLE_EX_FLAG_PIN, 142e1051a39Sopenharmony_ci (void *)&base_inited, &handle); 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci OSSL_TRACE1(INIT, 145e1051a39Sopenharmony_ci "ossl_init_load_crypto_nodelete: " 146e1051a39Sopenharmony_ci "obtained DSO reference? %s\n", 147e1051a39Sopenharmony_ci (ret == TRUE ? "No!" : "Yes.")); 148e1051a39Sopenharmony_ci return (ret == TRUE) ? 1 : 0; 149e1051a39Sopenharmony_ci } 150e1051a39Sopenharmony_ci# elif !defined(DSO_NONE) 151e1051a39Sopenharmony_ci /* 152e1051a39Sopenharmony_ci * Deliberately leak a reference to ourselves. This will force the library 153e1051a39Sopenharmony_ci * to remain loaded until the atexit() handler is run at process exit. 154e1051a39Sopenharmony_ci */ 155e1051a39Sopenharmony_ci { 156e1051a39Sopenharmony_ci DSO *dso; 157e1051a39Sopenharmony_ci void *err; 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci if (!err_shelve_state(&err)) 160e1051a39Sopenharmony_ci return 0; 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); 163e1051a39Sopenharmony_ci /* 164e1051a39Sopenharmony_ci * In case of No!, it is uncertain our exit()-handlers can still be 165e1051a39Sopenharmony_ci * called. After dlclose() the whole library might have been unloaded 166e1051a39Sopenharmony_ci * already. 167e1051a39Sopenharmony_ci */ 168e1051a39Sopenharmony_ci OSSL_TRACE1(INIT, "obtained DSO reference? %s\n", 169e1051a39Sopenharmony_ci (dso == NULL ? "No!" : "Yes.")); 170e1051a39Sopenharmony_ci DSO_free(dso); 171e1051a39Sopenharmony_ci err_unshelve_state(err); 172e1051a39Sopenharmony_ci } 173e1051a39Sopenharmony_ci# endif 174e1051a39Sopenharmony_ci#endif 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci return 1; 177e1051a39Sopenharmony_ci} 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_cistatic CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT; 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) 182e1051a39Sopenharmony_ci{ 183e1051a39Sopenharmony_ci int ret = 1; 184e1051a39Sopenharmony_ci /* 185e1051a39Sopenharmony_ci * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time 186e1051a39Sopenharmony_ci * pulling in all the error strings during static linking 187e1051a39Sopenharmony_ci */ 188e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) 189e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n"); 190e1051a39Sopenharmony_ci ret = ossl_err_load_crypto_strings(); 191e1051a39Sopenharmony_ci#endif 192e1051a39Sopenharmony_ci return ret; 193e1051a39Sopenharmony_ci} 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings, 196e1051a39Sopenharmony_ci ossl_init_load_crypto_strings) 197e1051a39Sopenharmony_ci{ 198e1051a39Sopenharmony_ci /* Do nothing in this case */ 199e1051a39Sopenharmony_ci return 1; 200e1051a39Sopenharmony_ci} 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_cistatic CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT; 203e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) 204e1051a39Sopenharmony_ci{ 205e1051a39Sopenharmony_ci /* 206e1051a39Sopenharmony_ci * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 207e1051a39Sopenharmony_ci * pulling in all the ciphers during static linking 208e1051a39Sopenharmony_ci */ 209e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_AUTOALGINIT 210e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n"); 211e1051a39Sopenharmony_ci openssl_add_all_ciphers_int(); 212e1051a39Sopenharmony_ci#endif 213e1051a39Sopenharmony_ci return 1; 214e1051a39Sopenharmony_ci} 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers, 217e1051a39Sopenharmony_ci ossl_init_add_all_ciphers) 218e1051a39Sopenharmony_ci{ 219e1051a39Sopenharmony_ci /* Do nothing */ 220e1051a39Sopenharmony_ci return 1; 221e1051a39Sopenharmony_ci} 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_cistatic CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT; 224e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) 225e1051a39Sopenharmony_ci{ 226e1051a39Sopenharmony_ci /* 227e1051a39Sopenharmony_ci * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 228e1051a39Sopenharmony_ci * pulling in all the ciphers during static linking 229e1051a39Sopenharmony_ci */ 230e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_AUTOALGINIT 231e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "openssl_add_all_digests()\n"); 232e1051a39Sopenharmony_ci openssl_add_all_digests_int(); 233e1051a39Sopenharmony_ci#endif 234e1051a39Sopenharmony_ci return 1; 235e1051a39Sopenharmony_ci} 236e1051a39Sopenharmony_ci 237e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests, 238e1051a39Sopenharmony_ci ossl_init_add_all_digests) 239e1051a39Sopenharmony_ci{ 240e1051a39Sopenharmony_ci /* Do nothing */ 241e1051a39Sopenharmony_ci return 1; 242e1051a39Sopenharmony_ci} 243e1051a39Sopenharmony_ci 244e1051a39Sopenharmony_cistatic CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; 245e1051a39Sopenharmony_cistatic int config_inited = 0; 246e1051a39Sopenharmony_cistatic const OPENSSL_INIT_SETTINGS *conf_settings = NULL; 247e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_config) 248e1051a39Sopenharmony_ci{ 249e1051a39Sopenharmony_ci int ret = ossl_config_int(NULL); 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ci config_inited = 1; 252e1051a39Sopenharmony_ci return ret; 253e1051a39Sopenharmony_ci} 254e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config) 255e1051a39Sopenharmony_ci{ 256e1051a39Sopenharmony_ci int ret = ossl_config_int(conf_settings); 257e1051a39Sopenharmony_ci 258e1051a39Sopenharmony_ci config_inited = 1; 259e1051a39Sopenharmony_ci return ret; 260e1051a39Sopenharmony_ci} 261e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config) 262e1051a39Sopenharmony_ci{ 263e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "ossl_no_config_int()\n"); 264e1051a39Sopenharmony_ci ossl_no_config_int(); 265e1051a39Sopenharmony_ci config_inited = 1; 266e1051a39Sopenharmony_ci return 1; 267e1051a39Sopenharmony_ci} 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_cistatic CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT; 270e1051a39Sopenharmony_cistatic int async_inited = 0; 271e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_async) 272e1051a39Sopenharmony_ci{ 273e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "async_init()\n"); 274e1051a39Sopenharmony_ci if (!async_init()) 275e1051a39Sopenharmony_ci return 0; 276e1051a39Sopenharmony_ci async_inited = 1; 277e1051a39Sopenharmony_ci return 1; 278e1051a39Sopenharmony_ci} 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 281e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT; 282e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) 283e1051a39Sopenharmony_ci{ 284e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_openssl_int()\n"); 285e1051a39Sopenharmony_ci engine_load_openssl_int(); 286e1051a39Sopenharmony_ci return 1; 287e1051a39Sopenharmony_ci} 288e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_RDRAND 289e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; 290e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) 291e1051a39Sopenharmony_ci{ 292e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_rdrand_int()\n"); 293e1051a39Sopenharmony_ci engine_load_rdrand_int(); 294e1051a39Sopenharmony_ci return 1; 295e1051a39Sopenharmony_ci} 296e1051a39Sopenharmony_ci# endif 297e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT; 298e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) 299e1051a39Sopenharmony_ci{ 300e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_dynamic_int()\n"); 301e1051a39Sopenharmony_ci engine_load_dynamic_int(); 302e1051a39Sopenharmony_ci return 1; 303e1051a39Sopenharmony_ci} 304e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_STATIC_ENGINE 305e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DEVCRYPTOENG 306e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; 307e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) 308e1051a39Sopenharmony_ci{ 309e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n"); 310e1051a39Sopenharmony_ci engine_load_devcrypto_int(); 311e1051a39Sopenharmony_ci return 1; 312e1051a39Sopenharmony_ci} 313e1051a39Sopenharmony_ci# endif 314e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_PADLOCKENG) 315e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; 316e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) 317e1051a39Sopenharmony_ci{ 318e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_padlock_int()\n"); 319e1051a39Sopenharmony_ci engine_load_padlock_int(); 320e1051a39Sopenharmony_ci return 1; 321e1051a39Sopenharmony_ci} 322e1051a39Sopenharmony_ci# endif 323e1051a39Sopenharmony_ci# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 324e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT; 325e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) 326e1051a39Sopenharmony_ci{ 327e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_capi_int()\n"); 328e1051a39Sopenharmony_ci engine_load_capi_int(); 329e1051a39Sopenharmony_ci return 1; 330e1051a39Sopenharmony_ci} 331e1051a39Sopenharmony_ci# endif 332e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_AFALGENG) 333e1051a39Sopenharmony_cistatic CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT; 334e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) 335e1051a39Sopenharmony_ci{ 336e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "engine_load_afalg_int()\n"); 337e1051a39Sopenharmony_ci engine_load_afalg_int(); 338e1051a39Sopenharmony_ci return 1; 339e1051a39Sopenharmony_ci} 340e1051a39Sopenharmony_ci# endif 341e1051a39Sopenharmony_ci# endif 342e1051a39Sopenharmony_ci#endif 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_civoid OPENSSL_cleanup(void) 345e1051a39Sopenharmony_ci{ 346e1051a39Sopenharmony_ci OPENSSL_INIT_STOP *currhandler, *lasthandler; 347e1051a39Sopenharmony_ci 348e1051a39Sopenharmony_ci /* 349e1051a39Sopenharmony_ci * At some point we should consider looking at this function with a view to 350e1051a39Sopenharmony_ci * moving most/all of this into onfree handlers in OSSL_LIB_CTX. 351e1051a39Sopenharmony_ci */ 352e1051a39Sopenharmony_ci 353e1051a39Sopenharmony_ci /* If we've not been inited then no need to deinit */ 354e1051a39Sopenharmony_ci if (!base_inited) 355e1051a39Sopenharmony_ci return; 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci /* Might be explicitly called and also by atexit */ 358e1051a39Sopenharmony_ci if (stopped) 359e1051a39Sopenharmony_ci return; 360e1051a39Sopenharmony_ci stopped = 1; 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci /* 363e1051a39Sopenharmony_ci * Thread stop may not get automatically called by the thread library for 364e1051a39Sopenharmony_ci * the very last thread in some situations, so call it directly. 365e1051a39Sopenharmony_ci */ 366e1051a39Sopenharmony_ci OPENSSL_thread_stop(); 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci currhandler = stop_handlers; 369e1051a39Sopenharmony_ci while (currhandler != NULL) { 370e1051a39Sopenharmony_ci currhandler->handler(); 371e1051a39Sopenharmony_ci lasthandler = currhandler; 372e1051a39Sopenharmony_ci currhandler = currhandler->next; 373e1051a39Sopenharmony_ci OPENSSL_free(lasthandler); 374e1051a39Sopenharmony_ci } 375e1051a39Sopenharmony_ci stop_handlers = NULL; 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(optsdone_lock); 378e1051a39Sopenharmony_ci optsdone_lock = NULL; 379e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(init_lock); 380e1051a39Sopenharmony_ci init_lock = NULL; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci CRYPTO_THREAD_cleanup_local(&in_init_config_local); 383e1051a39Sopenharmony_ci 384e1051a39Sopenharmony_ci /* 385e1051a39Sopenharmony_ci * We assume we are single-threaded for this function, i.e. no race 386e1051a39Sopenharmony_ci * conditions for the various "*_inited" vars below. 387e1051a39Sopenharmony_ci */ 388e1051a39Sopenharmony_ci 389e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_COMP 390e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n"); 391e1051a39Sopenharmony_ci ossl_comp_zlib_cleanup(); 392e1051a39Sopenharmony_ci#endif 393e1051a39Sopenharmony_ci 394e1051a39Sopenharmony_ci if (async_inited) { 395e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n"); 396e1051a39Sopenharmony_ci async_deinit(); 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci /* 400e1051a39Sopenharmony_ci * Note that cleanup order is important: 401e1051a39Sopenharmony_ci * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so 402e1051a39Sopenharmony_ci * must be called before engine_cleanup_int() 403e1051a39Sopenharmony_ci * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up 404e1051a39Sopenharmony_ci * before the ex data handlers are wiped during default ossl_lib_ctx deinit. 405e1051a39Sopenharmony_ci * - ossl_config_modules_free() can end up in ENGINE code so must be called 406e1051a39Sopenharmony_ci * before engine_cleanup_int() 407e1051a39Sopenharmony_ci * - ENGINEs and additional EVP algorithms might use added OIDs names so 408e1051a39Sopenharmony_ci * ossl_obj_cleanup_int() must be called last 409e1051a39Sopenharmony_ci */ 410e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n"); 411e1051a39Sopenharmony_ci ossl_rand_cleanup_int(); 412e1051a39Sopenharmony_ci 413e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n"); 414e1051a39Sopenharmony_ci ossl_config_modules_free(); 415e1051a39Sopenharmony_ci 416e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 417e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n"); 418e1051a39Sopenharmony_ci engine_cleanup_int(); 419e1051a39Sopenharmony_ci#endif 420e1051a39Sopenharmony_ci 421e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DEPRECATED_3_0 422e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n"); 423e1051a39Sopenharmony_ci ossl_store_cleanup_int(); 424e1051a39Sopenharmony_ci#endif 425e1051a39Sopenharmony_ci 426e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n"); 427e1051a39Sopenharmony_ci ossl_lib_ctx_default_deinit(); 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_ci ossl_cleanup_thread(); 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n"); 432e1051a39Sopenharmony_ci bio_cleanup(); 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n"); 435e1051a39Sopenharmony_ci evp_cleanup_int(); 436e1051a39Sopenharmony_ci 437e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n"); 438e1051a39Sopenharmony_ci ossl_obj_cleanup_int(); 439e1051a39Sopenharmony_ci 440e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n"); 441e1051a39Sopenharmony_ci err_cleanup(); 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n"); 444e1051a39Sopenharmony_ci CRYPTO_secure_malloc_done(); 445e1051a39Sopenharmony_ci 446e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_CMP 447e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n"); 448e1051a39Sopenharmony_ci OSSL_CMP_log_close(); 449e1051a39Sopenharmony_ci#endif 450e1051a39Sopenharmony_ci 451e1051a39Sopenharmony_ci OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n"); 452e1051a39Sopenharmony_ci ossl_trace_cleanup(); 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci base_inited = 0; 455e1051a39Sopenharmony_ci} 456e1051a39Sopenharmony_ci 457e1051a39Sopenharmony_ci/* 458e1051a39Sopenharmony_ci * If this function is called with a non NULL settings value then it must be 459e1051a39Sopenharmony_ci * called prior to any threads making calls to any OpenSSL functions, 460e1051a39Sopenharmony_ci * i.e. passing a non-null settings value is assumed to be single-threaded. 461e1051a39Sopenharmony_ci */ 462e1051a39Sopenharmony_ciint OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) 463e1051a39Sopenharmony_ci{ 464e1051a39Sopenharmony_ci uint64_t tmp; 465e1051a39Sopenharmony_ci int aloaddone = 0; 466e1051a39Sopenharmony_ci 467e1051a39Sopenharmony_ci /* Applications depend on 0 being returned when cleanup was already done */ 468e1051a39Sopenharmony_ci if (stopped) { 469e1051a39Sopenharmony_ci if (!(opts & OPENSSL_INIT_BASE_ONLY)) 470e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL); 471e1051a39Sopenharmony_ci return 0; 472e1051a39Sopenharmony_ci } 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ci /* 475e1051a39Sopenharmony_ci * We ignore failures from this function. It is probably because we are 476e1051a39Sopenharmony_ci * on a platform that doesn't support lockless atomic loads (we may not 477e1051a39Sopenharmony_ci * have created optsdone_lock yet so we can't use it). This is just an 478e1051a39Sopenharmony_ci * optimisation to skip the full checks in this function if we don't need 479e1051a39Sopenharmony_ci * to, so we carry on regardless in the event of failure. 480e1051a39Sopenharmony_ci * 481e1051a39Sopenharmony_ci * There could be a race here with other threads, so that optsdone has not 482e1051a39Sopenharmony_ci * been updated yet, even though the options have in fact been initialised. 483e1051a39Sopenharmony_ci * This doesn't matter - it just means we will run the full function 484e1051a39Sopenharmony_ci * unnecessarily - but all the critical code is contained in RUN_ONCE 485e1051a39Sopenharmony_ci * functions anyway so we are safe. 486e1051a39Sopenharmony_ci */ 487e1051a39Sopenharmony_ci if (CRYPTO_atomic_load(&optsdone, &tmp, NULL)) { 488e1051a39Sopenharmony_ci if ((tmp & opts) == opts) 489e1051a39Sopenharmony_ci return 1; 490e1051a39Sopenharmony_ci aloaddone = 1; 491e1051a39Sopenharmony_ci } 492e1051a39Sopenharmony_ci 493e1051a39Sopenharmony_ci /* 494e1051a39Sopenharmony_ci * At some point we should look at this function with a view to moving 495e1051a39Sopenharmony_ci * most/all of this into OSSL_LIB_CTX. 496e1051a39Sopenharmony_ci * 497e1051a39Sopenharmony_ci * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the 498e1051a39Sopenharmony_ci * *only* option specified. With that option we return immediately after 499e1051a39Sopenharmony_ci * doing the requested limited initialization. Note that 500e1051a39Sopenharmony_ci * err_shelve_state() called by us via ossl_init_load_crypto_nodelete() 501e1051a39Sopenharmony_ci * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with 502e1051a39Sopenharmony_ci * base already initialized this is a harmless NOOP. 503e1051a39Sopenharmony_ci * 504e1051a39Sopenharmony_ci * If we remain the only caller of err_shelve_state() the recursion should 505e1051a39Sopenharmony_ci * perhaps be removed, but if in doubt, it can be left in place. 506e1051a39Sopenharmony_ci */ 507e1051a39Sopenharmony_ci if (!RUN_ONCE(&base, ossl_init_base)) 508e1051a39Sopenharmony_ci return 0; 509e1051a39Sopenharmony_ci 510e1051a39Sopenharmony_ci if (opts & OPENSSL_INIT_BASE_ONLY) 511e1051a39Sopenharmony_ci return 1; 512e1051a39Sopenharmony_ci 513e1051a39Sopenharmony_ci /* 514e1051a39Sopenharmony_ci * optsdone_lock should definitely be set up now, so we can now repeat the 515e1051a39Sopenharmony_ci * same check from above but be sure that it will work even on platforms 516e1051a39Sopenharmony_ci * without lockless CRYPTO_atomic_load 517e1051a39Sopenharmony_ci */ 518e1051a39Sopenharmony_ci if (!aloaddone) { 519e1051a39Sopenharmony_ci if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock)) 520e1051a39Sopenharmony_ci return 0; 521e1051a39Sopenharmony_ci if ((tmp & opts) == opts) 522e1051a39Sopenharmony_ci return 1; 523e1051a39Sopenharmony_ci } 524e1051a39Sopenharmony_ci 525e1051a39Sopenharmony_ci /* 526e1051a39Sopenharmony_ci * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls 527e1051a39Sopenharmony_ci * should not have the side-effect of setting up exit handlers, and 528e1051a39Sopenharmony_ci * therefore, this code block is below the INIT_BASE_ONLY-conditioned early 529e1051a39Sopenharmony_ci * return above. 530e1051a39Sopenharmony_ci */ 531e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) { 532e1051a39Sopenharmony_ci if (!RUN_ONCE_ALT(®ister_atexit, ossl_init_no_register_atexit, 533e1051a39Sopenharmony_ci ossl_init_register_atexit)) 534e1051a39Sopenharmony_ci return 0; 535e1051a39Sopenharmony_ci } else if (!RUN_ONCE(®ister_atexit, ossl_init_register_atexit)) { 536e1051a39Sopenharmony_ci return 0; 537e1051a39Sopenharmony_ci } 538e1051a39Sopenharmony_ci 539e1051a39Sopenharmony_ci if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete)) 540e1051a39Sopenharmony_ci return 0; 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) 543e1051a39Sopenharmony_ci && !RUN_ONCE_ALT(&load_crypto_strings, 544e1051a39Sopenharmony_ci ossl_init_no_load_crypto_strings, 545e1051a39Sopenharmony_ci ossl_init_load_crypto_strings)) 546e1051a39Sopenharmony_ci return 0; 547e1051a39Sopenharmony_ci 548e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS) 549e1051a39Sopenharmony_ci && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings)) 550e1051a39Sopenharmony_ci return 0; 551e1051a39Sopenharmony_ci 552e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS) 553e1051a39Sopenharmony_ci && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers, 554e1051a39Sopenharmony_ci ossl_init_add_all_ciphers)) 555e1051a39Sopenharmony_ci return 0; 556e1051a39Sopenharmony_ci 557e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS) 558e1051a39Sopenharmony_ci && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers)) 559e1051a39Sopenharmony_ci return 0; 560e1051a39Sopenharmony_ci 561e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS) 562e1051a39Sopenharmony_ci && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests, 563e1051a39Sopenharmony_ci ossl_init_add_all_digests)) 564e1051a39Sopenharmony_ci return 0; 565e1051a39Sopenharmony_ci 566e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS) 567e1051a39Sopenharmony_ci && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests)) 568e1051a39Sopenharmony_ci return 0; 569e1051a39Sopenharmony_ci 570e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ATFORK) 571e1051a39Sopenharmony_ci && !openssl_init_fork_handlers()) 572e1051a39Sopenharmony_ci return 0; 573e1051a39Sopenharmony_ci 574e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) 575e1051a39Sopenharmony_ci && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config)) 576e1051a39Sopenharmony_ci return 0; 577e1051a39Sopenharmony_ci 578e1051a39Sopenharmony_ci if (opts & OPENSSL_INIT_LOAD_CONFIG) { 579e1051a39Sopenharmony_ci int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL; 580e1051a39Sopenharmony_ci 581e1051a39Sopenharmony_ci /* If called recursively from OBJ_ calls, just skip it. */ 582e1051a39Sopenharmony_ci if (!loading) { 583e1051a39Sopenharmony_ci int ret; 584e1051a39Sopenharmony_ci 585e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1)) 586e1051a39Sopenharmony_ci return 0; 587e1051a39Sopenharmony_ci if (settings == NULL) { 588e1051a39Sopenharmony_ci ret = RUN_ONCE(&config, ossl_init_config); 589e1051a39Sopenharmony_ci } else { 590e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(init_lock)) 591e1051a39Sopenharmony_ci return 0; 592e1051a39Sopenharmony_ci conf_settings = settings; 593e1051a39Sopenharmony_ci ret = RUN_ONCE_ALT(&config, ossl_init_config_settings, 594e1051a39Sopenharmony_ci ossl_init_config); 595e1051a39Sopenharmony_ci conf_settings = NULL; 596e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(init_lock); 597e1051a39Sopenharmony_ci } 598e1051a39Sopenharmony_ci 599e1051a39Sopenharmony_ci if (ret <= 0) 600e1051a39Sopenharmony_ci return 0; 601e1051a39Sopenharmony_ci } 602e1051a39Sopenharmony_ci } 603e1051a39Sopenharmony_ci 604e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ASYNC) 605e1051a39Sopenharmony_ci && !RUN_ONCE(&async, ossl_init_async)) 606e1051a39Sopenharmony_ci return 0; 607e1051a39Sopenharmony_ci 608e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 609e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) 610e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) 611e1051a39Sopenharmony_ci return 0; 612e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_RDRAND 613e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_RDRAND) 614e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) 615e1051a39Sopenharmony_ci return 0; 616e1051a39Sopenharmony_ci# endif 617e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC) 618e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) 619e1051a39Sopenharmony_ci return 0; 620e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_STATIC_ENGINE 621e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DEVCRYPTOENG 622e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) 623e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) 624e1051a39Sopenharmony_ci return 0; 625e1051a39Sopenharmony_ci# endif 626e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_PADLOCKENG) 627e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) 628e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) 629e1051a39Sopenharmony_ci return 0; 630e1051a39Sopenharmony_ci# endif 631e1051a39Sopenharmony_ci# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 632e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_CAPI) 633e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_capi, ossl_init_engine_capi)) 634e1051a39Sopenharmony_ci return 0; 635e1051a39Sopenharmony_ci# endif 636e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_AFALGENG) 637e1051a39Sopenharmony_ci if ((opts & OPENSSL_INIT_ENGINE_AFALG) 638e1051a39Sopenharmony_ci && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg)) 639e1051a39Sopenharmony_ci return 0; 640e1051a39Sopenharmony_ci# endif 641e1051a39Sopenharmony_ci# endif 642e1051a39Sopenharmony_ci if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN 643e1051a39Sopenharmony_ci | OPENSSL_INIT_ENGINE_OPENSSL 644e1051a39Sopenharmony_ci | OPENSSL_INIT_ENGINE_AFALG)) { 645e1051a39Sopenharmony_ci ENGINE_register_all_complete(); 646e1051a39Sopenharmony_ci } 647e1051a39Sopenharmony_ci#endif 648e1051a39Sopenharmony_ci 649e1051a39Sopenharmony_ci if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock)) 650e1051a39Sopenharmony_ci return 0; 651e1051a39Sopenharmony_ci 652e1051a39Sopenharmony_ci return 1; 653e1051a39Sopenharmony_ci} 654e1051a39Sopenharmony_ci 655e1051a39Sopenharmony_ciint OPENSSL_atexit(void (*handler)(void)) 656e1051a39Sopenharmony_ci{ 657e1051a39Sopenharmony_ci OPENSSL_INIT_STOP *newhand; 658e1051a39Sopenharmony_ci 659e1051a39Sopenharmony_ci#if !defined(OPENSSL_USE_NODELETE)\ 660e1051a39Sopenharmony_ci && !defined(OPENSSL_NO_PINSHARED) 661e1051a39Sopenharmony_ci { 662e1051a39Sopenharmony_ci# if defined(DSO_WIN32) && !defined(_WIN32_WCE) 663e1051a39Sopenharmony_ci HMODULE handle = NULL; 664e1051a39Sopenharmony_ci BOOL ret; 665e1051a39Sopenharmony_ci union { 666e1051a39Sopenharmony_ci void *sym; 667e1051a39Sopenharmony_ci void (*func)(void); 668e1051a39Sopenharmony_ci } handlersym; 669e1051a39Sopenharmony_ci 670e1051a39Sopenharmony_ci handlersym.func = handler; 671e1051a39Sopenharmony_ci 672e1051a39Sopenharmony_ci /* 673e1051a39Sopenharmony_ci * We don't use the DSO route for WIN32 because there is a better 674e1051a39Sopenharmony_ci * way 675e1051a39Sopenharmony_ci */ 676e1051a39Sopenharmony_ci ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 677e1051a39Sopenharmony_ci | GET_MODULE_HANDLE_EX_FLAG_PIN, 678e1051a39Sopenharmony_ci handlersym.sym, &handle); 679e1051a39Sopenharmony_ci 680e1051a39Sopenharmony_ci if (!ret) 681e1051a39Sopenharmony_ci return 0; 682e1051a39Sopenharmony_ci# elif !defined(DSO_NONE) 683e1051a39Sopenharmony_ci /* 684e1051a39Sopenharmony_ci * Deliberately leak a reference to the handler. This will force the 685e1051a39Sopenharmony_ci * library/code containing the handler to remain loaded until we run the 686e1051a39Sopenharmony_ci * atexit handler. If -znodelete has been used then this is 687e1051a39Sopenharmony_ci * unnecessary. 688e1051a39Sopenharmony_ci */ 689e1051a39Sopenharmony_ci DSO *dso = NULL; 690e1051a39Sopenharmony_ci union { 691e1051a39Sopenharmony_ci void *sym; 692e1051a39Sopenharmony_ci void (*func)(void); 693e1051a39Sopenharmony_ci } handlersym; 694e1051a39Sopenharmony_ci 695e1051a39Sopenharmony_ci handlersym.func = handler; 696e1051a39Sopenharmony_ci 697e1051a39Sopenharmony_ci ERR_set_mark(); 698e1051a39Sopenharmony_ci dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); 699e1051a39Sopenharmony_ci /* See same code above in ossl_init_base() for an explanation. */ 700e1051a39Sopenharmony_ci OSSL_TRACE1(INIT, 701e1051a39Sopenharmony_ci "atexit: obtained DSO reference? %s\n", 702e1051a39Sopenharmony_ci (dso == NULL ? "No!" : "Yes.")); 703e1051a39Sopenharmony_ci DSO_free(dso); 704e1051a39Sopenharmony_ci ERR_pop_to_mark(); 705e1051a39Sopenharmony_ci# endif 706e1051a39Sopenharmony_ci } 707e1051a39Sopenharmony_ci#endif 708e1051a39Sopenharmony_ci 709e1051a39Sopenharmony_ci if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) { 710e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 711e1051a39Sopenharmony_ci return 0; 712e1051a39Sopenharmony_ci } 713e1051a39Sopenharmony_ci 714e1051a39Sopenharmony_ci newhand->handler = handler; 715e1051a39Sopenharmony_ci newhand->next = stop_handlers; 716e1051a39Sopenharmony_ci stop_handlers = newhand; 717e1051a39Sopenharmony_ci 718e1051a39Sopenharmony_ci return 1; 719e1051a39Sopenharmony_ci} 720e1051a39Sopenharmony_ci 721