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