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