]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/init.c
STORE: Make sure the loader to be registered is complete
[thirdparty/openssl.git] / crypto / init.c
CommitLineData
b184e3ef 1/*
2039c421 2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
b184e3ef 3 *
2039c421
RS
4 * Licensed under the OpenSSL license (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
b184e3ef
MC
8 */
9
b184e3ef
MC
10#include <internal/cryptlib_int.h>
11#include <openssl/err.h>
f3cd81d6 12#include <internal/rand.h>
62d876ad 13#include <internal/bio.h>
b184e3ef 14#include <openssl/evp.h>
b184e3ef
MC
15#include <internal/evp_int.h>
16#include <internal/conf.h>
17#include <internal/async.h>
18#include <internal/engine.h>
02a247e0 19#include <internal/comp.h>
b184e3ef 20#include <internal/err.h>
13524b11 21#include <internal/err_int.h>
7b8cc9b3 22#include <internal/objects.h>
b184e3ef 23#include <stdlib.h>
dd27f16e 24#include <assert.h>
c2e4e5d2 25#include <internal/thread_once.h>
5836780f 26#include <internal/dso.h>
71a5516d 27#include <internal/store.h>
dd27f16e
RS
28
29static int stopped = 0;
b184e3ef 30
71567a6f
MC
31static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
32
a072ed0c 33static CRYPTO_THREAD_LOCAL threadstopkey;
b184e3ef 34
b184e3ef
MC
35static void ossl_init_thread_stop_wrap(void *local)
36{
37 ossl_init_thread_stop((struct thread_local_inits_st *)local);
38}
39
b7326ea7 40static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
b184e3ef 41{
a072ed0c
MC
42 struct thread_local_inits_st *local =
43 CRYPTO_THREAD_get_local(&threadstopkey);
b184e3ef
MC
44
45 if (local == NULL && alloc) {
46 local = OPENSSL_zalloc(sizeof *local);
3ac6d5ee
BE
47 if (local != NULL && !CRYPTO_THREAD_set_local(&threadstopkey, local)) {
48 OPENSSL_free(local);
49 return NULL;
50 }
b184e3ef 51 }
b7326ea7 52 if (!alloc) {
a072ed0c 53 CRYPTO_THREAD_set_local(&threadstopkey, NULL);
b7326ea7 54 }
b184e3ef
MC
55
56 return local;
57}
58
7253fd55 59typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
b184e3ef
MC
60struct ossl_init_stop_st {
61 void (*handler)(void);
62 OPENSSL_INIT_STOP *next;
63};
64
65static OPENSSL_INIT_STOP *stop_handlers = NULL;
c292b105 66static CRYPTO_RWLOCK *init_lock = NULL;
b184e3ef 67
b1f1e7ae 68static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
b184e3ef 69static int base_inited = 0;
c2e4e5d2 70DEFINE_RUN_ONCE_STATIC(ossl_init_base)
b184e3ef
MC
71{
72#ifdef OPENSSL_INIT_DEBUG
73 fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
f7edeced
RS
74#endif
75#ifndef OPENSSL_NO_CRYPTO_MDEBUG
76 ossl_malloc_setup_failures();
b184e3ef 77#endif
a072ed0c
MC
78 /*
79 * We use a dummy thread local key here. We use the destructor to detect
80 * when the thread is going to stop (where that feature is available)
81 */
82 CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
c7b7938e 83#ifndef OPENSSL_SYS_UEFI
f672aee4 84 atexit(OPENSSL_cleanup);
c7b7938e 85#endif
c2e4e5d2
RL
86 if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
87 return 0;
b184e3ef 88 OPENSSL_cpuid_setup();
8aa9cf7e
RL
89
90 /*
91 * BIG FAT WARNING!
92 * Everything needed to be initialized in this function before threads
93 * come along MUST happen before base_inited is set to 1, or we will
94 * see race conditions.
95 */
b184e3ef 96 base_inited = 1;
5836780f 97
6e290a25 98#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
2b59d1be
MC
99# ifdef DSO_WIN32
100 {
101 HMODULE handle = NULL;
102 BOOL ret;
103
104 /* We don't use the DSO route for WIN32 because there is a better way */
105 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
106 | GET_MODULE_HANDLE_EX_FLAG_PIN,
107 (void *)&base_inited, &handle);
108
109 return (ret == TRUE) ? 1 : 0;
110 }
111# else
5836780f
MC
112 /*
113 * Deliberately leak a reference to ourselves. This will force the library
689f112d 114 * to remain loaded until the atexit() handler is run at process exit.
5836780f
MC
115 */
116 {
117 DSO *dso = NULL;
118
689f112d 119 ERR_set_mark();
5836780f
MC
120 dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
121 DSO_free(dso);
689f112d 122 ERR_pop_to_mark();
5836780f 123 }
2b59d1be 124# endif
b6d5ba1a 125#endif
5836780f 126
c2e4e5d2 127 return 1;
b184e3ef
MC
128}
129
b1f1e7ae 130static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
b184e3ef 131static int load_crypto_strings_inited = 0;
c2e4e5d2 132DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings)
b184e3ef
MC
133{
134 /* Do nothing in this case */
c2e4e5d2 135 return 1;
b184e3ef
MC
136}
137
c2e4e5d2 138DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
b184e3ef 139{
69588edb 140 int ret = 1;
498abff0
MC
141 /*
142 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
143 * pulling in all the error strings during static linking
144 */
145#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
b184e3ef
MC
146# ifdef OPENSSL_INIT_DEBUG
147 fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
b3599dbb 148 "err_load_crypto_strings_int()\n");
b184e3ef 149# endif
69588edb 150 ret = err_load_crypto_strings_int();
b184e3ef 151 load_crypto_strings_inited = 1;
bd91e3c8 152#endif
69588edb 153 return ret;
b184e3ef
MC
154}
155
b1f1e7ae 156static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 157DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
b184e3ef
MC
158{
159 /*
160 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
161 * pulling in all the ciphers during static linking
162 */
163#ifndef OPENSSL_NO_AUTOALGINIT
164# ifdef OPENSSL_INIT_DEBUG
165 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
b3599dbb 166 "openssl_add_all_ciphers_int()\n");
b184e3ef 167# endif
b3599dbb 168 openssl_add_all_ciphers_int();
b184e3ef 169#endif
c2e4e5d2 170 return 1;
b184e3ef
MC
171}
172
b1f1e7ae 173static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 174DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
b184e3ef
MC
175{
176 /*
177 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
178 * pulling in all the ciphers during static linking
179 */
180#ifndef OPENSSL_NO_AUTOALGINIT
181# ifdef OPENSSL_INIT_DEBUG
182 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
b3599dbb 183 "openssl_add_all_digests()\n");
b184e3ef 184# endif
b3599dbb 185 openssl_add_all_digests_int();
b184e3ef 186#endif
c2e4e5d2 187 return 1;
b184e3ef
MC
188}
189
c2e4e5d2 190DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
b184e3ef
MC
191{
192 /* Do nothing */
c2e4e5d2 193 return 1;
b184e3ef
MC
194}
195
b1f1e7ae 196static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
b184e3ef 197static int config_inited = 0;
cda3ae5b 198static const char *appname;
c2e4e5d2 199DEFINE_RUN_ONCE_STATIC(ossl_init_config)
b184e3ef
MC
200{
201#ifdef OPENSSL_INIT_DEBUG
202 fprintf(stderr,
b3599dbb 203 "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n",
cda3ae5b 204 appname == NULL ? "NULL" : appname);
b184e3ef 205#endif
cda3ae5b 206 openssl_config_int(appname);
b184e3ef 207 config_inited = 1;
c2e4e5d2 208 return 1;
b184e3ef 209}
c2e4e5d2 210DEFINE_RUN_ONCE_STATIC(ossl_init_no_config)
b184e3ef
MC
211{
212#ifdef OPENSSL_INIT_DEBUG
213 fprintf(stderr,
b3599dbb 214 "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
b184e3ef 215#endif
b3599dbb 216 openssl_no_config_int();
b184e3ef 217 config_inited = 1;
c2e4e5d2 218 return 1;
b184e3ef
MC
219}
220
b1f1e7ae 221static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
b184e3ef 222static int async_inited = 0;
c2e4e5d2 223DEFINE_RUN_ONCE_STATIC(ossl_init_async)
b184e3ef
MC
224{
225#ifdef OPENSSL_INIT_DEBUG
226 fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
227#endif
c2e4e5d2
RL
228 if (!async_init())
229 return 0;
b184e3ef 230 async_inited = 1;
c2e4e5d2 231 return 1;
b184e3ef
MC
232}
233
234#ifndef OPENSSL_NO_ENGINE
b1f1e7ae 235static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 236DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
b184e3ef
MC
237{
238# ifdef OPENSSL_INIT_DEBUG
239 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
b3599dbb 240 "engine_load_openssl_int()\n");
b184e3ef 241# endif
b3599dbb 242 engine_load_openssl_int();
c2e4e5d2 243 return 1;
b184e3ef 244}
619eb33a
RL
245# ifndef OPENSSL_NO_DEVCRYPTOENG
246static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
247DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
248{
249# ifdef OPENSSL_INIT_DEBUG
250 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
251 "engine_load_devcrypto_int()\n");
252# endif
253 engine_load_devcrypto_int();
254 return 1;
255}
256# endif
b184e3ef
MC
257
258# ifndef OPENSSL_NO_RDRAND
b1f1e7ae 259static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 260DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
b184e3ef
MC
261{
262# ifdef OPENSSL_INIT_DEBUG
263 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
b3599dbb 264 "engine_load_rdrand_int()\n");
b184e3ef 265# endif
b3599dbb 266 engine_load_rdrand_int();
c2e4e5d2 267 return 1;
b184e3ef
MC
268}
269# endif
b1f1e7ae 270static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 271DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
b184e3ef
MC
272{
273# ifdef OPENSSL_INIT_DEBUG
274 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
b3599dbb 275 "engine_load_dynamic_int()\n");
b184e3ef 276# endif
b3599dbb 277 engine_load_dynamic_int();
c2e4e5d2 278 return 1;
b184e3ef
MC
279}
280# ifndef OPENSSL_NO_STATIC_ENGINE
281# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
b1f1e7ae 282static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 283DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
b184e3ef
MC
284{
285# ifdef OPENSSL_INIT_DEBUG
286 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
b3599dbb 287 "engine_load_padlock_int()\n");
b184e3ef 288# endif
b3599dbb 289 engine_load_padlock_int();
c2e4e5d2 290 return 1;
b184e3ef
MC
291}
292# endif
293# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
b1f1e7ae 294static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 295DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
b184e3ef
MC
296{
297# ifdef OPENSSL_INIT_DEBUG
298 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
b3599dbb 299 "engine_load_capi_int()\n");
b184e3ef 300# endif
b3599dbb 301 engine_load_capi_int();
c2e4e5d2 302 return 1;
b184e3ef
MC
303}
304# endif
6cba4a66 305# if !defined(OPENSSL_NO_AFALGENG)
a4d8bcf1 306static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
c2e4e5d2 307DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
6cba4a66 308{
309# ifdef OPENSSL_INIT_DEBUG
310 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
b3599dbb 311 "engine_load_afalg_int()\n");
6cba4a66 312# endif
b3599dbb 313 engine_load_afalg_int();
c2e4e5d2 314 return 1;
6cba4a66 315}
316# endif
b184e3ef
MC
317# endif
318#endif
319
e4ad0763 320#ifndef OPENSSL_NO_COMP
b1f1e7ae 321static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
e4ad0763 322
b184e3ef 323static int zlib_inited = 0;
c2e4e5d2 324DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
b184e3ef
MC
325{
326 /* Do nothing - we need to know about this for the later cleanup */
327 zlib_inited = 1;
c2e4e5d2 328 return 1;
b184e3ef 329}
e4ad0763 330#endif
b184e3ef 331
71567a6f 332static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
b184e3ef
MC
333{
334 /* Can't do much about this */
335 if (locals == NULL)
336 return;
337
338 if (locals->async) {
339#ifdef OPENSSL_INIT_DEBUG
340 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
341 "ASYNC_cleanup_thread()\n");
342#endif
343 ASYNC_cleanup_thread();
344 }
345
346 if (locals->err_state) {
347#ifdef OPENSSL_INIT_DEBUG
348 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
21e00174 349 "err_delete_thread_state()\n");
b184e3ef 350#endif
21e00174 351 err_delete_thread_state();
b184e3ef
MC
352 }
353
354 OPENSSL_free(locals);
b184e3ef
MC
355}
356
f672aee4 357void OPENSSL_thread_stop(void)
71567a6f
MC
358{
359 ossl_init_thread_stop(
360 (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
361}
362
b184e3ef
MC
363int ossl_init_thread_start(uint64_t opts)
364{
3ac6d5ee
BE
365 struct thread_local_inits_st *locals;
366
367 if (!OPENSSL_init_crypto(0, NULL))
368 return 0;
369
370 locals = ossl_init_get_thread_local(1);
b184e3ef
MC
371
372 if (locals == NULL)
373 return 0;
374
375 if (opts & OPENSSL_INIT_THREAD_ASYNC) {
376#ifdef OPENSSL_INIT_DEBUG
377 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
378 "marking thread for async\n");
379#endif
380 locals->async = 1;
381 }
382
383 if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
384#ifdef OPENSSL_INIT_DEBUG
385 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
386 "marking thread for err_state\n");
387#endif
388 locals->err_state = 1;
389 }
390
391 return 1;
392}
393
f672aee4 394void OPENSSL_cleanup(void)
b184e3ef
MC
395{
396 OPENSSL_INIT_STOP *currhandler, *lasthandler;
397
deca5df2
MC
398 /* If we've not been inited then no need to deinit */
399 if (!base_inited)
400 return;
401
dd27f16e
RS
402 /* Might be explicitly called and also by atexit */
403 if (stopped)
404 return;
405 stopped = 1;
406
b184e3ef
MC
407 /*
408 * Thread stop may not get automatically called by the thread library for
409 * the very last thread in some situations, so call it directly.
410 */
411 ossl_init_thread_stop(ossl_init_get_thread_local(0));
412
413 currhandler = stop_handlers;
414 while (currhandler != NULL) {
415 currhandler->handler();
416 lasthandler = currhandler;
417 currhandler = currhandler->next;
418 OPENSSL_free(lasthandler);
419 }
420 stop_handlers = NULL;
c292b105
MC
421
422 CRYPTO_THREAD_lock_free(init_lock);
423
b184e3ef
MC
424 /*
425 * We assume we are single-threaded for this function, i.e. no race
426 * conditions for the various "*_inited" vars below.
427 */
428
e4ad0763 429#ifndef OPENSSL_NO_COMP
b184e3ef
MC
430 if (zlib_inited) {
431#ifdef OPENSSL_INIT_DEBUG
f672aee4 432 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 433 "comp_zlib_cleanup_int()\n");
b184e3ef 434#endif
b3599dbb 435 comp_zlib_cleanup_int();
b184e3ef 436 }
e4ad0763 437#endif
b184e3ef 438
ed49f43a
MC
439 if (async_inited) {
440# ifdef OPENSSL_INIT_DEBUG
441 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
442 "async_deinit()\n");
443# endif
444 async_deinit();
445 }
ed49f43a 446
b184e3ef
MC
447 if (load_crypto_strings_inited) {
448#ifdef OPENSSL_INIT_DEBUG
f672aee4 449 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 450 "err_free_strings_int()\n");
b184e3ef 451#endif
b3599dbb 452 err_free_strings_int();
b184e3ef
MC
453 }
454
a072ed0c 455 CRYPTO_THREAD_cleanup_local(&threadstopkey);
6bc7bad0 456
b184e3ef 457#ifdef OPENSSL_INIT_DEBUG
58a8fc25 458 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 459 "rand_cleanup_int()\n");
58a8fc25 460 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 461 "conf_modules_free_int()\n");
9749a07a 462#ifndef OPENSSL_NO_ENGINE
ae6412f3 463 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 464 "engine_cleanup_int()\n");
9749a07a 465#endif
58a8fc25 466 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 467 "crypto_cleanup_all_ex_data_int()\n");
58a8fc25 468 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 469 "bio_sock_cleanup_int()\n");
ff234405
MC
470 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
471 "bio_cleanup()\n");
58a8fc25 472 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 473 "evp_cleanup_int()\n");
58a8fc25 474 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
b3599dbb 475 "obj_cleanup_int()\n");
ff234405
MC
476 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
477 "err_cleanup()\n");
9749a07a 478#endif
58a8fc25
MC
479 /*
480 * Note that cleanup order is important:
a535fe12 481 * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
b3599dbb 482 * must be called before engine_cleanup_int()
58a8fc25
MC
483 * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
484 * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
b3599dbb
MC
485 * - conf_modules_free_int() can end up in ENGINE code so must be called
486 * before engine_cleanup_int()
a535fe12
DSH
487 * - ENGINEs and additional EVP algorithms might use added OIDs names so
488 * obj_cleanup_int() must be called last
58a8fc25 489 */
b3599dbb
MC
490 rand_cleanup_int();
491 conf_modules_free_int();
773fd0ba 492#ifndef OPENSSL_NO_ENGINE
b3599dbb 493 engine_cleanup_int();
773fd0ba 494#endif
71a5516d 495 ossl_store_cleanup_int();
b3599dbb 496 crypto_cleanup_all_ex_data_int();
ff234405 497 bio_cleanup();
b3599dbb
MC
498 evp_cleanup_int();
499 obj_cleanup_int();
ff234405
MC
500 err_cleanup();
501
deca5df2 502 base_inited = 0;
b184e3ef
MC
503}
504
b184e3ef
MC
505/*
506 * If this function is called with a non NULL settings value then it must be
507 * called prior to any threads making calls to any OpenSSL functions,
508 * i.e. passing a non-null settings value is assumed to be single-threaded.
509 */
0fc32b07 510int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
b184e3ef 511{
302f7588
MC
512 static int stoperrset = 0;
513
514 if (stopped) {
515 if (!stoperrset) {
516 /*
517 * We only ever set this once to avoid getting into an infinite
518 * loop where the error system keeps trying to init and fails so
519 * sets an error etc
520 */
521 stoperrset = 1;
a4625290 522 CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
302f7588 523 }
0fc32b07 524 return 0;
302f7588 525 }
dd27f16e 526
b7a7f39a 527 if (!base_inited && !RUN_ONCE(&base, ossl_init_base))
b1f1e7ae 528 return 0;
b184e3ef 529
b1f1e7ae 530 if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
c2e4e5d2
RL
531 && !RUN_ONCE(&load_crypto_strings,
532 ossl_init_no_load_crypto_strings))
b1f1e7ae 533 return 0;
b184e3ef 534
b1f1e7ae 535 if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
c2e4e5d2 536 && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
b1f1e7ae 537 return 0;
b184e3ef 538
b1f1e7ae 539 if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
c2e4e5d2 540 && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
b1f1e7ae 541 return 0;
b184e3ef 542
b1f1e7ae 543 if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
c2e4e5d2 544 && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
b1f1e7ae 545 return 0;
b184e3ef 546
b1f1e7ae 547 if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
c2e4e5d2 548 && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
b1f1e7ae 549 return 0;
b184e3ef 550
b1f1e7ae 551 if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
c2e4e5d2 552 && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
b1f1e7ae 553 return 0;
b184e3ef 554
b1f1e7ae 555 if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
c2e4e5d2 556 && !RUN_ONCE(&config, ossl_init_no_config))
b1f1e7ae 557 return 0;
b184e3ef
MC
558
559 if (opts & OPENSSL_INIT_LOAD_CONFIG) {
b1f1e7ae 560 int ret;
c292b105 561 CRYPTO_THREAD_write_lock(init_lock);
cda3ae5b 562 appname = (settings == NULL) ? NULL : settings->appname;
c2e4e5d2 563 ret = RUN_ONCE(&config, ossl_init_config);
c292b105 564 CRYPTO_THREAD_unlock(init_lock);
b1f1e7ae
MC
565 if (!ret)
566 return 0;
b184e3ef
MC
567 }
568
b1f1e7ae 569 if ((opts & OPENSSL_INIT_ASYNC)
c2e4e5d2 570 && !RUN_ONCE(&async, ossl_init_async))
b1f1e7ae 571 return 0;
7626fbf2 572
b184e3ef 573#ifndef OPENSSL_NO_ENGINE
b1f1e7ae 574 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
c2e4e5d2 575 && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
b1f1e7ae 576 return 0;
619eb33a
RL
577# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
578 if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
579 && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
580 return 0;
581# endif
b184e3ef 582# ifndef OPENSSL_NO_RDRAND
b1f1e7ae 583 if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
c2e4e5d2 584 && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
b1f1e7ae 585 return 0;
b184e3ef 586# endif
b1f1e7ae 587 if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
c2e4e5d2 588 && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
b1f1e7ae 589 return 0;
b184e3ef
MC
590# ifndef OPENSSL_NO_STATIC_ENGINE
591# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
b1f1e7ae 592 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
c2e4e5d2 593 && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
b1f1e7ae 594 return 0;
b184e3ef
MC
595# endif
596# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
b1f1e7ae 597 if ((opts & OPENSSL_INIT_ENGINE_CAPI)
c2e4e5d2 598 && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
b1f1e7ae 599 return 0;
b184e3ef 600# endif
6cba4a66 601# if !defined(OPENSSL_NO_AFALGENG)
b1f1e7ae 602 if ((opts & OPENSSL_INIT_ENGINE_AFALG)
c2e4e5d2 603 && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
b1f1e7ae 604 return 0;
6cba4a66 605# endif
b184e3ef
MC
606# endif
607 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
8d00e30f 608 | OPENSSL_INIT_ENGINE_OPENSSL
6cba4a66 609 | OPENSSL_INIT_ENGINE_AFALG)) {
b184e3ef
MC
610 ENGINE_register_all_complete();
611 }
612#endif
613
e4ad0763 614#ifndef OPENSSL_NO_COMP
b1f1e7ae 615 if ((opts & OPENSSL_INIT_ZLIB)
c2e4e5d2 616 && !RUN_ONCE(&zlib, ossl_init_zlib))
b1f1e7ae 617 return 0;
e4ad0763 618#endif
0fc32b07
MC
619
620 return 1;
b184e3ef
MC
621}
622
f672aee4 623int OPENSSL_atexit(void (*handler)(void))
b184e3ef
MC
624{
625 OPENSSL_INIT_STOP *newhand;
626
6e290a25 627#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
5836780f 628 {
5836780f
MC
629 union {
630 void *sym;
631 void (*func)(void);
632 } handlersym;
633
634 handlersym.func = handler;
2b59d1be
MC
635# ifdef DSO_WIN32
636 {
637 HMODULE handle = NULL;
638 BOOL ret;
5836780f 639
2b59d1be
MC
640 /*
641 * We don't use the DSO route for WIN32 because there is a better
642 * way
643 */
644 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
645 | GET_MODULE_HANDLE_EX_FLAG_PIN,
646 handlersym.sym, &handle);
647
648 if (!ret)
649 return 0;
650 }
651# else
652 /*
653 * Deliberately leak a reference to the handler. This will force the
654 * library/code containing the handler to remain loaded until we run the
655 * atexit handler. If -znodelete has been used then this is
656 * unneccessary.
657 */
658 {
659 DSO *dso = NULL;
660
689f112d 661 ERR_set_mark();
2b59d1be
MC
662 dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
663 DSO_free(dso);
689f112d 664 ERR_pop_to_mark();
2b59d1be
MC
665 }
666# endif
5836780f 667 }
b6d5ba1a 668#endif
5836780f 669
b184e3ef
MC
670 newhand = OPENSSL_malloc(sizeof(*newhand));
671 if (newhand == NULL)
672 return 0;
673
674 newhand->handler = handler;
675 newhand->next = stop_handlers;
676 stop_handlers = newhand;
677
678 return 1;
679}