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