xref: /freebsd/crypto/openssl/crypto/init.c (revision 34252e89)
1e71b7053SJung-uk Kim /*
2*34252e89SJung-uk Kim  * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim  */
9e71b7053SJung-uk Kim 
10e71b7053SJung-uk Kim #include "e_os.h"
1117f01e99SJung-uk Kim #include "crypto/cryptlib.h"
12e71b7053SJung-uk Kim #include <openssl/err.h>
1317f01e99SJung-uk Kim #include "crypto/rand.h"
14e71b7053SJung-uk Kim #include "internal/bio.h"
15e71b7053SJung-uk Kim #include <openssl/evp.h>
1617f01e99SJung-uk Kim #include "crypto/evp.h"
17e71b7053SJung-uk Kim #include "internal/conf.h"
1817f01e99SJung-uk Kim #include "crypto/async.h"
1917f01e99SJung-uk Kim #include "crypto/engine.h"
20e71b7053SJung-uk Kim #include "internal/comp.h"
21e71b7053SJung-uk Kim #include "internal/err.h"
2217f01e99SJung-uk Kim #include "crypto/err.h"
2317f01e99SJung-uk Kim #include "crypto/objects.h"
24e71b7053SJung-uk Kim #include <stdlib.h>
25e71b7053SJung-uk Kim #include <assert.h>
26e71b7053SJung-uk Kim #include "internal/thread_once.h"
2717f01e99SJung-uk Kim #include "crypto/dso_conf.h"
28e71b7053SJung-uk Kim #include "internal/dso.h"
2917f01e99SJung-uk Kim #include "crypto/store.h"
30e71b7053SJung-uk Kim 
31e71b7053SJung-uk Kim static int stopped = 0;
32e71b7053SJung-uk Kim 
33e71b7053SJung-uk Kim /*
34e71b7053SJung-uk Kim  * Since per-thread-specific-data destructors are not universally
35e71b7053SJung-uk Kim  * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
36e71b7053SJung-uk Kim  * is assumed to have destructor associated. And then an effort is made
37e71b7053SJung-uk Kim  * to call this single destructor on non-pthread platform[s].
38e71b7053SJung-uk Kim  *
39e71b7053SJung-uk Kim  * Initial value is "impossible". It is used as guard value to shortcut
40e71b7053SJung-uk Kim  * destructor for threads terminating before libcrypto is initialized or
41e71b7053SJung-uk Kim  * after it's de-initialized. Access to the key doesn't have to be
42e71b7053SJung-uk Kim  * serialized for the said threads, because they didn't use libcrypto
43da327cd2SJung-uk Kim  * and it doesn't matter if they pick "impossible" or dereference real
44e71b7053SJung-uk Kim  * key value and pull NULL past initialization in the first thread that
45e71b7053SJung-uk Kim  * intends to use libcrypto.
46e71b7053SJung-uk Kim  */
47e71b7053SJung-uk Kim static union {
48e71b7053SJung-uk Kim     long sane;
49e71b7053SJung-uk Kim     CRYPTO_THREAD_LOCAL value;
50e71b7053SJung-uk Kim } destructor_key = { -1 };
51e71b7053SJung-uk Kim 
52e71b7053SJung-uk Kim static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
53e71b7053SJung-uk Kim 
54e71b7053SJung-uk Kim static void ossl_init_thread_destructor(void *local)
55e71b7053SJung-uk Kim {
56e71b7053SJung-uk Kim     ossl_init_thread_stop((struct thread_local_inits_st *)local);
57e71b7053SJung-uk Kim }
58e71b7053SJung-uk Kim 
59e71b7053SJung-uk Kim static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
60e71b7053SJung-uk Kim {
61e71b7053SJung-uk Kim     struct thread_local_inits_st *local =
62e71b7053SJung-uk Kim         CRYPTO_THREAD_get_local(&destructor_key.value);
63e71b7053SJung-uk Kim 
64e71b7053SJung-uk Kim     if (alloc) {
65e71b7053SJung-uk Kim         if (local == NULL
66e71b7053SJung-uk Kim             && (local = OPENSSL_zalloc(sizeof(*local))) != NULL
67e71b7053SJung-uk Kim             && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) {
68e71b7053SJung-uk Kim             OPENSSL_free(local);
69e71b7053SJung-uk Kim             return NULL;
70e71b7053SJung-uk Kim         }
71e71b7053SJung-uk Kim     } else {
72e71b7053SJung-uk Kim         CRYPTO_THREAD_set_local(&destructor_key.value, NULL);
73e71b7053SJung-uk Kim     }
74e71b7053SJung-uk Kim 
75e71b7053SJung-uk Kim     return local;
76e71b7053SJung-uk Kim }
77e71b7053SJung-uk Kim 
78e71b7053SJung-uk Kim typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
79e71b7053SJung-uk Kim struct ossl_init_stop_st {
80e71b7053SJung-uk Kim     void (*handler)(void);
81e71b7053SJung-uk Kim     OPENSSL_INIT_STOP *next;
82e71b7053SJung-uk Kim };
83e71b7053SJung-uk Kim 
84e71b7053SJung-uk Kim static OPENSSL_INIT_STOP *stop_handlers = NULL;
85e71b7053SJung-uk Kim static CRYPTO_RWLOCK *init_lock = NULL;
86e71b7053SJung-uk Kim 
87e71b7053SJung-uk Kim static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
88e71b7053SJung-uk Kim static int base_inited = 0;
89e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_base)
90e71b7053SJung-uk Kim {
91e71b7053SJung-uk Kim     CRYPTO_THREAD_LOCAL key;
92e71b7053SJung-uk Kim 
93e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
94e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
95e71b7053SJung-uk Kim #endif
96e71b7053SJung-uk Kim #ifndef OPENSSL_NO_CRYPTO_MDEBUG
97e71b7053SJung-uk Kim     ossl_malloc_setup_failures();
98e71b7053SJung-uk Kim #endif
99e71b7053SJung-uk Kim     if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor))
100e71b7053SJung-uk Kim         return 0;
101e71b7053SJung-uk Kim     if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
102e71b7053SJung-uk Kim         goto err;
103e71b7053SJung-uk Kim     OPENSSL_cpuid_setup();
104e71b7053SJung-uk Kim 
105e71b7053SJung-uk Kim     destructor_key.value = key;
106e71b7053SJung-uk Kim     base_inited = 1;
107e71b7053SJung-uk Kim     return 1;
108e71b7053SJung-uk Kim 
109e71b7053SJung-uk Kim err:
110e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
111e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n");
112e71b7053SJung-uk Kim #endif
113e71b7053SJung-uk Kim     CRYPTO_THREAD_lock_free(init_lock);
114e71b7053SJung-uk Kim     init_lock = NULL;
115e71b7053SJung-uk Kim 
116e71b7053SJung-uk Kim     CRYPTO_THREAD_cleanup_local(&key);
117e71b7053SJung-uk Kim     return 0;
118e71b7053SJung-uk Kim }
119e71b7053SJung-uk Kim 
1206935a639SJung-uk Kim static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
1216935a639SJung-uk Kim #if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
1226935a639SJung-uk Kim static int win32atexit(void)
1236935a639SJung-uk Kim {
1246935a639SJung-uk Kim     OPENSSL_cleanup();
1256935a639SJung-uk Kim     return 0;
1266935a639SJung-uk Kim }
1276935a639SJung-uk Kim #endif
1286935a639SJung-uk Kim 
1296935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
1306935a639SJung-uk Kim {
1316935a639SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
1326935a639SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
1336935a639SJung-uk Kim #endif
1346935a639SJung-uk Kim #ifndef OPENSSL_SYS_UEFI
1356935a639SJung-uk Kim # ifdef _WIN32
1366935a639SJung-uk Kim     /* We use _onexit() in preference because it gets called on DLL unload */
1376935a639SJung-uk Kim     if (_onexit(win32atexit) == NULL)
1386935a639SJung-uk Kim         return 0;
1396935a639SJung-uk Kim # else
1406935a639SJung-uk Kim     if (atexit(OPENSSL_cleanup) != 0)
1416935a639SJung-uk Kim         return 0;
1426935a639SJung-uk Kim # endif
1436935a639SJung-uk Kim #endif
1446935a639SJung-uk Kim 
1456935a639SJung-uk Kim     return 1;
1466935a639SJung-uk Kim }
1476935a639SJung-uk Kim 
1486935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
1496935a639SJung-uk Kim                            ossl_init_register_atexit)
1506935a639SJung-uk Kim {
1516935a639SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
1526935a639SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
1536935a639SJung-uk Kim #endif
1546935a639SJung-uk Kim     /* Do nothing in this case */
1556935a639SJung-uk Kim     return 1;
1566935a639SJung-uk Kim }
1576935a639SJung-uk Kim 
158e71b7053SJung-uk Kim static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
159e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
160e71b7053SJung-uk Kim {
161e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
162e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n");
163e71b7053SJung-uk Kim #endif
164610a21fdSJung-uk Kim #if !defined(OPENSSL_USE_NODELETE) \
1656935a639SJung-uk Kim     && !defined(OPENSSL_NO_PINSHARED)
166610a21fdSJung-uk Kim # if defined(DSO_WIN32) && !defined(_WIN32_WCE)
167e71b7053SJung-uk Kim     {
168e71b7053SJung-uk Kim         HMODULE handle = NULL;
169e71b7053SJung-uk Kim         BOOL ret;
170e71b7053SJung-uk Kim 
171e71b7053SJung-uk Kim         /* We don't use the DSO route for WIN32 because there is a better way */
172e71b7053SJung-uk Kim         ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
173e71b7053SJung-uk Kim                                 | GET_MODULE_HANDLE_EX_FLAG_PIN,
174e71b7053SJung-uk Kim                                 (void *)&base_inited, &handle);
175e71b7053SJung-uk Kim 
176e71b7053SJung-uk Kim #  ifdef OPENSSL_INIT_DEBUG
177e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n",
178e71b7053SJung-uk Kim                 (ret == TRUE ? "No!" : "Yes."));
179e71b7053SJung-uk Kim #  endif
180e71b7053SJung-uk Kim         return (ret == TRUE) ? 1 : 0;
181e71b7053SJung-uk Kim     }
182610a21fdSJung-uk Kim # elif !defined(DSO_NONE)
183e71b7053SJung-uk Kim     /*
184e71b7053SJung-uk Kim      * Deliberately leak a reference to ourselves. This will force the library
185e71b7053SJung-uk Kim      * to remain loaded until the atexit() handler is run at process exit.
186e71b7053SJung-uk Kim      */
187e71b7053SJung-uk Kim     {
188e71b7053SJung-uk Kim         DSO *dso;
189e71b7053SJung-uk Kim         void *err;
190e71b7053SJung-uk Kim 
191e71b7053SJung-uk Kim         if (!err_shelve_state(&err))
192e71b7053SJung-uk Kim             return 0;
193e71b7053SJung-uk Kim 
194e71b7053SJung-uk Kim         dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
195e71b7053SJung-uk Kim #  ifdef OPENSSL_INIT_DEBUG
196e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n",
197e71b7053SJung-uk Kim                 (dso == NULL ? "No!" : "Yes."));
198e71b7053SJung-uk Kim         /*
199e71b7053SJung-uk Kim          * In case of No!, it is uncertain our exit()-handlers can still be
200e71b7053SJung-uk Kim          * called. After dlclose() the whole library might have been unloaded
201e71b7053SJung-uk Kim          * already.
202e71b7053SJung-uk Kim          */
203e71b7053SJung-uk Kim #  endif
204e71b7053SJung-uk Kim         DSO_free(dso);
205e71b7053SJung-uk Kim         err_unshelve_state(err);
206e71b7053SJung-uk Kim     }
207e71b7053SJung-uk Kim # endif
208e71b7053SJung-uk Kim #endif
209e71b7053SJung-uk Kim 
210e71b7053SJung-uk Kim     return 1;
211e71b7053SJung-uk Kim }
212e71b7053SJung-uk Kim 
213e71b7053SJung-uk Kim static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
214*34252e89SJung-uk Kim 
215e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
216e71b7053SJung-uk Kim {
217e71b7053SJung-uk Kim     int ret = 1;
218e71b7053SJung-uk Kim     /*
219e71b7053SJung-uk Kim      * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
220e71b7053SJung-uk Kim      * pulling in all the error strings during static linking
221e71b7053SJung-uk Kim      */
222e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
223e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
224e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
225e71b7053SJung-uk Kim                     "err_load_crypto_strings_int()\n");
226e71b7053SJung-uk Kim # endif
227e71b7053SJung-uk Kim     ret = err_load_crypto_strings_int();
228e71b7053SJung-uk Kim #endif
229e71b7053SJung-uk Kim     return ret;
230e71b7053SJung-uk Kim }
231e71b7053SJung-uk Kim 
2326935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
2336935a639SJung-uk Kim                            ossl_init_load_crypto_strings)
2346935a639SJung-uk Kim {
2356935a639SJung-uk Kim     /* Do nothing in this case */
2366935a639SJung-uk Kim     return 1;
2376935a639SJung-uk Kim }
2386935a639SJung-uk Kim 
239e71b7053SJung-uk Kim static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
240e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
241e71b7053SJung-uk Kim {
242e71b7053SJung-uk Kim     /*
243e71b7053SJung-uk Kim      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
244e71b7053SJung-uk Kim      * pulling in all the ciphers during static linking
245e71b7053SJung-uk Kim      */
246e71b7053SJung-uk Kim #ifndef OPENSSL_NO_AUTOALGINIT
247e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
248e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
249e71b7053SJung-uk Kim                     "openssl_add_all_ciphers_int()\n");
250e71b7053SJung-uk Kim # endif
251e71b7053SJung-uk Kim     openssl_add_all_ciphers_int();
252e71b7053SJung-uk Kim #endif
253e71b7053SJung-uk Kim     return 1;
254e71b7053SJung-uk Kim }
255e71b7053SJung-uk Kim 
2566935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
2576935a639SJung-uk Kim                            ossl_init_add_all_ciphers)
2586935a639SJung-uk Kim {
2596935a639SJung-uk Kim     /* Do nothing */
2606935a639SJung-uk Kim     return 1;
2616935a639SJung-uk Kim }
2626935a639SJung-uk Kim 
263e71b7053SJung-uk Kim static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
264e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
265e71b7053SJung-uk Kim {
266e71b7053SJung-uk Kim     /*
267e71b7053SJung-uk Kim      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
268e71b7053SJung-uk Kim      * pulling in all the ciphers during static linking
269e71b7053SJung-uk Kim      */
270e71b7053SJung-uk Kim #ifndef OPENSSL_NO_AUTOALGINIT
271e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
272e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
273e71b7053SJung-uk Kim                     "openssl_add_all_digests()\n");
274e71b7053SJung-uk Kim # endif
275e71b7053SJung-uk Kim     openssl_add_all_digests_int();
276e71b7053SJung-uk Kim #endif
277e71b7053SJung-uk Kim     return 1;
278e71b7053SJung-uk Kim }
279e71b7053SJung-uk Kim 
2806935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
2816935a639SJung-uk Kim                            ossl_init_add_all_digests)
282e71b7053SJung-uk Kim {
283e71b7053SJung-uk Kim     /* Do nothing */
284e71b7053SJung-uk Kim     return 1;
285e71b7053SJung-uk Kim }
286e71b7053SJung-uk Kim 
287e71b7053SJung-uk Kim static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
288e71b7053SJung-uk Kim static int config_inited = 0;
2896935a639SJung-uk Kim static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
290e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_config)
291e71b7053SJung-uk Kim {
2926935a639SJung-uk Kim     int ret = openssl_config_int(conf_settings);
293e71b7053SJung-uk Kim     config_inited = 1;
2946935a639SJung-uk Kim     return ret;
295e71b7053SJung-uk Kim }
2966935a639SJung-uk Kim DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
297e71b7053SJung-uk Kim {
298e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
299e71b7053SJung-uk Kim     fprintf(stderr,
300e71b7053SJung-uk Kim             "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
301e71b7053SJung-uk Kim #endif
302e71b7053SJung-uk Kim     openssl_no_config_int();
303e71b7053SJung-uk Kim     config_inited = 1;
304e71b7053SJung-uk Kim     return 1;
305e71b7053SJung-uk Kim }
306e71b7053SJung-uk Kim 
307e71b7053SJung-uk Kim static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
308e71b7053SJung-uk Kim static int async_inited = 0;
309e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_async)
310e71b7053SJung-uk Kim {
311e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
312e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
313e71b7053SJung-uk Kim #endif
314e71b7053SJung-uk Kim     if (!async_init())
315e71b7053SJung-uk Kim         return 0;
316e71b7053SJung-uk Kim     async_inited = 1;
317e71b7053SJung-uk Kim     return 1;
318e71b7053SJung-uk Kim }
319e71b7053SJung-uk Kim 
320e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE
321e71b7053SJung-uk Kim static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
322e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
323e71b7053SJung-uk Kim {
324e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
325e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
326e71b7053SJung-uk Kim                     "engine_load_openssl_int()\n");
327e71b7053SJung-uk Kim # endif
328e71b7053SJung-uk Kim     engine_load_openssl_int();
329e71b7053SJung-uk Kim     return 1;
330e71b7053SJung-uk Kim }
331e71b7053SJung-uk Kim # ifndef OPENSSL_NO_DEVCRYPTOENG
332e71b7053SJung-uk Kim static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
333e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
334e71b7053SJung-uk Kim {
335e71b7053SJung-uk Kim #  ifdef OPENSSL_INIT_DEBUG
336e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
337e71b7053SJung-uk Kim                     "engine_load_devcrypto_int()\n");
338e71b7053SJung-uk Kim #  endif
339e71b7053SJung-uk Kim     engine_load_devcrypto_int();
340e71b7053SJung-uk Kim     return 1;
341e71b7053SJung-uk Kim }
342e71b7053SJung-uk Kim # endif
343e71b7053SJung-uk Kim 
344e71b7053SJung-uk Kim # ifndef OPENSSL_NO_RDRAND
345e71b7053SJung-uk Kim static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
346e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
347e71b7053SJung-uk Kim {
348e71b7053SJung-uk Kim #  ifdef OPENSSL_INIT_DEBUG
349e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
350e71b7053SJung-uk Kim                     "engine_load_rdrand_int()\n");
351e71b7053SJung-uk Kim #  endif
352e71b7053SJung-uk Kim     engine_load_rdrand_int();
353e71b7053SJung-uk Kim     return 1;
354e71b7053SJung-uk Kim }
355e71b7053SJung-uk Kim # endif
356e71b7053SJung-uk Kim static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
357e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
358e71b7053SJung-uk Kim {
359e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
360e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
361e71b7053SJung-uk Kim                     "engine_load_dynamic_int()\n");
362e71b7053SJung-uk Kim # endif
363e71b7053SJung-uk Kim     engine_load_dynamic_int();
364e71b7053SJung-uk Kim     return 1;
365e71b7053SJung-uk Kim }
366e71b7053SJung-uk Kim # ifndef OPENSSL_NO_STATIC_ENGINE
367e71b7053SJung-uk Kim #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
368e71b7053SJung-uk Kim static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
369e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
370e71b7053SJung-uk Kim {
371e71b7053SJung-uk Kim #   ifdef OPENSSL_INIT_DEBUG
372e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
373e71b7053SJung-uk Kim                     "engine_load_padlock_int()\n");
374e71b7053SJung-uk Kim #   endif
375e71b7053SJung-uk Kim     engine_load_padlock_int();
376e71b7053SJung-uk Kim     return 1;
377e71b7053SJung-uk Kim }
378e71b7053SJung-uk Kim #  endif
379e71b7053SJung-uk Kim #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
380e71b7053SJung-uk Kim static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
381e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
382e71b7053SJung-uk Kim {
383e71b7053SJung-uk Kim #   ifdef OPENSSL_INIT_DEBUG
384e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
385e71b7053SJung-uk Kim                     "engine_load_capi_int()\n");
386e71b7053SJung-uk Kim #   endif
387e71b7053SJung-uk Kim     engine_load_capi_int();
388e71b7053SJung-uk Kim     return 1;
389e71b7053SJung-uk Kim }
390e71b7053SJung-uk Kim #  endif
391e71b7053SJung-uk Kim #  if !defined(OPENSSL_NO_AFALGENG)
392e71b7053SJung-uk Kim static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
393e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
394e71b7053SJung-uk Kim {
395e71b7053SJung-uk Kim #   ifdef OPENSSL_INIT_DEBUG
396e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
397e71b7053SJung-uk Kim                     "engine_load_afalg_int()\n");
398e71b7053SJung-uk Kim #   endif
399e71b7053SJung-uk Kim     engine_load_afalg_int();
400e71b7053SJung-uk Kim     return 1;
401e71b7053SJung-uk Kim }
402e71b7053SJung-uk Kim #  endif
403e71b7053SJung-uk Kim # endif
404e71b7053SJung-uk Kim #endif
405e71b7053SJung-uk Kim 
406e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
407e71b7053SJung-uk Kim static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
408e71b7053SJung-uk Kim 
409e71b7053SJung-uk Kim static int zlib_inited = 0;
410e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
411e71b7053SJung-uk Kim {
412e71b7053SJung-uk Kim     /* Do nothing - we need to know about this for the later cleanup */
413e71b7053SJung-uk Kim     zlib_inited = 1;
414e71b7053SJung-uk Kim     return 1;
415e71b7053SJung-uk Kim }
416e71b7053SJung-uk Kim #endif
417e71b7053SJung-uk Kim 
418e71b7053SJung-uk Kim static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
419e71b7053SJung-uk Kim {
420e71b7053SJung-uk Kim     /* Can't do much about this */
421e71b7053SJung-uk Kim     if (locals == NULL)
422e71b7053SJung-uk Kim         return;
423e71b7053SJung-uk Kim 
424e71b7053SJung-uk Kim     if (locals->async) {
425e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
426e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
427e71b7053SJung-uk Kim                         "async_delete_thread_state()\n");
428e71b7053SJung-uk Kim #endif
429e71b7053SJung-uk Kim         async_delete_thread_state();
430e71b7053SJung-uk Kim     }
431e71b7053SJung-uk Kim 
432e71b7053SJung-uk Kim     if (locals->err_state) {
433e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
434e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
435e71b7053SJung-uk Kim                         "err_delete_thread_state()\n");
436e71b7053SJung-uk Kim #endif
437e71b7053SJung-uk Kim         err_delete_thread_state();
438e71b7053SJung-uk Kim     }
439e71b7053SJung-uk Kim 
440e71b7053SJung-uk Kim     if (locals->rand) {
441e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
442e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
443e71b7053SJung-uk Kim                         "drbg_delete_thread_state()\n");
444e71b7053SJung-uk Kim #endif
445e71b7053SJung-uk Kim         drbg_delete_thread_state();
446e71b7053SJung-uk Kim     }
447e71b7053SJung-uk Kim 
448e71b7053SJung-uk Kim     OPENSSL_free(locals);
449e71b7053SJung-uk Kim }
450e71b7053SJung-uk Kim 
451e71b7053SJung-uk Kim void OPENSSL_thread_stop(void)
452e71b7053SJung-uk Kim {
453e71b7053SJung-uk Kim     if (destructor_key.sane != -1)
454e71b7053SJung-uk Kim         ossl_init_thread_stop(ossl_init_get_thread_local(0));
455e71b7053SJung-uk Kim }
456e71b7053SJung-uk Kim 
457e71b7053SJung-uk Kim int ossl_init_thread_start(uint64_t opts)
458e71b7053SJung-uk Kim {
459e71b7053SJung-uk Kim     struct thread_local_inits_st *locals;
460e71b7053SJung-uk Kim 
461e71b7053SJung-uk Kim     if (!OPENSSL_init_crypto(0, NULL))
462e71b7053SJung-uk Kim         return 0;
463e71b7053SJung-uk Kim 
464e71b7053SJung-uk Kim     locals = ossl_init_get_thread_local(1);
465e71b7053SJung-uk Kim 
466e71b7053SJung-uk Kim     if (locals == NULL)
467e71b7053SJung-uk Kim         return 0;
468e71b7053SJung-uk Kim 
469e71b7053SJung-uk Kim     if (opts & OPENSSL_INIT_THREAD_ASYNC) {
470e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
471e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
472e71b7053SJung-uk Kim                         "marking thread for async\n");
473e71b7053SJung-uk Kim #endif
474e71b7053SJung-uk Kim         locals->async = 1;
475e71b7053SJung-uk Kim     }
476e71b7053SJung-uk Kim 
477e71b7053SJung-uk Kim     if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
478e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
479e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
480e71b7053SJung-uk Kim                         "marking thread for err_state\n");
481e71b7053SJung-uk Kim #endif
482e71b7053SJung-uk Kim         locals->err_state = 1;
483e71b7053SJung-uk Kim     }
484e71b7053SJung-uk Kim 
485e71b7053SJung-uk Kim     if (opts & OPENSSL_INIT_THREAD_RAND) {
486e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
487e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
488e71b7053SJung-uk Kim                         "marking thread for rand\n");
489e71b7053SJung-uk Kim #endif
490e71b7053SJung-uk Kim         locals->rand = 1;
491e71b7053SJung-uk Kim     }
492e71b7053SJung-uk Kim 
493e71b7053SJung-uk Kim     return 1;
494e71b7053SJung-uk Kim }
495e71b7053SJung-uk Kim 
496e71b7053SJung-uk Kim void OPENSSL_cleanup(void)
497e71b7053SJung-uk Kim {
498e71b7053SJung-uk Kim     OPENSSL_INIT_STOP *currhandler, *lasthandler;
499e71b7053SJung-uk Kim     CRYPTO_THREAD_LOCAL key;
500e71b7053SJung-uk Kim 
501e71b7053SJung-uk Kim     /* If we've not been inited then no need to deinit */
502e71b7053SJung-uk Kim     if (!base_inited)
503e71b7053SJung-uk Kim         return;
504e71b7053SJung-uk Kim 
505e71b7053SJung-uk Kim     /* Might be explicitly called and also by atexit */
506e71b7053SJung-uk Kim     if (stopped)
507e71b7053SJung-uk Kim         return;
508e71b7053SJung-uk Kim     stopped = 1;
509e71b7053SJung-uk Kim 
510e71b7053SJung-uk Kim     /*
511e71b7053SJung-uk Kim      * Thread stop may not get automatically called by the thread library for
512e71b7053SJung-uk Kim      * the very last thread in some situations, so call it directly.
513e71b7053SJung-uk Kim      */
514e71b7053SJung-uk Kim     ossl_init_thread_stop(ossl_init_get_thread_local(0));
515e71b7053SJung-uk Kim 
516e71b7053SJung-uk Kim     currhandler = stop_handlers;
517e71b7053SJung-uk Kim     while (currhandler != NULL) {
518e71b7053SJung-uk Kim         currhandler->handler();
519e71b7053SJung-uk Kim         lasthandler = currhandler;
520e71b7053SJung-uk Kim         currhandler = currhandler->next;
521e71b7053SJung-uk Kim         OPENSSL_free(lasthandler);
522e71b7053SJung-uk Kim     }
523e71b7053SJung-uk Kim     stop_handlers = NULL;
524e71b7053SJung-uk Kim 
525e71b7053SJung-uk Kim     CRYPTO_THREAD_lock_free(init_lock);
526e71b7053SJung-uk Kim     init_lock = NULL;
527e71b7053SJung-uk Kim 
528e71b7053SJung-uk Kim     /*
529e71b7053SJung-uk Kim      * We assume we are single-threaded for this function, i.e. no race
530e71b7053SJung-uk Kim      * conditions for the various "*_inited" vars below.
531e71b7053SJung-uk Kim      */
532e71b7053SJung-uk Kim 
533e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
534e71b7053SJung-uk Kim     if (zlib_inited) {
535e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
536e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
537e71b7053SJung-uk Kim                         "comp_zlib_cleanup_int()\n");
538e71b7053SJung-uk Kim #endif
539e71b7053SJung-uk Kim         comp_zlib_cleanup_int();
540e71b7053SJung-uk Kim     }
541e71b7053SJung-uk Kim #endif
542e71b7053SJung-uk Kim 
543e71b7053SJung-uk Kim     if (async_inited) {
544e71b7053SJung-uk Kim # ifdef OPENSSL_INIT_DEBUG
545e71b7053SJung-uk Kim         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
546e71b7053SJung-uk Kim                         "async_deinit()\n");
547e71b7053SJung-uk Kim # endif
548e71b7053SJung-uk Kim         async_deinit();
549e71b7053SJung-uk Kim     }
550e71b7053SJung-uk Kim 
551e71b7053SJung-uk Kim     key = destructor_key.value;
552e71b7053SJung-uk Kim     destructor_key.sane = -1;
553e71b7053SJung-uk Kim     CRYPTO_THREAD_cleanup_local(&key);
554e71b7053SJung-uk Kim 
555e71b7053SJung-uk Kim #ifdef OPENSSL_INIT_DEBUG
556e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
557e71b7053SJung-uk Kim                     "rand_cleanup_int()\n");
558e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
559e71b7053SJung-uk Kim                     "conf_modules_free_int()\n");
560e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE
561e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
562e71b7053SJung-uk Kim                     "engine_cleanup_int()\n");
563e71b7053SJung-uk Kim #endif
564e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
565e71b7053SJung-uk Kim                     "crypto_cleanup_all_ex_data_int()\n");
566e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
567e71b7053SJung-uk Kim                     "bio_sock_cleanup_int()\n");
568e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
569e71b7053SJung-uk Kim                     "bio_cleanup()\n");
570e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
571e71b7053SJung-uk Kim                     "evp_cleanup_int()\n");
572e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
573e71b7053SJung-uk Kim                     "obj_cleanup_int()\n");
574e71b7053SJung-uk Kim     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
575e71b7053SJung-uk Kim                     "err_cleanup()\n");
576e71b7053SJung-uk Kim #endif
577e71b7053SJung-uk Kim     /*
578e71b7053SJung-uk Kim      * Note that cleanup order is important:
579e71b7053SJung-uk Kim      * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
580e71b7053SJung-uk Kim      * must be called before engine_cleanup_int()
581e71b7053SJung-uk Kim      * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
582e71b7053SJung-uk Kim      * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
583e71b7053SJung-uk Kim      * - conf_modules_free_int() can end up in ENGINE code so must be called
584e71b7053SJung-uk Kim      * before engine_cleanup_int()
585e71b7053SJung-uk Kim      * - ENGINEs and additional EVP algorithms might use added OIDs names so
586e71b7053SJung-uk Kim      * obj_cleanup_int() must be called last
587e71b7053SJung-uk Kim      */
588e71b7053SJung-uk Kim     rand_cleanup_int();
589e71b7053SJung-uk Kim     rand_drbg_cleanup_int();
590e71b7053SJung-uk Kim     conf_modules_free_int();
591e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE
592e71b7053SJung-uk Kim     engine_cleanup_int();
593e71b7053SJung-uk Kim #endif
594e71b7053SJung-uk Kim     ossl_store_cleanup_int();
595e71b7053SJung-uk Kim     crypto_cleanup_all_ex_data_int();
596e71b7053SJung-uk Kim     bio_cleanup();
597e71b7053SJung-uk Kim     evp_cleanup_int();
598e71b7053SJung-uk Kim     obj_cleanup_int();
599e71b7053SJung-uk Kim     err_cleanup();
600e71b7053SJung-uk Kim 
601e71b7053SJung-uk Kim     CRYPTO_secure_malloc_done();
602e71b7053SJung-uk Kim 
603e71b7053SJung-uk Kim     base_inited = 0;
604e71b7053SJung-uk Kim }
605e71b7053SJung-uk Kim 
606e71b7053SJung-uk Kim /*
607e71b7053SJung-uk Kim  * If this function is called with a non NULL settings value then it must be
608e71b7053SJung-uk Kim  * called prior to any threads making calls to any OpenSSL functions,
609e71b7053SJung-uk Kim  * i.e. passing a non-null settings value is assumed to be single-threaded.
610e71b7053SJung-uk Kim  */
611e71b7053SJung-uk Kim int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
612e71b7053SJung-uk Kim {
613e71b7053SJung-uk Kim     if (stopped) {
614e71b7053SJung-uk Kim         if (!(opts & OPENSSL_INIT_BASE_ONLY))
615e71b7053SJung-uk Kim             CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
616e71b7053SJung-uk Kim         return 0;
617e71b7053SJung-uk Kim     }
618e71b7053SJung-uk Kim 
6196935a639SJung-uk Kim     /*
6206935a639SJung-uk Kim      * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
6216935a639SJung-uk Kim      * *only* option specified.  With that option we return immediately after
6226935a639SJung-uk Kim      * doing the requested limited initialization.  Note that
6236935a639SJung-uk Kim      * err_shelve_state() called by us via ossl_init_load_crypto_nodelete()
6246935a639SJung-uk Kim      * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with
6256935a639SJung-uk Kim      * base already initialized this is a harmless NOOP.
6266935a639SJung-uk Kim      *
6276935a639SJung-uk Kim      * If we remain the only caller of err_shelve_state() the recursion should
6286935a639SJung-uk Kim      * perhaps be removed, but if in doubt, it can be left in place.
6296935a639SJung-uk Kim      */
630e71b7053SJung-uk Kim     if (!RUN_ONCE(&base, ossl_init_base))
631e71b7053SJung-uk Kim         return 0;
6326935a639SJung-uk Kim     if (opts & OPENSSL_INIT_BASE_ONLY)
6336935a639SJung-uk Kim         return 1;
634e71b7053SJung-uk Kim 
6356935a639SJung-uk Kim     /*
6366935a639SJung-uk Kim      * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls
6376935a639SJung-uk Kim      * should not have the side-effect of setting up exit handlers, and
6386935a639SJung-uk Kim      * therefore, this code block is below the INIT_BASE_ONLY-conditioned early
6396935a639SJung-uk Kim      * return above.
6406935a639SJung-uk Kim      */
6416935a639SJung-uk Kim     if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) {
6426935a639SJung-uk Kim         if (!RUN_ONCE_ALT(&register_atexit, ossl_init_no_register_atexit,
6436935a639SJung-uk Kim                           ossl_init_register_atexit))
6446935a639SJung-uk Kim             return 0;
6456935a639SJung-uk Kim     } else if (!RUN_ONCE(&register_atexit, ossl_init_register_atexit)) {
6466935a639SJung-uk Kim         return 0;
6476935a639SJung-uk Kim     }
6486935a639SJung-uk Kim 
6496935a639SJung-uk Kim     if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
650e71b7053SJung-uk Kim         return 0;
651e71b7053SJung-uk Kim 
652e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
6536935a639SJung-uk Kim             && !RUN_ONCE_ALT(&load_crypto_strings,
6546935a639SJung-uk Kim                              ossl_init_no_load_crypto_strings,
6556935a639SJung-uk Kim                              ossl_init_load_crypto_strings))
656e71b7053SJung-uk Kim         return 0;
657e71b7053SJung-uk Kim 
658e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
659e71b7053SJung-uk Kim             && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
660e71b7053SJung-uk Kim         return 0;
661e71b7053SJung-uk Kim 
662e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
6636935a639SJung-uk Kim             && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
6646935a639SJung-uk Kim                              ossl_init_add_all_ciphers))
665e71b7053SJung-uk Kim         return 0;
666e71b7053SJung-uk Kim 
667e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
668e71b7053SJung-uk Kim             && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
669e71b7053SJung-uk Kim         return 0;
670e71b7053SJung-uk Kim 
671e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
6726935a639SJung-uk Kim             && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
6736935a639SJung-uk Kim                              ossl_init_add_all_digests))
674e71b7053SJung-uk Kim         return 0;
675e71b7053SJung-uk Kim 
676e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
677e71b7053SJung-uk Kim             && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
678e71b7053SJung-uk Kim         return 0;
679e71b7053SJung-uk Kim 
680e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ATFORK)
681e71b7053SJung-uk Kim             && !openssl_init_fork_handlers())
682e71b7053SJung-uk Kim         return 0;
683e71b7053SJung-uk Kim 
684e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
6856935a639SJung-uk Kim             && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
686e71b7053SJung-uk Kim         return 0;
687e71b7053SJung-uk Kim 
688e71b7053SJung-uk Kim     if (opts & OPENSSL_INIT_LOAD_CONFIG) {
689e71b7053SJung-uk Kim         int ret;
690e71b7053SJung-uk Kim         CRYPTO_THREAD_write_lock(init_lock);
6916935a639SJung-uk Kim         conf_settings = settings;
692e71b7053SJung-uk Kim         ret = RUN_ONCE(&config, ossl_init_config);
6936935a639SJung-uk Kim         conf_settings = NULL;
694e71b7053SJung-uk Kim         CRYPTO_THREAD_unlock(init_lock);
695610a21fdSJung-uk Kim         if (ret <= 0)
696e71b7053SJung-uk Kim             return 0;
697e71b7053SJung-uk Kim     }
698e71b7053SJung-uk Kim 
699e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ASYNC)
700e71b7053SJung-uk Kim             && !RUN_ONCE(&async, ossl_init_async))
701e71b7053SJung-uk Kim         return 0;
702e71b7053SJung-uk Kim 
703e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE
704e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
705e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
706e71b7053SJung-uk Kim         return 0;
707e71b7053SJung-uk Kim # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
708e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
709e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
710e71b7053SJung-uk Kim         return 0;
711e71b7053SJung-uk Kim # endif
712e71b7053SJung-uk Kim # ifndef OPENSSL_NO_RDRAND
713e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
714e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
715e71b7053SJung-uk Kim         return 0;
716e71b7053SJung-uk Kim # endif
717e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
718e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
719e71b7053SJung-uk Kim         return 0;
720e71b7053SJung-uk Kim # ifndef OPENSSL_NO_STATIC_ENGINE
721e71b7053SJung-uk Kim #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
722e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
723e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
724e71b7053SJung-uk Kim         return 0;
725e71b7053SJung-uk Kim #  endif
726e71b7053SJung-uk Kim #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
727e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_CAPI)
728e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
729e71b7053SJung-uk Kim         return 0;
730e71b7053SJung-uk Kim #  endif
731e71b7053SJung-uk Kim #  if !defined(OPENSSL_NO_AFALGENG)
732e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ENGINE_AFALG)
733e71b7053SJung-uk Kim             && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
734e71b7053SJung-uk Kim         return 0;
735e71b7053SJung-uk Kim #  endif
736e71b7053SJung-uk Kim # endif
737e71b7053SJung-uk Kim     if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
738e71b7053SJung-uk Kim                 | OPENSSL_INIT_ENGINE_OPENSSL
739e71b7053SJung-uk Kim                 | OPENSSL_INIT_ENGINE_AFALG)) {
740e71b7053SJung-uk Kim         ENGINE_register_all_complete();
741e71b7053SJung-uk Kim     }
742e71b7053SJung-uk Kim #endif
743e71b7053SJung-uk Kim 
744e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
745e71b7053SJung-uk Kim     if ((opts & OPENSSL_INIT_ZLIB)
746e71b7053SJung-uk Kim             && !RUN_ONCE(&zlib, ossl_init_zlib))
747e71b7053SJung-uk Kim         return 0;
748e71b7053SJung-uk Kim #endif
749e71b7053SJung-uk Kim 
750e71b7053SJung-uk Kim     return 1;
751e71b7053SJung-uk Kim }
752e71b7053SJung-uk Kim 
753e71b7053SJung-uk Kim int OPENSSL_atexit(void (*handler)(void))
754e71b7053SJung-uk Kim {
755e71b7053SJung-uk Kim     OPENSSL_INIT_STOP *newhand;
756e71b7053SJung-uk Kim 
757610a21fdSJung-uk Kim #if !defined(OPENSSL_USE_NODELETE)\
7586935a639SJung-uk Kim     && !defined(OPENSSL_NO_PINSHARED)
759e71b7053SJung-uk Kim     {
760e71b7053SJung-uk Kim         union {
761e71b7053SJung-uk Kim             void *sym;
762e71b7053SJung-uk Kim             void (*func)(void);
763e71b7053SJung-uk Kim         } handlersym;
764e71b7053SJung-uk Kim 
765e71b7053SJung-uk Kim         handlersym.func = handler;
766610a21fdSJung-uk Kim # if defined(DSO_WIN32) && !defined(_WIN32_WCE)
767e71b7053SJung-uk Kim         {
768e71b7053SJung-uk Kim             HMODULE handle = NULL;
769e71b7053SJung-uk Kim             BOOL ret;
770e71b7053SJung-uk Kim 
771e71b7053SJung-uk Kim             /*
772e71b7053SJung-uk Kim              * We don't use the DSO route for WIN32 because there is a better
773e71b7053SJung-uk Kim              * way
774e71b7053SJung-uk Kim              */
775e71b7053SJung-uk Kim             ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
776e71b7053SJung-uk Kim                                     | GET_MODULE_HANDLE_EX_FLAG_PIN,
777e71b7053SJung-uk Kim                                     handlersym.sym, &handle);
778e71b7053SJung-uk Kim 
779e71b7053SJung-uk Kim             if (!ret)
780e71b7053SJung-uk Kim                 return 0;
781e71b7053SJung-uk Kim         }
782610a21fdSJung-uk Kim # elif !defined(DSO_NONE)
783e71b7053SJung-uk Kim         /*
784e71b7053SJung-uk Kim          * Deliberately leak a reference to the handler. This will force the
785e71b7053SJung-uk Kim          * library/code containing the handler to remain loaded until we run the
786e71b7053SJung-uk Kim          * atexit handler. If -znodelete has been used then this is
787e71b7053SJung-uk Kim          * unnecessary.
788e71b7053SJung-uk Kim          */
789e71b7053SJung-uk Kim         {
790e71b7053SJung-uk Kim             DSO *dso = NULL;
791e71b7053SJung-uk Kim 
792e71b7053SJung-uk Kim             ERR_set_mark();
793e71b7053SJung-uk Kim             dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
794e71b7053SJung-uk Kim #  ifdef OPENSSL_INIT_DEBUG
795e71b7053SJung-uk Kim             fprintf(stderr,
796e71b7053SJung-uk Kim                     "OPENSSL_INIT: OPENSSL_atexit: obtained DSO reference? %s\n",
797e71b7053SJung-uk Kim                     (dso == NULL ? "No!" : "Yes."));
798e71b7053SJung-uk Kim             /* See same code above in ossl_init_base() for an explanation. */
799e71b7053SJung-uk Kim #  endif
800e71b7053SJung-uk Kim             DSO_free(dso);
801e71b7053SJung-uk Kim             ERR_pop_to_mark();
802e71b7053SJung-uk Kim         }
803e71b7053SJung-uk Kim # endif
804e71b7053SJung-uk Kim     }
805e71b7053SJung-uk Kim #endif
806e71b7053SJung-uk Kim 
807e71b7053SJung-uk Kim     if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) {
808e71b7053SJung-uk Kim         CRYPTOerr(CRYPTO_F_OPENSSL_ATEXIT, ERR_R_MALLOC_FAILURE);
809e71b7053SJung-uk Kim         return 0;
810e71b7053SJung-uk Kim     }
811e71b7053SJung-uk Kim 
812e71b7053SJung-uk Kim     newhand->handler = handler;
813e71b7053SJung-uk Kim     newhand->next = stop_handlers;
814e71b7053SJung-uk Kim     stop_handlers = newhand;
815e71b7053SJung-uk Kim 
816e71b7053SJung-uk Kim     return 1;
817e71b7053SJung-uk Kim }
818e71b7053SJung-uk Kim 
819e71b7053SJung-uk Kim #ifdef OPENSSL_SYS_UNIX
820e71b7053SJung-uk Kim /*
821e71b7053SJung-uk Kim  * The following three functions are for OpenSSL developers.  This is
822e71b7053SJung-uk Kim  * where we set/reset state across fork (called via pthread_atfork when
823e71b7053SJung-uk Kim  * it exists, or manually by the application when it doesn't).
824e71b7053SJung-uk Kim  *
825e71b7053SJung-uk Kim  * WARNING!  If you put code in either OPENSSL_fork_parent or
826e71b7053SJung-uk Kim  * OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal-
827e71b7053SJung-uk Kim  * safe.  See this link, for example:
828e71b7053SJung-uk Kim  *      http://man7.org/linux/man-pages/man7/signal-safety.7.html
829e71b7053SJung-uk Kim  */
830e71b7053SJung-uk Kim 
831e71b7053SJung-uk Kim void OPENSSL_fork_prepare(void)
832e71b7053SJung-uk Kim {
833e71b7053SJung-uk Kim }
834e71b7053SJung-uk Kim 
835e71b7053SJung-uk Kim void OPENSSL_fork_parent(void)
836e71b7053SJung-uk Kim {
837e71b7053SJung-uk Kim }
838e71b7053SJung-uk Kim 
839e71b7053SJung-uk Kim void OPENSSL_fork_child(void)
840e71b7053SJung-uk Kim {
841e71b7053SJung-uk Kim }
842e71b7053SJung-uk Kim #endif
843