1e71b7053SJung-uk Kim /* 2*34252e89SJung-uk Kim * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim */ 9e71b7053SJung-uk Kim 10e71b7053SJung-uk Kim #include "e_os.h" 1117f01e99SJung-uk Kim #include "crypto/cryptlib.h" 12e71b7053SJung-uk Kim #include <openssl/err.h> 1317f01e99SJung-uk Kim #include "crypto/rand.h" 14e71b7053SJung-uk Kim #include "internal/bio.h" 15e71b7053SJung-uk Kim #include <openssl/evp.h> 1617f01e99SJung-uk Kim #include "crypto/evp.h" 17e71b7053SJung-uk Kim #include "internal/conf.h" 1817f01e99SJung-uk Kim #include "crypto/async.h" 1917f01e99SJung-uk Kim #include "crypto/engine.h" 20e71b7053SJung-uk Kim #include "internal/comp.h" 21e71b7053SJung-uk Kim #include "internal/err.h" 2217f01e99SJung-uk Kim #include "crypto/err.h" 2317f01e99SJung-uk Kim #include "crypto/objects.h" 24e71b7053SJung-uk Kim #include <stdlib.h> 25e71b7053SJung-uk Kim #include <assert.h> 26e71b7053SJung-uk Kim #include "internal/thread_once.h" 2717f01e99SJung-uk Kim #include "crypto/dso_conf.h" 28e71b7053SJung-uk Kim #include "internal/dso.h" 2917f01e99SJung-uk Kim #include "crypto/store.h" 30e71b7053SJung-uk Kim 31e71b7053SJung-uk Kim static int stopped = 0; 32e71b7053SJung-uk Kim 33e71b7053SJung-uk Kim /* 34e71b7053SJung-uk Kim * Since per-thread-specific-data destructors are not universally 35e71b7053SJung-uk Kim * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key 36e71b7053SJung-uk Kim * is assumed to have destructor associated. And then an effort is made 37e71b7053SJung-uk Kim * to call this single destructor on non-pthread platform[s]. 38e71b7053SJung-uk Kim * 39e71b7053SJung-uk Kim * Initial value is "impossible". It is used as guard value to shortcut 40e71b7053SJung-uk Kim * destructor for threads terminating before libcrypto is initialized or 41e71b7053SJung-uk Kim * after it's de-initialized. Access to the key doesn't have to be 42e71b7053SJung-uk Kim * serialized for the said threads, because they didn't use libcrypto 43da327cd2SJung-uk Kim * and it doesn't matter if they pick "impossible" or dereference real 44e71b7053SJung-uk Kim * key value and pull NULL past initialization in the first thread that 45e71b7053SJung-uk Kim * intends to use libcrypto. 46e71b7053SJung-uk Kim */ 47e71b7053SJung-uk Kim static union { 48e71b7053SJung-uk Kim long sane; 49e71b7053SJung-uk Kim CRYPTO_THREAD_LOCAL value; 50e71b7053SJung-uk Kim } destructor_key = { -1 }; 51e71b7053SJung-uk Kim 52e71b7053SJung-uk Kim static void ossl_init_thread_stop(struct thread_local_inits_st *locals); 53e71b7053SJung-uk Kim 54e71b7053SJung-uk Kim static void ossl_init_thread_destructor(void *local) 55e71b7053SJung-uk Kim { 56e71b7053SJung-uk Kim ossl_init_thread_stop((struct thread_local_inits_st *)local); 57e71b7053SJung-uk Kim } 58e71b7053SJung-uk Kim 59e71b7053SJung-uk Kim static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) 60e71b7053SJung-uk Kim { 61e71b7053SJung-uk Kim struct thread_local_inits_st *local = 62e71b7053SJung-uk Kim CRYPTO_THREAD_get_local(&destructor_key.value); 63e71b7053SJung-uk Kim 64e71b7053SJung-uk Kim if (alloc) { 65e71b7053SJung-uk Kim if (local == NULL 66e71b7053SJung-uk Kim && (local = OPENSSL_zalloc(sizeof(*local))) != NULL 67e71b7053SJung-uk Kim && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) { 68e71b7053SJung-uk Kim OPENSSL_free(local); 69e71b7053SJung-uk Kim return NULL; 70e71b7053SJung-uk Kim } 71e71b7053SJung-uk Kim } else { 72e71b7053SJung-uk Kim CRYPTO_THREAD_set_local(&destructor_key.value, NULL); 73e71b7053SJung-uk Kim } 74e71b7053SJung-uk Kim 75e71b7053SJung-uk Kim return local; 76e71b7053SJung-uk Kim } 77e71b7053SJung-uk Kim 78e71b7053SJung-uk Kim typedef struct ossl_init_stop_st OPENSSL_INIT_STOP; 79e71b7053SJung-uk Kim struct ossl_init_stop_st { 80e71b7053SJung-uk Kim void (*handler)(void); 81e71b7053SJung-uk Kim OPENSSL_INIT_STOP *next; 82e71b7053SJung-uk Kim }; 83e71b7053SJung-uk Kim 84e71b7053SJung-uk Kim static OPENSSL_INIT_STOP *stop_handlers = NULL; 85e71b7053SJung-uk Kim static CRYPTO_RWLOCK *init_lock = NULL; 86e71b7053SJung-uk Kim 87e71b7053SJung-uk Kim static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; 88e71b7053SJung-uk Kim static int base_inited = 0; 89e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_base) 90e71b7053SJung-uk Kim { 91e71b7053SJung-uk Kim CRYPTO_THREAD_LOCAL key; 92e71b7053SJung-uk Kim 93e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 94e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n"); 95e71b7053SJung-uk Kim #endif 96e71b7053SJung-uk Kim #ifndef OPENSSL_NO_CRYPTO_MDEBUG 97e71b7053SJung-uk Kim ossl_malloc_setup_failures(); 98e71b7053SJung-uk Kim #endif 99e71b7053SJung-uk Kim if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor)) 100e71b7053SJung-uk Kim return 0; 101e71b7053SJung-uk Kim if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) 102e71b7053SJung-uk Kim goto err; 103e71b7053SJung-uk Kim OPENSSL_cpuid_setup(); 104e71b7053SJung-uk Kim 105e71b7053SJung-uk Kim destructor_key.value = key; 106e71b7053SJung-uk Kim base_inited = 1; 107e71b7053SJung-uk Kim return 1; 108e71b7053SJung-uk Kim 109e71b7053SJung-uk Kim err: 110e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 111e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n"); 112e71b7053SJung-uk Kim #endif 113e71b7053SJung-uk Kim CRYPTO_THREAD_lock_free(init_lock); 114e71b7053SJung-uk Kim init_lock = NULL; 115e71b7053SJung-uk Kim 116e71b7053SJung-uk Kim CRYPTO_THREAD_cleanup_local(&key); 117e71b7053SJung-uk Kim return 0; 118e71b7053SJung-uk Kim } 119e71b7053SJung-uk Kim 1206935a639SJung-uk Kim static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT; 1216935a639SJung-uk Kim #if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32) 1226935a639SJung-uk Kim static int win32atexit(void) 1236935a639SJung-uk Kim { 1246935a639SJung-uk Kim OPENSSL_cleanup(); 1256935a639SJung-uk Kim return 0; 1266935a639SJung-uk Kim } 1276935a639SJung-uk Kim #endif 1286935a639SJung-uk Kim 1296935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit) 1306935a639SJung-uk Kim { 1316935a639SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 1326935a639SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n"); 1336935a639SJung-uk Kim #endif 1346935a639SJung-uk Kim #ifndef OPENSSL_SYS_UEFI 1356935a639SJung-uk Kim # ifdef _WIN32 1366935a639SJung-uk Kim /* We use _onexit() in preference because it gets called on DLL unload */ 1376935a639SJung-uk Kim if (_onexit(win32atexit) == NULL) 1386935a639SJung-uk Kim return 0; 1396935a639SJung-uk Kim # else 1406935a639SJung-uk Kim if (atexit(OPENSSL_cleanup) != 0) 1416935a639SJung-uk Kim return 0; 1426935a639SJung-uk Kim # endif 1436935a639SJung-uk Kim #endif 1446935a639SJung-uk Kim 1456935a639SJung-uk Kim return 1; 1466935a639SJung-uk Kim } 1476935a639SJung-uk Kim 1486935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit, 1496935a639SJung-uk Kim ossl_init_register_atexit) 1506935a639SJung-uk Kim { 1516935a639SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 1526935a639SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n"); 1536935a639SJung-uk Kim #endif 1546935a639SJung-uk Kim /* Do nothing in this case */ 1556935a639SJung-uk Kim return 1; 1566935a639SJung-uk Kim } 1576935a639SJung-uk Kim 158e71b7053SJung-uk Kim static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT; 159e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) 160e71b7053SJung-uk Kim { 161e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 162e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n"); 163e71b7053SJung-uk Kim #endif 164610a21fdSJung-uk Kim #if !defined(OPENSSL_USE_NODELETE) \ 1656935a639SJung-uk Kim && !defined(OPENSSL_NO_PINSHARED) 166610a21fdSJung-uk Kim # if defined(DSO_WIN32) && !defined(_WIN32_WCE) 167e71b7053SJung-uk Kim { 168e71b7053SJung-uk Kim HMODULE handle = NULL; 169e71b7053SJung-uk Kim BOOL ret; 170e71b7053SJung-uk Kim 171e71b7053SJung-uk Kim /* We don't use the DSO route for WIN32 because there is a better way */ 172e71b7053SJung-uk Kim ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 173e71b7053SJung-uk Kim | GET_MODULE_HANDLE_EX_FLAG_PIN, 174e71b7053SJung-uk Kim (void *)&base_inited, &handle); 175e71b7053SJung-uk Kim 176e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 177e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", 178e71b7053SJung-uk Kim (ret == TRUE ? "No!" : "Yes.")); 179e71b7053SJung-uk Kim # endif 180e71b7053SJung-uk Kim return (ret == TRUE) ? 1 : 0; 181e71b7053SJung-uk Kim } 182610a21fdSJung-uk Kim # elif !defined(DSO_NONE) 183e71b7053SJung-uk Kim /* 184e71b7053SJung-uk Kim * Deliberately leak a reference to ourselves. This will force the library 185e71b7053SJung-uk Kim * to remain loaded until the atexit() handler is run at process exit. 186e71b7053SJung-uk Kim */ 187e71b7053SJung-uk Kim { 188e71b7053SJung-uk Kim DSO *dso; 189e71b7053SJung-uk Kim void *err; 190e71b7053SJung-uk Kim 191e71b7053SJung-uk Kim if (!err_shelve_state(&err)) 192e71b7053SJung-uk Kim return 0; 193e71b7053SJung-uk Kim 194e71b7053SJung-uk Kim dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); 195e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 196e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", 197e71b7053SJung-uk Kim (dso == NULL ? "No!" : "Yes.")); 198e71b7053SJung-uk Kim /* 199e71b7053SJung-uk Kim * In case of No!, it is uncertain our exit()-handlers can still be 200e71b7053SJung-uk Kim * called. After dlclose() the whole library might have been unloaded 201e71b7053SJung-uk Kim * already. 202e71b7053SJung-uk Kim */ 203e71b7053SJung-uk Kim # endif 204e71b7053SJung-uk Kim DSO_free(dso); 205e71b7053SJung-uk Kim err_unshelve_state(err); 206e71b7053SJung-uk Kim } 207e71b7053SJung-uk Kim # endif 208e71b7053SJung-uk Kim #endif 209e71b7053SJung-uk Kim 210e71b7053SJung-uk Kim return 1; 211e71b7053SJung-uk Kim } 212e71b7053SJung-uk Kim 213e71b7053SJung-uk Kim static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT; 214*34252e89SJung-uk Kim 215e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) 216e71b7053SJung-uk Kim { 217e71b7053SJung-uk Kim int ret = 1; 218e71b7053SJung-uk Kim /* 219e71b7053SJung-uk Kim * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time 220e71b7053SJung-uk Kim * pulling in all the error strings during static linking 221e71b7053SJung-uk Kim */ 222e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) 223e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 224e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: " 225e71b7053SJung-uk Kim "err_load_crypto_strings_int()\n"); 226e71b7053SJung-uk Kim # endif 227e71b7053SJung-uk Kim ret = err_load_crypto_strings_int(); 228e71b7053SJung-uk Kim #endif 229e71b7053SJung-uk Kim return ret; 230e71b7053SJung-uk Kim } 231e71b7053SJung-uk Kim 2326935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings, 2336935a639SJung-uk Kim ossl_init_load_crypto_strings) 2346935a639SJung-uk Kim { 2356935a639SJung-uk Kim /* Do nothing in this case */ 2366935a639SJung-uk Kim return 1; 2376935a639SJung-uk Kim } 2386935a639SJung-uk Kim 239e71b7053SJung-uk Kim static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT; 240e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) 241e71b7053SJung-uk Kim { 242e71b7053SJung-uk Kim /* 243e71b7053SJung-uk Kim * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 244e71b7053SJung-uk Kim * pulling in all the ciphers during static linking 245e71b7053SJung-uk Kim */ 246e71b7053SJung-uk Kim #ifndef OPENSSL_NO_AUTOALGINIT 247e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 248e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: " 249e71b7053SJung-uk Kim "openssl_add_all_ciphers_int()\n"); 250e71b7053SJung-uk Kim # endif 251e71b7053SJung-uk Kim openssl_add_all_ciphers_int(); 252e71b7053SJung-uk Kim #endif 253e71b7053SJung-uk Kim return 1; 254e71b7053SJung-uk Kim } 255e71b7053SJung-uk Kim 2566935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers, 2576935a639SJung-uk Kim ossl_init_add_all_ciphers) 2586935a639SJung-uk Kim { 2596935a639SJung-uk Kim /* Do nothing */ 2606935a639SJung-uk Kim return 1; 2616935a639SJung-uk Kim } 2626935a639SJung-uk Kim 263e71b7053SJung-uk Kim static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT; 264e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) 265e71b7053SJung-uk Kim { 266e71b7053SJung-uk Kim /* 267e71b7053SJung-uk Kim * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 268e71b7053SJung-uk Kim * pulling in all the ciphers during static linking 269e71b7053SJung-uk Kim */ 270e71b7053SJung-uk Kim #ifndef OPENSSL_NO_AUTOALGINIT 271e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 272e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: " 273e71b7053SJung-uk Kim "openssl_add_all_digests()\n"); 274e71b7053SJung-uk Kim # endif 275e71b7053SJung-uk Kim openssl_add_all_digests_int(); 276e71b7053SJung-uk Kim #endif 277e71b7053SJung-uk Kim return 1; 278e71b7053SJung-uk Kim } 279e71b7053SJung-uk Kim 2806935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests, 2816935a639SJung-uk Kim ossl_init_add_all_digests) 282e71b7053SJung-uk Kim { 283e71b7053SJung-uk Kim /* Do nothing */ 284e71b7053SJung-uk Kim return 1; 285e71b7053SJung-uk Kim } 286e71b7053SJung-uk Kim 287e71b7053SJung-uk Kim static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; 288e71b7053SJung-uk Kim static int config_inited = 0; 2896935a639SJung-uk Kim static const OPENSSL_INIT_SETTINGS *conf_settings = NULL; 290e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_config) 291e71b7053SJung-uk Kim { 2926935a639SJung-uk Kim int ret = openssl_config_int(conf_settings); 293e71b7053SJung-uk Kim config_inited = 1; 2946935a639SJung-uk Kim return ret; 295e71b7053SJung-uk Kim } 2966935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config) 297e71b7053SJung-uk Kim { 298e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 299e71b7053SJung-uk Kim fprintf(stderr, 300e71b7053SJung-uk Kim "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n"); 301e71b7053SJung-uk Kim #endif 302e71b7053SJung-uk Kim openssl_no_config_int(); 303e71b7053SJung-uk Kim config_inited = 1; 304e71b7053SJung-uk Kim return 1; 305e71b7053SJung-uk Kim } 306e71b7053SJung-uk Kim 307e71b7053SJung-uk Kim static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT; 308e71b7053SJung-uk Kim static int async_inited = 0; 309e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_async) 310e71b7053SJung-uk Kim { 311e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 312e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n"); 313e71b7053SJung-uk Kim #endif 314e71b7053SJung-uk Kim if (!async_init()) 315e71b7053SJung-uk Kim return 0; 316e71b7053SJung-uk Kim async_inited = 1; 317e71b7053SJung-uk Kim return 1; 318e71b7053SJung-uk Kim } 319e71b7053SJung-uk Kim 320e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 321e71b7053SJung-uk Kim static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT; 322e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) 323e71b7053SJung-uk Kim { 324e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 325e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: " 326e71b7053SJung-uk Kim "engine_load_openssl_int()\n"); 327e71b7053SJung-uk Kim # endif 328e71b7053SJung-uk Kim engine_load_openssl_int(); 329e71b7053SJung-uk Kim return 1; 330e71b7053SJung-uk Kim } 331e71b7053SJung-uk Kim # ifndef OPENSSL_NO_DEVCRYPTOENG 332e71b7053SJung-uk Kim static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; 333e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) 334e71b7053SJung-uk Kim { 335e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 336e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " 337e71b7053SJung-uk Kim "engine_load_devcrypto_int()\n"); 338e71b7053SJung-uk Kim # endif 339e71b7053SJung-uk Kim engine_load_devcrypto_int(); 340e71b7053SJung-uk Kim return 1; 341e71b7053SJung-uk Kim } 342e71b7053SJung-uk Kim # endif 343e71b7053SJung-uk Kim 344e71b7053SJung-uk Kim # ifndef OPENSSL_NO_RDRAND 345e71b7053SJung-uk Kim static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; 346e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) 347e71b7053SJung-uk Kim { 348e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 349e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: " 350e71b7053SJung-uk Kim "engine_load_rdrand_int()\n"); 351e71b7053SJung-uk Kim # endif 352e71b7053SJung-uk Kim engine_load_rdrand_int(); 353e71b7053SJung-uk Kim return 1; 354e71b7053SJung-uk Kim } 355e71b7053SJung-uk Kim # endif 356e71b7053SJung-uk Kim static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT; 357e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) 358e71b7053SJung-uk Kim { 359e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 360e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: " 361e71b7053SJung-uk Kim "engine_load_dynamic_int()\n"); 362e71b7053SJung-uk Kim # endif 363e71b7053SJung-uk Kim engine_load_dynamic_int(); 364e71b7053SJung-uk Kim return 1; 365e71b7053SJung-uk Kim } 366e71b7053SJung-uk Kim # ifndef OPENSSL_NO_STATIC_ENGINE 367e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 368e71b7053SJung-uk Kim static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; 369e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) 370e71b7053SJung-uk Kim { 371e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 372e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: " 373e71b7053SJung-uk Kim "engine_load_padlock_int()\n"); 374e71b7053SJung-uk Kim # endif 375e71b7053SJung-uk Kim engine_load_padlock_int(); 376e71b7053SJung-uk Kim return 1; 377e71b7053SJung-uk Kim } 378e71b7053SJung-uk Kim # endif 379e71b7053SJung-uk Kim # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 380e71b7053SJung-uk Kim static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT; 381e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) 382e71b7053SJung-uk Kim { 383e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 384e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: " 385e71b7053SJung-uk Kim "engine_load_capi_int()\n"); 386e71b7053SJung-uk Kim # endif 387e71b7053SJung-uk Kim engine_load_capi_int(); 388e71b7053SJung-uk Kim return 1; 389e71b7053SJung-uk Kim } 390e71b7053SJung-uk Kim # endif 391e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_AFALGENG) 392e71b7053SJung-uk Kim static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT; 393e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) 394e71b7053SJung-uk Kim { 395e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 396e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: " 397e71b7053SJung-uk Kim "engine_load_afalg_int()\n"); 398e71b7053SJung-uk Kim # endif 399e71b7053SJung-uk Kim engine_load_afalg_int(); 400e71b7053SJung-uk Kim return 1; 401e71b7053SJung-uk Kim } 402e71b7053SJung-uk Kim # endif 403e71b7053SJung-uk Kim # endif 404e71b7053SJung-uk Kim #endif 405e71b7053SJung-uk Kim 406e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP 407e71b7053SJung-uk Kim static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT; 408e71b7053SJung-uk Kim 409e71b7053SJung-uk Kim static int zlib_inited = 0; 410e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_zlib) 411e71b7053SJung-uk Kim { 412e71b7053SJung-uk Kim /* Do nothing - we need to know about this for the later cleanup */ 413e71b7053SJung-uk Kim zlib_inited = 1; 414e71b7053SJung-uk Kim return 1; 415e71b7053SJung-uk Kim } 416e71b7053SJung-uk Kim #endif 417e71b7053SJung-uk Kim 418e71b7053SJung-uk Kim static void ossl_init_thread_stop(struct thread_local_inits_st *locals) 419e71b7053SJung-uk Kim { 420e71b7053SJung-uk Kim /* Can't do much about this */ 421e71b7053SJung-uk Kim if (locals == NULL) 422e71b7053SJung-uk Kim return; 423e71b7053SJung-uk Kim 424e71b7053SJung-uk Kim if (locals->async) { 425e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 426e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " 427e71b7053SJung-uk Kim "async_delete_thread_state()\n"); 428e71b7053SJung-uk Kim #endif 429e71b7053SJung-uk Kim async_delete_thread_state(); 430e71b7053SJung-uk Kim } 431e71b7053SJung-uk Kim 432e71b7053SJung-uk Kim if (locals->err_state) { 433e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 434e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " 435e71b7053SJung-uk Kim "err_delete_thread_state()\n"); 436e71b7053SJung-uk Kim #endif 437e71b7053SJung-uk Kim err_delete_thread_state(); 438e71b7053SJung-uk Kim } 439e71b7053SJung-uk Kim 440e71b7053SJung-uk Kim if (locals->rand) { 441e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 442e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " 443e71b7053SJung-uk Kim "drbg_delete_thread_state()\n"); 444e71b7053SJung-uk Kim #endif 445e71b7053SJung-uk Kim drbg_delete_thread_state(); 446e71b7053SJung-uk Kim } 447e71b7053SJung-uk Kim 448e71b7053SJung-uk Kim OPENSSL_free(locals); 449e71b7053SJung-uk Kim } 450e71b7053SJung-uk Kim 451e71b7053SJung-uk Kim void OPENSSL_thread_stop(void) 452e71b7053SJung-uk Kim { 453e71b7053SJung-uk Kim if (destructor_key.sane != -1) 454e71b7053SJung-uk Kim ossl_init_thread_stop(ossl_init_get_thread_local(0)); 455e71b7053SJung-uk Kim } 456e71b7053SJung-uk Kim 457e71b7053SJung-uk Kim int ossl_init_thread_start(uint64_t opts) 458e71b7053SJung-uk Kim { 459e71b7053SJung-uk Kim struct thread_local_inits_st *locals; 460e71b7053SJung-uk Kim 461e71b7053SJung-uk Kim if (!OPENSSL_init_crypto(0, NULL)) 462e71b7053SJung-uk Kim return 0; 463e71b7053SJung-uk Kim 464e71b7053SJung-uk Kim locals = ossl_init_get_thread_local(1); 465e71b7053SJung-uk Kim 466e71b7053SJung-uk Kim if (locals == NULL) 467e71b7053SJung-uk Kim return 0; 468e71b7053SJung-uk Kim 469e71b7053SJung-uk Kim if (opts & OPENSSL_INIT_THREAD_ASYNC) { 470e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 471e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " 472e71b7053SJung-uk Kim "marking thread for async\n"); 473e71b7053SJung-uk Kim #endif 474e71b7053SJung-uk Kim locals->async = 1; 475e71b7053SJung-uk Kim } 476e71b7053SJung-uk Kim 477e71b7053SJung-uk Kim if (opts & OPENSSL_INIT_THREAD_ERR_STATE) { 478e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 479e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " 480e71b7053SJung-uk Kim "marking thread for err_state\n"); 481e71b7053SJung-uk Kim #endif 482e71b7053SJung-uk Kim locals->err_state = 1; 483e71b7053SJung-uk Kim } 484e71b7053SJung-uk Kim 485e71b7053SJung-uk Kim if (opts & OPENSSL_INIT_THREAD_RAND) { 486e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 487e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " 488e71b7053SJung-uk Kim "marking thread for rand\n"); 489e71b7053SJung-uk Kim #endif 490e71b7053SJung-uk Kim locals->rand = 1; 491e71b7053SJung-uk Kim } 492e71b7053SJung-uk Kim 493e71b7053SJung-uk Kim return 1; 494e71b7053SJung-uk Kim } 495e71b7053SJung-uk Kim 496e71b7053SJung-uk Kim void OPENSSL_cleanup(void) 497e71b7053SJung-uk Kim { 498e71b7053SJung-uk Kim OPENSSL_INIT_STOP *currhandler, *lasthandler; 499e71b7053SJung-uk Kim CRYPTO_THREAD_LOCAL key; 500e71b7053SJung-uk Kim 501e71b7053SJung-uk Kim /* If we've not been inited then no need to deinit */ 502e71b7053SJung-uk Kim if (!base_inited) 503e71b7053SJung-uk Kim return; 504e71b7053SJung-uk Kim 505e71b7053SJung-uk Kim /* Might be explicitly called and also by atexit */ 506e71b7053SJung-uk Kim if (stopped) 507e71b7053SJung-uk Kim return; 508e71b7053SJung-uk Kim stopped = 1; 509e71b7053SJung-uk Kim 510e71b7053SJung-uk Kim /* 511e71b7053SJung-uk Kim * Thread stop may not get automatically called by the thread library for 512e71b7053SJung-uk Kim * the very last thread in some situations, so call it directly. 513e71b7053SJung-uk Kim */ 514e71b7053SJung-uk Kim ossl_init_thread_stop(ossl_init_get_thread_local(0)); 515e71b7053SJung-uk Kim 516e71b7053SJung-uk Kim currhandler = stop_handlers; 517e71b7053SJung-uk Kim while (currhandler != NULL) { 518e71b7053SJung-uk Kim currhandler->handler(); 519e71b7053SJung-uk Kim lasthandler = currhandler; 520e71b7053SJung-uk Kim currhandler = currhandler->next; 521e71b7053SJung-uk Kim OPENSSL_free(lasthandler); 522e71b7053SJung-uk Kim } 523e71b7053SJung-uk Kim stop_handlers = NULL; 524e71b7053SJung-uk Kim 525e71b7053SJung-uk Kim CRYPTO_THREAD_lock_free(init_lock); 526e71b7053SJung-uk Kim init_lock = NULL; 527e71b7053SJung-uk Kim 528e71b7053SJung-uk Kim /* 529e71b7053SJung-uk Kim * We assume we are single-threaded for this function, i.e. no race 530e71b7053SJung-uk Kim * conditions for the various "*_inited" vars below. 531e71b7053SJung-uk Kim */ 532e71b7053SJung-uk Kim 533e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP 534e71b7053SJung-uk Kim if (zlib_inited) { 535e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 536e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 537e71b7053SJung-uk Kim "comp_zlib_cleanup_int()\n"); 538e71b7053SJung-uk Kim #endif 539e71b7053SJung-uk Kim comp_zlib_cleanup_int(); 540e71b7053SJung-uk Kim } 541e71b7053SJung-uk Kim #endif 542e71b7053SJung-uk Kim 543e71b7053SJung-uk Kim if (async_inited) { 544e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 545e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 546e71b7053SJung-uk Kim "async_deinit()\n"); 547e71b7053SJung-uk Kim # endif 548e71b7053SJung-uk Kim async_deinit(); 549e71b7053SJung-uk Kim } 550e71b7053SJung-uk Kim 551e71b7053SJung-uk Kim key = destructor_key.value; 552e71b7053SJung-uk Kim destructor_key.sane = -1; 553e71b7053SJung-uk Kim CRYPTO_THREAD_cleanup_local(&key); 554e71b7053SJung-uk Kim 555e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG 556e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 557e71b7053SJung-uk Kim "rand_cleanup_int()\n"); 558e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 559e71b7053SJung-uk Kim "conf_modules_free_int()\n"); 560e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 561e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 562e71b7053SJung-uk Kim "engine_cleanup_int()\n"); 563e71b7053SJung-uk Kim #endif 564e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 565e71b7053SJung-uk Kim "crypto_cleanup_all_ex_data_int()\n"); 566e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 567e71b7053SJung-uk Kim "bio_sock_cleanup_int()\n"); 568e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 569e71b7053SJung-uk Kim "bio_cleanup()\n"); 570e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 571e71b7053SJung-uk Kim "evp_cleanup_int()\n"); 572e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 573e71b7053SJung-uk Kim "obj_cleanup_int()\n"); 574e71b7053SJung-uk Kim fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 575e71b7053SJung-uk Kim "err_cleanup()\n"); 576e71b7053SJung-uk Kim #endif 577e71b7053SJung-uk Kim /* 578e71b7053SJung-uk Kim * Note that cleanup order is important: 579e71b7053SJung-uk Kim * - rand_cleanup_int could call an ENGINE's RAND cleanup function so 580e71b7053SJung-uk Kim * must be called before engine_cleanup_int() 581e71b7053SJung-uk Kim * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up 582e71b7053SJung-uk Kim * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data(). 583e71b7053SJung-uk Kim * - conf_modules_free_int() can end up in ENGINE code so must be called 584e71b7053SJung-uk Kim * before engine_cleanup_int() 585e71b7053SJung-uk Kim * - ENGINEs and additional EVP algorithms might use added OIDs names so 586e71b7053SJung-uk Kim * obj_cleanup_int() must be called last 587e71b7053SJung-uk Kim */ 588e71b7053SJung-uk Kim rand_cleanup_int(); 589e71b7053SJung-uk Kim rand_drbg_cleanup_int(); 590e71b7053SJung-uk Kim conf_modules_free_int(); 591e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 592e71b7053SJung-uk Kim engine_cleanup_int(); 593e71b7053SJung-uk Kim #endif 594e71b7053SJung-uk Kim ossl_store_cleanup_int(); 595e71b7053SJung-uk Kim crypto_cleanup_all_ex_data_int(); 596e71b7053SJung-uk Kim bio_cleanup(); 597e71b7053SJung-uk Kim evp_cleanup_int(); 598e71b7053SJung-uk Kim obj_cleanup_int(); 599e71b7053SJung-uk Kim err_cleanup(); 600e71b7053SJung-uk Kim 601e71b7053SJung-uk Kim CRYPTO_secure_malloc_done(); 602e71b7053SJung-uk Kim 603e71b7053SJung-uk Kim base_inited = 0; 604e71b7053SJung-uk Kim } 605e71b7053SJung-uk Kim 606e71b7053SJung-uk Kim /* 607e71b7053SJung-uk Kim * If this function is called with a non NULL settings value then it must be 608e71b7053SJung-uk Kim * called prior to any threads making calls to any OpenSSL functions, 609e71b7053SJung-uk Kim * i.e. passing a non-null settings value is assumed to be single-threaded. 610e71b7053SJung-uk Kim */ 611e71b7053SJung-uk Kim int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) 612e71b7053SJung-uk Kim { 613e71b7053SJung-uk Kim if (stopped) { 614e71b7053SJung-uk Kim if (!(opts & OPENSSL_INIT_BASE_ONLY)) 615e71b7053SJung-uk Kim CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL); 616e71b7053SJung-uk Kim return 0; 617e71b7053SJung-uk Kim } 618e71b7053SJung-uk Kim 6196935a639SJung-uk Kim /* 6206935a639SJung-uk Kim * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the 6216935a639SJung-uk Kim * *only* option specified. With that option we return immediately after 6226935a639SJung-uk Kim * doing the requested limited initialization. Note that 6236935a639SJung-uk Kim * err_shelve_state() called by us via ossl_init_load_crypto_nodelete() 6246935a639SJung-uk Kim * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with 6256935a639SJung-uk Kim * base already initialized this is a harmless NOOP. 6266935a639SJung-uk Kim * 6276935a639SJung-uk Kim * If we remain the only caller of err_shelve_state() the recursion should 6286935a639SJung-uk Kim * perhaps be removed, but if in doubt, it can be left in place. 6296935a639SJung-uk Kim */ 630e71b7053SJung-uk Kim if (!RUN_ONCE(&base, ossl_init_base)) 631e71b7053SJung-uk Kim return 0; 6326935a639SJung-uk Kim if (opts & OPENSSL_INIT_BASE_ONLY) 6336935a639SJung-uk Kim return 1; 634e71b7053SJung-uk Kim 6356935a639SJung-uk Kim /* 6366935a639SJung-uk Kim * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls 6376935a639SJung-uk Kim * should not have the side-effect of setting up exit handlers, and 6386935a639SJung-uk Kim * therefore, this code block is below the INIT_BASE_ONLY-conditioned early 6396935a639SJung-uk Kim * return above. 6406935a639SJung-uk Kim */ 6416935a639SJung-uk Kim if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) { 6426935a639SJung-uk Kim if (!RUN_ONCE_ALT(®ister_atexit, ossl_init_no_register_atexit, 6436935a639SJung-uk Kim ossl_init_register_atexit)) 6446935a639SJung-uk Kim return 0; 6456935a639SJung-uk Kim } else if (!RUN_ONCE(®ister_atexit, ossl_init_register_atexit)) { 6466935a639SJung-uk Kim return 0; 6476935a639SJung-uk Kim } 6486935a639SJung-uk Kim 6496935a639SJung-uk Kim if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete)) 650e71b7053SJung-uk Kim return 0; 651e71b7053SJung-uk Kim 652e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) 6536935a639SJung-uk Kim && !RUN_ONCE_ALT(&load_crypto_strings, 6546935a639SJung-uk Kim ossl_init_no_load_crypto_strings, 6556935a639SJung-uk Kim ossl_init_load_crypto_strings)) 656e71b7053SJung-uk Kim return 0; 657e71b7053SJung-uk Kim 658e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS) 659e71b7053SJung-uk Kim && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings)) 660e71b7053SJung-uk Kim return 0; 661e71b7053SJung-uk Kim 662e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS) 6636935a639SJung-uk Kim && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers, 6646935a639SJung-uk Kim ossl_init_add_all_ciphers)) 665e71b7053SJung-uk Kim return 0; 666e71b7053SJung-uk Kim 667e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS) 668e71b7053SJung-uk Kim && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers)) 669e71b7053SJung-uk Kim return 0; 670e71b7053SJung-uk Kim 671e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS) 6726935a639SJung-uk Kim && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests, 6736935a639SJung-uk Kim ossl_init_add_all_digests)) 674e71b7053SJung-uk Kim return 0; 675e71b7053SJung-uk Kim 676e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS) 677e71b7053SJung-uk Kim && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests)) 678e71b7053SJung-uk Kim return 0; 679e71b7053SJung-uk Kim 680e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ATFORK) 681e71b7053SJung-uk Kim && !openssl_init_fork_handlers()) 682e71b7053SJung-uk Kim return 0; 683e71b7053SJung-uk Kim 684e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) 6856935a639SJung-uk Kim && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config)) 686e71b7053SJung-uk Kim return 0; 687e71b7053SJung-uk Kim 688e71b7053SJung-uk Kim if (opts & OPENSSL_INIT_LOAD_CONFIG) { 689e71b7053SJung-uk Kim int ret; 690e71b7053SJung-uk Kim CRYPTO_THREAD_write_lock(init_lock); 6916935a639SJung-uk Kim conf_settings = settings; 692e71b7053SJung-uk Kim ret = RUN_ONCE(&config, ossl_init_config); 6936935a639SJung-uk Kim conf_settings = NULL; 694e71b7053SJung-uk Kim CRYPTO_THREAD_unlock(init_lock); 695610a21fdSJung-uk Kim if (ret <= 0) 696e71b7053SJung-uk Kim return 0; 697e71b7053SJung-uk Kim } 698e71b7053SJung-uk Kim 699e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ASYNC) 700e71b7053SJung-uk Kim && !RUN_ONCE(&async, ossl_init_async)) 701e71b7053SJung-uk Kim return 0; 702e71b7053SJung-uk Kim 703e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 704e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) 705e71b7053SJung-uk Kim && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) 706e71b7053SJung-uk Kim return 0; 707e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG) 708e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) 709e71b7053SJung-uk Kim && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) 710e71b7053SJung-uk Kim return 0; 711e71b7053SJung-uk Kim # endif 712e71b7053SJung-uk Kim # ifndef OPENSSL_NO_RDRAND 713e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_RDRAND) 714e71b7053SJung-uk Kim && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) 715e71b7053SJung-uk Kim return 0; 716e71b7053SJung-uk Kim # endif 717e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC) 718e71b7053SJung-uk Kim && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) 719e71b7053SJung-uk Kim return 0; 720e71b7053SJung-uk Kim # ifndef OPENSSL_NO_STATIC_ENGINE 721e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 722e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) 723e71b7053SJung-uk Kim && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) 724e71b7053SJung-uk Kim return 0; 725e71b7053SJung-uk Kim # endif 726e71b7053SJung-uk Kim # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 727e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_CAPI) 728e71b7053SJung-uk Kim && !RUN_ONCE(&engine_capi, ossl_init_engine_capi)) 729e71b7053SJung-uk Kim return 0; 730e71b7053SJung-uk Kim # endif 731e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_AFALGENG) 732e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ENGINE_AFALG) 733e71b7053SJung-uk Kim && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg)) 734e71b7053SJung-uk Kim return 0; 735e71b7053SJung-uk Kim # endif 736e71b7053SJung-uk Kim # endif 737e71b7053SJung-uk Kim if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN 738e71b7053SJung-uk Kim | OPENSSL_INIT_ENGINE_OPENSSL 739e71b7053SJung-uk Kim | OPENSSL_INIT_ENGINE_AFALG)) { 740e71b7053SJung-uk Kim ENGINE_register_all_complete(); 741e71b7053SJung-uk Kim } 742e71b7053SJung-uk Kim #endif 743e71b7053SJung-uk Kim 744e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP 745e71b7053SJung-uk Kim if ((opts & OPENSSL_INIT_ZLIB) 746e71b7053SJung-uk Kim && !RUN_ONCE(&zlib, ossl_init_zlib)) 747e71b7053SJung-uk Kim return 0; 748e71b7053SJung-uk Kim #endif 749e71b7053SJung-uk Kim 750e71b7053SJung-uk Kim return 1; 751e71b7053SJung-uk Kim } 752e71b7053SJung-uk Kim 753e71b7053SJung-uk Kim int OPENSSL_atexit(void (*handler)(void)) 754e71b7053SJung-uk Kim { 755e71b7053SJung-uk Kim OPENSSL_INIT_STOP *newhand; 756e71b7053SJung-uk Kim 757610a21fdSJung-uk Kim #if !defined(OPENSSL_USE_NODELETE)\ 7586935a639SJung-uk Kim && !defined(OPENSSL_NO_PINSHARED) 759e71b7053SJung-uk Kim { 760e71b7053SJung-uk Kim union { 761e71b7053SJung-uk Kim void *sym; 762e71b7053SJung-uk Kim void (*func)(void); 763e71b7053SJung-uk Kim } handlersym; 764e71b7053SJung-uk Kim 765e71b7053SJung-uk Kim handlersym.func = handler; 766610a21fdSJung-uk Kim # if defined(DSO_WIN32) && !defined(_WIN32_WCE) 767e71b7053SJung-uk Kim { 768e71b7053SJung-uk Kim HMODULE handle = NULL; 769e71b7053SJung-uk Kim BOOL ret; 770e71b7053SJung-uk Kim 771e71b7053SJung-uk Kim /* 772e71b7053SJung-uk Kim * We don't use the DSO route for WIN32 because there is a better 773e71b7053SJung-uk Kim * way 774e71b7053SJung-uk Kim */ 775e71b7053SJung-uk Kim ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 776e71b7053SJung-uk Kim | GET_MODULE_HANDLE_EX_FLAG_PIN, 777e71b7053SJung-uk Kim handlersym.sym, &handle); 778e71b7053SJung-uk Kim 779e71b7053SJung-uk Kim if (!ret) 780e71b7053SJung-uk Kim return 0; 781e71b7053SJung-uk Kim } 782610a21fdSJung-uk Kim # elif !defined(DSO_NONE) 783e71b7053SJung-uk Kim /* 784e71b7053SJung-uk Kim * Deliberately leak a reference to the handler. This will force the 785e71b7053SJung-uk Kim * library/code containing the handler to remain loaded until we run the 786e71b7053SJung-uk Kim * atexit handler. If -znodelete has been used then this is 787e71b7053SJung-uk Kim * unnecessary. 788e71b7053SJung-uk Kim */ 789e71b7053SJung-uk Kim { 790e71b7053SJung-uk Kim DSO *dso = NULL; 791e71b7053SJung-uk Kim 792e71b7053SJung-uk Kim ERR_set_mark(); 793e71b7053SJung-uk Kim dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); 794e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG 795e71b7053SJung-uk Kim fprintf(stderr, 796e71b7053SJung-uk Kim "OPENSSL_INIT: OPENSSL_atexit: obtained DSO reference? %s\n", 797e71b7053SJung-uk Kim (dso == NULL ? "No!" : "Yes.")); 798e71b7053SJung-uk Kim /* See same code above in ossl_init_base() for an explanation. */ 799e71b7053SJung-uk Kim # endif 800e71b7053SJung-uk Kim DSO_free(dso); 801e71b7053SJung-uk Kim ERR_pop_to_mark(); 802e71b7053SJung-uk Kim } 803e71b7053SJung-uk Kim # endif 804e71b7053SJung-uk Kim } 805e71b7053SJung-uk Kim #endif 806e71b7053SJung-uk Kim 807e71b7053SJung-uk Kim if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) { 808e71b7053SJung-uk Kim CRYPTOerr(CRYPTO_F_OPENSSL_ATEXIT, ERR_R_MALLOC_FAILURE); 809e71b7053SJung-uk Kim return 0; 810e71b7053SJung-uk Kim } 811e71b7053SJung-uk Kim 812e71b7053SJung-uk Kim newhand->handler = handler; 813e71b7053SJung-uk Kim newhand->next = stop_handlers; 814e71b7053SJung-uk Kim stop_handlers = newhand; 815e71b7053SJung-uk Kim 816e71b7053SJung-uk Kim return 1; 817e71b7053SJung-uk Kim } 818e71b7053SJung-uk Kim 819e71b7053SJung-uk Kim #ifdef OPENSSL_SYS_UNIX 820e71b7053SJung-uk Kim /* 821e71b7053SJung-uk Kim * The following three functions are for OpenSSL developers. This is 822e71b7053SJung-uk Kim * where we set/reset state across fork (called via pthread_atfork when 823e71b7053SJung-uk Kim * it exists, or manually by the application when it doesn't). 824e71b7053SJung-uk Kim * 825e71b7053SJung-uk Kim * WARNING! If you put code in either OPENSSL_fork_parent or 826e71b7053SJung-uk Kim * OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal- 827e71b7053SJung-uk Kim * safe. See this link, for example: 828e71b7053SJung-uk Kim * http://man7.org/linux/man-pages/man7/signal-safety.7.html 829e71b7053SJung-uk Kim */ 830e71b7053SJung-uk Kim 831e71b7053SJung-uk Kim void OPENSSL_fork_prepare(void) 832e71b7053SJung-uk Kim { 833e71b7053SJung-uk Kim } 834e71b7053SJung-uk Kim 835e71b7053SJung-uk Kim void OPENSSL_fork_parent(void) 836e71b7053SJung-uk Kim { 837e71b7053SJung-uk Kim } 838e71b7053SJung-uk Kim 839e71b7053SJung-uk Kim void OPENSSL_fork_child(void) 840e71b7053SJung-uk Kim { 841e71b7053SJung-uk Kim } 842e71b7053SJung-uk Kim #endif 843