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