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