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