rand: remove unimplemented librandom stub code
[openssl.git] / crypto / init.c
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 "internal/e_os.h"
14 #include "crypto/cryptlib.h"
15 #include <openssl/err.h>
16 #include "crypto/rand.h"
17 #include "internal/bio.h"
18 #include <openssl/evp.h>
19 #include "crypto/evp.h"
20 #include "internal/conf.h"
21 #include "crypto/async.h"
22 #include "crypto/engine.h"
23 #include "internal/comp.h"
24 #include "internal/err.h"
25 #include "crypto/err.h"
26 #include "crypto/objects.h"
27 #include <stdlib.h>
28 #include <assert.h>
29 #include "internal/thread_once.h"
30 #include "crypto/dso_conf.h"
31 #include "internal/dso.h"
32 #include "crypto/store.h"
33 #include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
34 #include <openssl/trace.h>
35 #include "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     void *err;
192
193     if (!err_shelve_state(&err))
194         return 0;
195
196     OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n");
197     ret = ossl_err_load_crypto_strings();
198
199     err_unshelve_state(err);
200 #endif
201     return ret;
202 }
203
204 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
205                            ossl_init_load_crypto_strings)
206 {
207     /* Do nothing in this case */
208     return 1;
209 }
210
211 static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
212 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
213 {
214     /*
215      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
216      * pulling in all the ciphers during static linking
217      */
218 #ifndef OPENSSL_NO_AUTOALGINIT
219     OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n");
220     openssl_add_all_ciphers_int();
221 #endif
222     return 1;
223 }
224
225 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
226                            ossl_init_add_all_ciphers)
227 {
228     /* Do nothing */
229     return 1;
230 }
231
232 static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
233 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
234 {
235     /*
236      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
237      * pulling in all the ciphers during static linking
238      */
239 #ifndef OPENSSL_NO_AUTOALGINIT
240     OSSL_TRACE(INIT, "openssl_add_all_digests()\n");
241     openssl_add_all_digests_int();
242 #endif
243     return 1;
244 }
245
246 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
247                            ossl_init_add_all_digests)
248 {
249     /* Do nothing */
250     return 1;
251 }
252
253 static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
254 static int config_inited = 0;
255 static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
256 DEFINE_RUN_ONCE_STATIC(ossl_init_config)
257 {
258     int ret = ossl_config_int(NULL);
259
260     config_inited = 1;
261     return ret;
262 }
263 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config)
264 {
265     int ret = ossl_config_int(conf_settings);
266
267     config_inited = 1;
268     return ret;
269 }
270 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
271 {
272     OSSL_TRACE(INIT, "ossl_no_config_int()\n");
273     ossl_no_config_int();
274     config_inited = 1;
275     return 1;
276 }
277
278 static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
279 static int async_inited = 0;
280 DEFINE_RUN_ONCE_STATIC(ossl_init_async)
281 {
282     OSSL_TRACE(INIT, "async_init()\n");
283     if (!async_init())
284         return 0;
285     async_inited = 1;
286     return 1;
287 }
288
289 #ifndef OPENSSL_NO_ENGINE
290 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
291 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
292 {
293     OSSL_TRACE(INIT, "engine_load_openssl_int()\n");
294     engine_load_openssl_int();
295     return 1;
296 }
297 # ifndef OPENSSL_NO_RDRAND
298 static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
299 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
300 {
301     OSSL_TRACE(INIT, "engine_load_rdrand_int()\n");
302     engine_load_rdrand_int();
303     return 1;
304 }
305 # endif
306 static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
307 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
308 {
309     OSSL_TRACE(INIT, "engine_load_dynamic_int()\n");
310     engine_load_dynamic_int();
311     return 1;
312 }
313 # ifndef OPENSSL_NO_STATIC_ENGINE
314 #  ifndef OPENSSL_NO_DEVCRYPTOENG
315 static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
316 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
317 {
318     OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n");
319     engine_load_devcrypto_int();
320     return 1;
321 }
322 #  endif
323 #  if !defined(OPENSSL_NO_PADLOCKENG)
324 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
325 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
326 {
327     OSSL_TRACE(INIT, "engine_load_padlock_int()\n");
328     engine_load_padlock_int();
329     return 1;
330 }
331 #  endif
332 #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
333 static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
334 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
335 {
336     OSSL_TRACE(INIT, "engine_load_capi_int()\n");
337     engine_load_capi_int();
338     return 1;
339 }
340 #  endif
341 #  if !defined(OPENSSL_NO_AFALGENG)
342 static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
343 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
344 {
345     OSSL_TRACE(INIT, "engine_load_afalg_int()\n");
346     engine_load_afalg_int();
347     return 1;
348 }
349 #  endif
350 # endif
351 #endif
352
353 void OPENSSL_cleanup(void)
354 {
355     OPENSSL_INIT_STOP *currhandler, *lasthandler;
356
357     /*
358      * At some point we should consider looking at this function with a view to
359      * moving most/all of this into onfree handlers in OSSL_LIB_CTX.
360      */
361
362     /* If we've not been inited then no need to deinit */
363     if (!base_inited)
364         return;
365
366     /* Might be explicitly called and also by atexit */
367     if (stopped)
368         return;
369     stopped = 1;
370
371     /*
372      * Thread stop may not get automatically called by the thread library for
373      * the very last thread in some situations, so call it directly.
374      */
375     OPENSSL_thread_stop();
376
377     currhandler = stop_handlers;
378     while (currhandler != NULL) {
379         currhandler->handler();
380         lasthandler = currhandler;
381         currhandler = currhandler->next;
382         OPENSSL_free(lasthandler);
383     }
384     stop_handlers = NULL;
385
386     CRYPTO_THREAD_lock_free(optsdone_lock);
387     optsdone_lock = NULL;
388     CRYPTO_THREAD_lock_free(init_lock);
389     init_lock = NULL;
390
391     CRYPTO_THREAD_cleanup_local(&in_init_config_local);
392
393     /*
394      * We assume we are single-threaded for this function, i.e. no race
395      * conditions for the various "*_inited" vars below.
396      */
397
398 #ifndef OPENSSL_NO_COMP
399     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n");
400     ossl_comp_zlib_cleanup();
401     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_brotli_cleanup()\n");
402     ossl_comp_brotli_cleanup();
403     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zstd_cleanup()\n");
404     ossl_comp_zstd_cleanup();
405 #endif
406
407     if (async_inited) {
408         OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n");
409         async_deinit();
410     }
411
412     /*
413      * Note that cleanup order is important:
414      * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so
415      * must be called before engine_cleanup_int()
416      * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
417      * before the ex data handlers are wiped during default ossl_lib_ctx deinit.
418      * - ossl_config_modules_free() can end up in ENGINE code so must be called
419      * before engine_cleanup_int()
420      * - ENGINEs and additional EVP algorithms might use added OIDs names so
421      * ossl_obj_cleanup_int() must be called last
422      */
423     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n");
424     ossl_rand_cleanup_int();
425
426     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n");
427     ossl_config_modules_free();
428
429 #ifndef OPENSSL_NO_ENGINE
430     OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
431     engine_cleanup_int();
432 #endif
433
434 #ifndef OPENSSL_NO_DEPRECATED_3_0
435     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
436     ossl_store_cleanup_int();
437 #endif
438
439     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n");
440     ossl_lib_ctx_default_deinit();
441
442     ossl_cleanup_thread();
443
444     OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
445     bio_cleanup();
446
447     OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n");
448     evp_cleanup_int();
449
450     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n");
451     ossl_obj_cleanup_int();
452
453     OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n");
454     err_cleanup();
455
456     OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n");
457     CRYPTO_secure_malloc_done();
458
459 #ifndef OPENSSL_NO_CMP
460     OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n");
461     OSSL_CMP_log_close();
462 #endif
463
464     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
465     ossl_trace_cleanup();
466
467     base_inited = 0;
468 }
469
470 /*
471  * If this function is called with a non NULL settings value then it must be
472  * called prior to any threads making calls to any OpenSSL functions,
473  * i.e. passing a non-null settings value is assumed to be single-threaded.
474  */
475 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
476 {
477     uint64_t tmp;
478     int aloaddone = 0;
479
480    /* Applications depend on 0 being returned when cleanup was already done */
481     if (stopped) {
482         if (!(opts & OPENSSL_INIT_BASE_ONLY))
483             ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL);
484         return 0;
485     }
486
487     /*
488      * We ignore failures from this function. It is probably because we are
489      * on a platform that doesn't support lockless atomic loads (we may not
490      * have created optsdone_lock yet so we can't use it). This is just an
491      * optimisation to skip the full checks in this function if we don't need
492      * to, so we carry on regardless in the event of failure.
493      *
494      * There could be a race here with other threads, so that optsdone has not
495      * been updated yet, even though the options have in fact been initialised.
496      * This doesn't matter - it just means we will run the full function
497      * unnecessarily - but all the critical code is contained in RUN_ONCE
498      * functions anyway so we are safe.
499      */
500     if (CRYPTO_atomic_load(&optsdone, &tmp, NULL)) {
501         if ((tmp & opts) == opts)
502             return 1;
503         aloaddone = 1;
504     }
505
506     /*
507      * At some point we should look at this function with a view to moving
508      * most/all of this into OSSL_LIB_CTX.
509      *
510      * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
511      * *only* option specified.  With that option we return immediately after
512      * doing the requested limited initialization.  Note that
513      * err_shelve_state() called by us via ossl_init_load_crypto_nodelete()
514      * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with
515      * base already initialized this is a harmless NOOP.
516      *
517      * If we remain the only caller of err_shelve_state() the recursion should
518      * perhaps be removed, but if in doubt, it can be left in place.
519      */
520     if (!RUN_ONCE(&base, ossl_init_base))
521         return 0;
522
523     if (opts & OPENSSL_INIT_BASE_ONLY)
524         return 1;
525
526     /*
527      * optsdone_lock should definitely be set up now, so we can now repeat the
528      * same check from above but be sure that it will work even on platforms
529      * without lockless CRYPTO_atomic_load
530      */
531     if (!aloaddone) {
532         if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock))
533             return 0;
534         if ((tmp & opts) == opts)
535             return 1;
536     }
537
538     /*
539      * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls
540      * should not have the side-effect of setting up exit handlers, and
541      * therefore, this code block is below the INIT_BASE_ONLY-conditioned early
542      * return above.
543      */
544     if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) {
545         if (!RUN_ONCE_ALT(&register_atexit, ossl_init_no_register_atexit,
546                           ossl_init_register_atexit))
547             return 0;
548     } else if (!RUN_ONCE(&register_atexit, ossl_init_register_atexit)) {
549         return 0;
550     }
551
552     if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
553         return 0;
554
555     if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
556             && !RUN_ONCE_ALT(&load_crypto_strings,
557                              ossl_init_no_load_crypto_strings,
558                              ossl_init_load_crypto_strings))
559         return 0;
560
561     if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
562             && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
563         return 0;
564
565     if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
566             && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
567                              ossl_init_add_all_ciphers))
568         return 0;
569
570     if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
571             && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
572         return 0;
573
574     if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
575             && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
576                              ossl_init_add_all_digests))
577         return 0;
578
579     if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
580             && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
581         return 0;
582
583     if ((opts & OPENSSL_INIT_ATFORK)
584             && !openssl_init_fork_handlers())
585         return 0;
586
587     if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
588             && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
589         return 0;
590
591     if (opts & OPENSSL_INIT_LOAD_CONFIG) {
592         int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL;
593
594         /* If called recursively from OBJ_ calls, just skip it. */
595         if (!loading) {
596             int ret;
597
598             if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1))
599                 return 0;
600             if (settings == NULL) {
601                 ret = RUN_ONCE(&config, ossl_init_config);
602             } else {
603                 if (!CRYPTO_THREAD_write_lock(init_lock))
604                     return 0;
605                 conf_settings = settings;
606                 ret = RUN_ONCE_ALT(&config, ossl_init_config_settings,
607                                    ossl_init_config);
608                 conf_settings = NULL;
609                 CRYPTO_THREAD_unlock(init_lock);
610             }
611
612             if (ret <= 0)
613                 return 0;
614         }
615     }
616
617     if ((opts & OPENSSL_INIT_ASYNC)
618             && !RUN_ONCE(&async, ossl_init_async))
619         return 0;
620
621 #ifndef OPENSSL_NO_ENGINE
622     if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
623             && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
624         return 0;
625 # ifndef OPENSSL_NO_RDRAND
626     if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
627             && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
628         return 0;
629 # endif
630     if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
631             && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
632         return 0;
633 # ifndef OPENSSL_NO_STATIC_ENGINE
634 #  ifndef OPENSSL_NO_DEVCRYPTOENG
635     if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
636             && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
637         return 0;
638 #  endif
639 #  if !defined(OPENSSL_NO_PADLOCKENG)
640     if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
641             && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
642         return 0;
643 #  endif
644 #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
645     if ((opts & OPENSSL_INIT_ENGINE_CAPI)
646             && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
647         return 0;
648 #  endif
649 #  if !defined(OPENSSL_NO_AFALGENG)
650     if ((opts & OPENSSL_INIT_ENGINE_AFALG)
651             && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
652         return 0;
653 #  endif
654 # endif
655     if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
656                 | OPENSSL_INIT_ENGINE_OPENSSL
657                 | OPENSSL_INIT_ENGINE_AFALG)) {
658         ENGINE_register_all_complete();
659     }
660 #endif
661
662     if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
663         return 0;
664
665     return 1;
666 }
667
668 int OPENSSL_atexit(void (*handler)(void))
669 {
670     OPENSSL_INIT_STOP *newhand;
671
672 #if !defined(OPENSSL_USE_NODELETE)\
673     && !defined(OPENSSL_NO_PINSHARED)
674     {
675 # if defined(DSO_WIN32) && !defined(_WIN32_WCE)
676         HMODULE handle = NULL;
677         BOOL ret;
678         union {
679             void *sym;
680             void (*func)(void);
681         } handlersym;
682
683         handlersym.func = handler;
684
685         /*
686          * We don't use the DSO route for WIN32 because there is a better
687          * way
688          */
689         ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
690                                 | GET_MODULE_HANDLE_EX_FLAG_PIN,
691                                 handlersym.sym, &handle);
692
693         if (!ret)
694             return 0;
695 # elif !defined(DSO_NONE)
696         /*
697          * Deliberately leak a reference to the handler. This will force the
698          * library/code containing the handler to remain loaded until we run the
699          * atexit handler. If -znodelete has been used then this is
700          * unnecessary.
701          */
702         DSO *dso = NULL;
703         union {
704             void *sym;
705             void (*func)(void);
706         } handlersym;
707
708         handlersym.func = handler;
709
710         ERR_set_mark();
711         dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
712         /* See same code above in ossl_init_base() for an explanation. */
713         OSSL_TRACE1(INIT,
714                    "atexit: obtained DSO reference? %s\n",
715                    (dso == NULL ? "No!" : "Yes."));
716         DSO_free(dso);
717         ERR_pop_to_mark();
718 # endif
719     }
720 #endif
721
722     if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL)
723         return 0;
724
725     newhand->handler = handler;
726     newhand->next = stop_handlers;
727     stop_handlers = newhand;
728
729     return 1;
730 }
731