]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/init.c
Deprecate BIO_sock_cleanup() and make it a no-op
[thirdparty/openssl.git] / crypto / init.c
CommitLineData
b184e3ef
MC
1/*
2 * Written by Matt Caswell for the OpenSSL project.
3 */
4/* ====================================================================
5 * Copyright (c) 2016 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * openssl-core@openssl.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
b1f1e7ae 58#include <internal/threads.h>
b184e3ef
MC
59#include <internal/cryptlib_int.h>
60#include <openssl/err.h>
f3cd81d6 61#include <internal/rand.h>
62d876ad 62#include <internal/bio.h>
b184e3ef 63#include <openssl/evp.h>
b184e3ef
MC
64#include <internal/evp_int.h>
65#include <internal/conf.h>
66#include <internal/async.h>
67#include <internal/engine.h>
02a247e0 68#include <internal/comp.h>
b184e3ef 69#include <internal/err.h>
b184e3ef 70#include <stdlib.h>
dd27f16e
RS
71#include <assert.h>
72
73static int stopped = 0;
b184e3ef 74
71567a6f
MC
75static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
76
a072ed0c 77static CRYPTO_THREAD_LOCAL threadstopkey;
b184e3ef 78
b184e3ef
MC
79static void ossl_init_thread_stop_wrap(void *local)
80{
81 ossl_init_thread_stop((struct thread_local_inits_st *)local);
82}
83
b7326ea7 84static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
b184e3ef 85{
a072ed0c
MC
86 struct thread_local_inits_st *local =
87 CRYPTO_THREAD_get_local(&threadstopkey);
b184e3ef
MC
88
89 if (local == NULL && alloc) {
90 local = OPENSSL_zalloc(sizeof *local);
a072ed0c 91 CRYPTO_THREAD_set_local(&threadstopkey, local);
b184e3ef 92 }
b7326ea7 93 if (!alloc) {
a072ed0c 94 CRYPTO_THREAD_set_local(&threadstopkey, NULL);
b7326ea7 95 }
b184e3ef
MC
96
97 return local;
98}
99
7253fd55 100typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
b184e3ef
MC
101struct ossl_init_stop_st {
102 void (*handler)(void);
103 OPENSSL_INIT_STOP *next;
104};
105
106static OPENSSL_INIT_STOP *stop_handlers = NULL;
c292b105 107static CRYPTO_RWLOCK *init_lock = NULL;
b184e3ef 108
b1f1e7ae 109static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
110static int base_inited = 0;
111static void ossl_init_base(void)
112{
113#ifdef OPENSSL_INIT_DEBUG
114 fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
115#endif
a072ed0c
MC
116 /*
117 * We use a dummy thread local key here. We use the destructor to detect
118 * when the thread is going to stop (where that feature is available)
119 */
120 CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
c7b7938e 121#ifndef OPENSSL_SYS_UEFI
f672aee4 122 atexit(OPENSSL_cleanup);
c7b7938e 123#endif
c292b105 124 init_lock = CRYPTO_THREAD_lock_new();
b184e3ef
MC
125 OPENSSL_cpuid_setup();
126 base_inited = 1;
127}
128
b1f1e7ae 129static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
130static int load_crypto_strings_inited = 0;
131static void ossl_init_no_load_crypto_strings(void)
132{
133 /* Do nothing in this case */
134 return;
135}
136
137static void ossl_init_load_crypto_strings(void)
138{
498abff0
MC
139 /*
140 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
141 * pulling in all the error strings during static linking
142 */
143#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
b184e3ef
MC
144# ifdef OPENSSL_INIT_DEBUG
145 fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
146 "err_load_crypto_strings_intern()\n");
147# endif
b184e3ef 148 err_load_crypto_strings_intern();
b184e3ef
MC
149#endif
150 load_crypto_strings_inited = 1;
151}
152
b1f1e7ae 153static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
154static void ossl_init_add_all_ciphers(void)
155{
156 /*
157 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
158 * pulling in all the ciphers during static linking
159 */
160#ifndef OPENSSL_NO_AUTOALGINIT
161# ifdef OPENSSL_INIT_DEBUG
162 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
163 "openssl_add_all_ciphers_internal()\n");
164# endif
b184e3ef 165 openssl_add_all_ciphers_internal();
b184e3ef
MC
166# ifndef OPENSSL_NO_ENGINE
167# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
168 ENGINE_setup_bsd_cryptodev();
169# endif
170# endif
171#endif
172}
173
b1f1e7ae 174static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
175static void ossl_init_add_all_digests(void)
176{
177 /*
178 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
179 * pulling in all the ciphers during static linking
180 */
181#ifndef OPENSSL_NO_AUTOALGINIT
182# ifdef OPENSSL_INIT_DEBUG
183 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
184 "openssl_add_all_digests_internal()\n");
185# endif
b184e3ef 186 openssl_add_all_digests_internal();
b184e3ef
MC
187# ifndef OPENSSL_NO_ENGINE
188# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
189 ENGINE_setup_bsd_cryptodev();
190# endif
191# endif
192#endif
193}
194
195static void ossl_init_no_add_algs(void)
196{
197 /* Do nothing */
198 return;
199}
200
b1f1e7ae 201static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
202static int config_inited = 0;
203static const char *config_filename;
204static void ossl_init_config(void)
205{
206#ifdef OPENSSL_INIT_DEBUG
207 fprintf(stderr,
208 "OPENSSL_INIT: ossl_init_config: openssl_config_internal(%s)\n",
209 config_filename==NULL?"NULL":config_filename);
210#endif
b184e3ef 211 openssl_config_internal(config_filename);
b184e3ef
MC
212 config_inited = 1;
213}
214static void ossl_init_no_config(void)
215{
216#ifdef OPENSSL_INIT_DEBUG
217 fprintf(stderr,
218 "OPENSSL_INIT: ossl_init_config: openssl_no_config_internal()\n");
219#endif
b184e3ef 220 openssl_no_config_internal();
b184e3ef
MC
221 config_inited = 1;
222}
223
b1f1e7ae 224static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
225static int async_inited = 0;
226static void ossl_init_async(void)
227{
228#ifdef OPENSSL_INIT_DEBUG
229 fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
230#endif
b184e3ef 231 async_init();
b184e3ef
MC
232 async_inited = 1;
233}
234
235#ifndef OPENSSL_NO_ENGINE
b1f1e7ae 236static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
237static void ossl_init_engine_openssl(void)
238{
239# ifdef OPENSSL_INIT_DEBUG
240 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
241 "engine_load_openssl_internal()\n");
242# endif
b184e3ef 243 engine_load_openssl_internal();
b184e3ef
MC
244}
245# if !defined(OPENSSL_NO_HW) && \
246 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
b1f1e7ae 247static CRYPTO_ONCE engine_cryptodev = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
248static void ossl_init_engine_cryptodev(void)
249{
250# ifdef OPENSSL_INIT_DEBUG
251 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: "
252 "engine_load_cryptodev_internal()\n");
253# endif
b184e3ef 254 engine_load_cryptodev_internal();
b184e3ef
MC
255}
256# endif
257
258# ifndef OPENSSL_NO_RDRAND
b1f1e7ae 259static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
260static void ossl_init_engine_rdrand(void)
261{
262# ifdef OPENSSL_INIT_DEBUG
263 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
264 "engine_load_rdrand_internal()\n");
265# endif
b184e3ef 266 engine_load_rdrand_internal();
b184e3ef
MC
267}
268# endif
b1f1e7ae 269static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
270static void ossl_init_engine_dynamic(void)
271{
272# ifdef OPENSSL_INIT_DEBUG
273 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
274 "engine_load_dynamic_internal()\n");
275# endif
b184e3ef 276 engine_load_dynamic_internal();
b184e3ef
MC
277}
278# ifndef OPENSSL_NO_STATIC_ENGINE
279# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
b1f1e7ae 280static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
281static void ossl_init_engine_padlock(void)
282{
283# ifdef OPENSSL_INIT_DEBUG
284 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
285 "engine_load_padlock_internal()\n");
286# endif
b184e3ef 287 engine_load_padlock_internal();
b184e3ef
MC
288}
289# endif
290# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
b1f1e7ae 291static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
292static void ossl_init_engine_capi(void)
293{
294# ifdef OPENSSL_INIT_DEBUG
295 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
296 "engine_load_capi_internal()\n");
297# endif
b184e3ef 298 engine_load_capi_internal();
b184e3ef
MC
299}
300# endif
b1f1e7ae 301static CRYPTO_ONCE engine_dasync = CRYPTO_ONCE_STATIC_INIT;
b184e3ef
MC
302static void ossl_init_engine_dasync(void)
303{
304# ifdef OPENSSL_INIT_DEBUG
305 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dasync: "
306 "engine_load_dasync_internal()\n");
307# endif
b184e3ef 308 engine_load_dasync_internal();
b184e3ef 309}
6cba4a66 310# if !defined(OPENSSL_NO_AFALGENG)
a4d8bcf1 311static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
6cba4a66 312static void ossl_init_engine_afalg(void)
313{
314# ifdef OPENSSL_INIT_DEBUG
315 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
316 "engine_load_afalg_internal()\n");
317# endif
318 engine_load_afalg_internal();
6cba4a66 319}
320# endif
b184e3ef
MC
321# endif
322#endif
323
e4ad0763 324#ifndef OPENSSL_NO_COMP
b1f1e7ae 325static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
e4ad0763 326
b184e3ef
MC
327static int zlib_inited = 0;
328static void ossl_init_zlib(void)
329{
330 /* Do nothing - we need to know about this for the later cleanup */
331 zlib_inited = 1;
332}
e4ad0763 333#endif
b184e3ef 334
71567a6f 335static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
b184e3ef
MC
336{
337 /* Can't do much about this */
338 if (locals == NULL)
339 return;
340
341 if (locals->async) {
342#ifdef OPENSSL_INIT_DEBUG
343 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
344 "ASYNC_cleanup_thread()\n");
345#endif
346 ASYNC_cleanup_thread();
347 }
348
349 if (locals->err_state) {
350#ifdef OPENSSL_INIT_DEBUG
351 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
8509dcc9 352 "ERR_remove_thread_state()\n");
b184e3ef 353#endif
8509dcc9 354 ERR_remove_thread_state();
b184e3ef
MC
355 }
356
357 OPENSSL_free(locals);
b184e3ef
MC
358}
359
f672aee4 360void OPENSSL_thread_stop(void)
71567a6f
MC
361{
362 ossl_init_thread_stop(
363 (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
364}
365
b184e3ef
MC
366int ossl_init_thread_start(uint64_t opts)
367{
368 struct thread_local_inits_st *locals = ossl_init_get_thread_local(1);
369
370 if (locals == NULL)
371 return 0;
372
373 if (opts & OPENSSL_INIT_THREAD_ASYNC) {
374#ifdef OPENSSL_INIT_DEBUG
375 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
376 "marking thread for async\n");
377#endif
378 locals->async = 1;
379 }
380
381 if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
382#ifdef OPENSSL_INIT_DEBUG
383 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
384 "marking thread for err_state\n");
385#endif
386 locals->err_state = 1;
387 }
388
389 return 1;
390}
391
f672aee4 392void OPENSSL_cleanup(void)
b184e3ef
MC
393{
394 OPENSSL_INIT_STOP *currhandler, *lasthandler;
395
deca5df2
MC
396 /* If we've not been inited then no need to deinit */
397 if (!base_inited)
398 return;
399
dd27f16e
RS
400 /* Might be explicitly called and also by atexit */
401 if (stopped)
402 return;
403 stopped = 1;
404
b184e3ef
MC
405 /*
406 * Thread stop may not get automatically called by the thread library for
407 * the very last thread in some situations, so call it directly.
408 */
409 ossl_init_thread_stop(ossl_init_get_thread_local(0));
410
411 currhandler = stop_handlers;
412 while (currhandler != NULL) {
413 currhandler->handler();
414 lasthandler = currhandler;
415 currhandler = currhandler->next;
416 OPENSSL_free(lasthandler);
417 }
418 stop_handlers = NULL;
c292b105
MC
419
420 CRYPTO_THREAD_lock_free(init_lock);
421
b184e3ef
MC
422 /*
423 * We assume we are single-threaded for this function, i.e. no race
424 * conditions for the various "*_inited" vars below.
425 */
426
e4ad0763 427#ifndef OPENSSL_NO_COMP
b184e3ef
MC
428 if (zlib_inited) {
429#ifdef OPENSSL_INIT_DEBUG
f672aee4 430 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
02a247e0 431 "comp_zlib_cleanup_internal()\n");
b184e3ef 432#endif
02a247e0 433 comp_zlib_cleanup_internal();
b184e3ef 434 }
e4ad0763 435#endif
b184e3ef 436
ed49f43a
MC
437 if (async_inited) {
438# ifdef OPENSSL_INIT_DEBUG
439 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
440 "async_deinit()\n");
441# endif
442 async_deinit();
443 }
ed49f43a 444
b184e3ef
MC
445 if (load_crypto_strings_inited) {
446#ifdef OPENSSL_INIT_DEBUG
f672aee4 447 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
6827cb36 448 "err_free_strings_intern()\n");
b184e3ef 449#endif
6827cb36 450 err_free_strings_intern();
b184e3ef
MC
451 }
452
a072ed0c 453 CRYPTO_THREAD_cleanup_local(&threadstopkey);
6bc7bad0 454
b184e3ef 455#ifdef OPENSSL_INIT_DEBUG
58a8fc25 456 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
f3cd81d6 457 "rand_cleanup_intern()\n");
58a8fc25
MC
458 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
459 "CONF_modules_free()\n");
9749a07a 460#ifndef OPENSSL_NO_ENGINE
ae6412f3
MC
461 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
462 "ENGINE_cleanup()\n");
9749a07a 463#endif
58a8fc25 464 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
a5e3ac13 465 "crypto_cleanup_all_ex_data_intern()\n");
58a8fc25 466 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
62d876ad 467 "bio_sock_cleanup_intern()\n");
58a8fc25 468 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
deca5df2 469 "EVP_cleanup()\n");
58a8fc25
MC
470 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
471 "OBJ_cleanup()\n");
9749a07a 472#endif
58a8fc25
MC
473 /*
474 * Note that cleanup order is important:
f3cd81d6
MC
475 * - rand_cleanup_intern could call an ENINGE's RAND cleanup function so
476 * must be called before ENGINE_cleanup()
58a8fc25
MC
477 * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
478 * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
479 * - CONF_modules_free() can end up in ENGINE code so must be called before
480 * ENGINE_cleanup()
481 */
f3cd81d6 482 rand_cleanup_intern();
58a8fc25 483 CONF_modules_free();
773fd0ba
MC
484#ifndef OPENSSL_NO_ENGINE
485 ENGINE_cleanup();
486#endif
a5e3ac13 487 crypto_cleanup_all_ex_data_intern();
f9e55034 488#ifndef OPENSSL_NO_SOCK
62d876ad 489 bio_sock_cleanup_intern();
f9e55034 490#endif
8cab4e9b 491 EVP_cleanup();
b10cdcce 492 OBJ_cleanup();
deca5df2 493 base_inited = 0;
b184e3ef
MC
494}
495
b184e3ef
MC
496/*
497 * If this function is called with a non NULL settings value then it must be
498 * called prior to any threads making calls to any OpenSSL functions,
499 * i.e. passing a non-null settings value is assumed to be single-threaded.
500 */
0fc32b07 501int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
b184e3ef 502{
302f7588
MC
503 static int stoperrset = 0;
504
505 if (stopped) {
506 if (!stoperrset) {
507 /*
508 * We only ever set this once to avoid getting into an infinite
509 * loop where the error system keeps trying to init and fails so
510 * sets an error etc
511 */
512 stoperrset = 1;
a4625290 513 CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
302f7588 514 }
0fc32b07 515 return 0;
302f7588 516 }
dd27f16e 517
b1f1e7ae
MC
518 if (!CRYPTO_THREAD_run_once(&base, ossl_init_base))
519 return 0;
b184e3ef 520
b1f1e7ae
MC
521 if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
522 && !CRYPTO_THREAD_run_once(&load_crypto_strings,
523 ossl_init_no_load_crypto_strings))
524 return 0;
b184e3ef 525
b1f1e7ae
MC
526 if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
527 && !CRYPTO_THREAD_run_once(&load_crypto_strings,
528 ossl_init_load_crypto_strings))
529 return 0;
b184e3ef 530
b1f1e7ae
MC
531 if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
532 && !CRYPTO_THREAD_run_once(&add_all_ciphers, ossl_init_no_add_algs))
533 return 0;
b184e3ef 534
b1f1e7ae
MC
535 if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
536 && !CRYPTO_THREAD_run_once(&add_all_ciphers,
537 ossl_init_add_all_ciphers))
538 return 0;
b184e3ef 539
b1f1e7ae
MC
540 if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
541 && !CRYPTO_THREAD_run_once(&add_all_digests, ossl_init_no_add_algs))
542 return 0;
b184e3ef 543
b1f1e7ae
MC
544 if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
545 && !CRYPTO_THREAD_run_once(&add_all_digests,
546 ossl_init_add_all_digests))
547 return 0;
b184e3ef 548
b1f1e7ae
MC
549 if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
550 && !CRYPTO_THREAD_run_once(&config, ossl_init_no_config))
551 return 0;
b184e3ef
MC
552
553 if (opts & OPENSSL_INIT_LOAD_CONFIG) {
b1f1e7ae 554 int ret;
c292b105 555 CRYPTO_THREAD_write_lock(init_lock);
7253fd55 556 config_filename = (settings == NULL) ? NULL : settings->config_name;
b1f1e7ae 557 ret = CRYPTO_THREAD_run_once(&config, ossl_init_config);
c292b105 558 CRYPTO_THREAD_unlock(init_lock);
b1f1e7ae
MC
559 if (!ret)
560 return 0;
b184e3ef
MC
561 }
562
b1f1e7ae
MC
563 if ((opts & OPENSSL_INIT_ASYNC)
564 && !CRYPTO_THREAD_run_once(&async, ossl_init_async))
565 return 0;
7626fbf2 566
b184e3ef 567#ifndef OPENSSL_NO_ENGINE
b1f1e7ae
MC
568 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
569 && !CRYPTO_THREAD_run_once(&engine_openssl,
570 ossl_init_engine_openssl))
571 return 0;
b184e3ef
MC
572# if !defined(OPENSSL_NO_HW) && \
573 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
b1f1e7ae
MC
574 if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
575 && !CRYPTO_THREAD_run_once(&engine_cryptodev,
576 ossl_init_engine_cryptodev))
577 return 0;
b184e3ef
MC
578# endif
579# ifndef OPENSSL_NO_RDRAND
b1f1e7ae
MC
580 if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
581 && !CRYPTO_THREAD_run_once(&engine_rdrand, ossl_init_engine_rdrand))
582 return 0;
b184e3ef 583# endif
b1f1e7ae
MC
584 if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
585 && !CRYPTO_THREAD_run_once(&engine_dynamic,
586 ossl_init_engine_dynamic))
587 return 0;
b184e3ef
MC
588# ifndef OPENSSL_NO_STATIC_ENGINE
589# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
b1f1e7ae 590 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
3ddd1d04
EK
591 && !CRYPTO_THREAD_run_once(&engine_padlock,
592 ossl_init_engine_padlock))
b1f1e7ae 593 return 0;
b184e3ef
MC
594# endif
595# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
b1f1e7ae 596 if ((opts & OPENSSL_INIT_ENGINE_CAPI)
3ddd1d04 597 && !CRYPTO_THREAD_run_once(&engine_capi, ossl_init_engine_capi))
b1f1e7ae 598 return 0;
b184e3ef 599# endif
b1f1e7ae
MC
600 if ((opts & OPENSSL_INIT_ENGINE_DASYNC)
601 && !CRYPTO_THREAD_run_once(&engine_dasync, ossl_init_engine_dasync))
602 return 0;
6cba4a66 603# if !defined(OPENSSL_NO_AFALGENG)
b1f1e7ae
MC
604 if ((opts & OPENSSL_INIT_ENGINE_AFALG)
605 && !CRYPTO_THREAD_run_once(&engine_afalg, ossl_init_engine_afalg))
606 return 0;
6cba4a66 607# endif
b184e3ef
MC
608# endif
609 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
6cba4a66 610 | OPENSSL_INIT_ENGINE_DASYNC | OPENSSL_INIT_ENGINE_OPENSSL
611 | OPENSSL_INIT_ENGINE_AFALG)) {
b184e3ef
MC
612 ENGINE_register_all_complete();
613 }
614#endif
615
e4ad0763 616#ifndef OPENSSL_NO_COMP
b1f1e7ae 617 if ((opts & OPENSSL_INIT_ZLIB)
3ddd1d04 618 && !CRYPTO_THREAD_run_once(&zlib, ossl_init_zlib))
b1f1e7ae 619 return 0;
e4ad0763 620#endif
0fc32b07
MC
621
622 return 1;
b184e3ef
MC
623}
624
f672aee4 625int OPENSSL_atexit(void (*handler)(void))
b184e3ef
MC
626{
627 OPENSSL_INIT_STOP *newhand;
628
629 newhand = OPENSSL_malloc(sizeof(*newhand));
630 if (newhand == NULL)
631 return 0;
632
633 newhand->handler = handler;
634 newhand->next = stop_handlers;
635 stop_handlers = newhand;
636
637 return 1;
638}