Improve use of the test framework in the SM2 internal tests
[openssl.git] / crypto / init.c
1 /*
2  * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 #include "e_os.h"
11 #include "internal/cryptlib_int.h"
12 #include <openssl/err.h>
13 #include "internal/rand_int.h"
14 #include "internal/bio.h"
15 #include <openssl/evp.h>
16 #include "internal/evp_int.h"
17 #include "internal/conf.h"
18 #include "internal/async.h"
19 #include "internal/engine.h"
20 #include "internal/comp.h"
21 #include "internal/err.h"
22 #include "internal/err_int.h"
23 #include "internal/objects.h"
24 #include <stdlib.h>
25 #include <assert.h>
26 #include "internal/thread_once.h"
27 #include "internal/dso_conf.h"
28 #include "internal/dso.h"
29 #include "internal/store.h"
30
31 static int stopped = 0;
32
33 static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
34
35 static CRYPTO_THREAD_LOCAL threadstopkey;
36
37 static void ossl_init_thread_stop_wrap(void *local)
38 {
39     ossl_init_thread_stop((struct thread_local_inits_st *)local);
40 }
41
42 static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
43 {
44     struct thread_local_inits_st *local =
45         CRYPTO_THREAD_get_local(&threadstopkey);
46
47     if (local == NULL && alloc) {
48         local = OPENSSL_zalloc(sizeof(*local));
49         if (local != NULL && !CRYPTO_THREAD_set_local(&threadstopkey, local)) {
50             OPENSSL_free(local);
51             return NULL;
52         }
53     }
54     if (!alloc) {
55         CRYPTO_THREAD_set_local(&threadstopkey, NULL);
56     }
57
58     return local;
59 }
60
61 typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
62 struct ossl_init_stop_st {
63     void (*handler)(void);
64     OPENSSL_INIT_STOP *next;
65 };
66
67 static OPENSSL_INIT_STOP *stop_handlers = NULL;
68 static CRYPTO_RWLOCK *init_lock = NULL;
69
70 static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
71 static int base_inited = 0;
72 DEFINE_RUN_ONCE_STATIC(ossl_init_base)
73 {
74 #ifdef OPENSSL_INIT_DEBUG
75     fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
76 #endif
77 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
78     ossl_malloc_setup_failures();
79 #endif
80     /*
81      * We use a dummy thread local key here. We use the destructor to detect
82      * when the thread is going to stop (where that feature is available)
83      */
84     if (!CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap))
85         return 0;
86     if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
87         goto err;
88 #ifndef OPENSSL_SYS_UEFI
89     if (atexit(OPENSSL_cleanup) != 0)
90         goto err;
91 #endif
92     OPENSSL_cpuid_setup();
93
94     base_inited = 1;
95     return 1;
96
97 err:
98 #ifdef OPENSSL_INIT_DEBUG
99     fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n");
100 #endif
101     CRYPTO_THREAD_lock_free(init_lock);
102     init_lock = NULL;
103
104     CRYPTO_THREAD_cleanup_local(&threadstopkey);
105     return 0;
106 }
107
108 static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
109 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
110 {
111 #ifdef OPENSSL_INIT_DEBUG
112     fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n");
113 #endif
114 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
115 # ifdef DSO_WIN32
116     {
117         HMODULE handle = NULL;
118         BOOL ret;
119
120         /* We don't use the DSO route for WIN32 because there is a better way */
121         ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
122                                 | GET_MODULE_HANDLE_EX_FLAG_PIN,
123                                 (void *)&base_inited, &handle);
124
125 #  ifdef OPENSSL_INIT_DEBUG
126         fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n",
127                 (ret == TRUE ? "No!" : "Yes."));
128 #  endif
129         return (ret == TRUE) ? 1 : 0;
130     }
131 # else
132     /*
133      * Deliberately leak a reference to ourselves. This will force the library
134      * to remain loaded until the atexit() handler is run at process exit.
135      */
136     {
137         DSO *dso;
138         void *err;
139
140         if (!err_shelve_state(&err))
141             return 0;
142
143         dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
144 #  ifdef OPENSSL_INIT_DEBUG
145         fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n",
146                 (dso == NULL ? "No!" : "Yes."));
147         /*
148          * In case of No!, it is uncertain our exit()-handlers can still be
149          * called. After dlclose() the whole library might have been unloaded
150          * already.
151          */
152 #  endif
153         DSO_free(dso);
154         err_unshelve_state(err);
155     }
156 # endif
157 #endif
158
159     return 1;
160 }
161
162 static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
163 static int load_crypto_strings_inited = 0;
164 DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings)
165 {
166     /* Do nothing in this case */
167     return 1;
168 }
169
170 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
171 {
172     int ret = 1;
173     /*
174      * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
175      * pulling in all the error strings during static linking
176      */
177 #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
178 # ifdef OPENSSL_INIT_DEBUG
179     fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
180                     "err_load_crypto_strings_int()\n");
181 # endif
182     ret = err_load_crypto_strings_int();
183     load_crypto_strings_inited = 1;
184 #endif
185     return ret;
186 }
187
188 static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
189 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
190 {
191     /*
192      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
193      * pulling in all the ciphers during static linking
194      */
195 #ifndef OPENSSL_NO_AUTOALGINIT
196 # ifdef OPENSSL_INIT_DEBUG
197     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
198                     "openssl_add_all_ciphers_int()\n");
199 # endif
200     openssl_add_all_ciphers_int();
201 #endif
202     return 1;
203 }
204
205 static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
206 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
207 {
208     /*
209      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
210      * pulling in all the ciphers during static linking
211      */
212 #ifndef OPENSSL_NO_AUTOALGINIT
213 # ifdef OPENSSL_INIT_DEBUG
214     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
215                     "openssl_add_all_digests()\n");
216 # endif
217     openssl_add_all_digests_int();
218 #endif
219     return 1;
220 }
221
222 DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
223 {
224     /* Do nothing */
225     return 1;
226 }
227
228 static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
229 static int config_inited = 0;
230 static const char *appname;
231 DEFINE_RUN_ONCE_STATIC(ossl_init_config)
232 {
233 #ifdef OPENSSL_INIT_DEBUG
234     fprintf(stderr,
235             "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n",
236             appname == NULL ? "NULL" : appname);
237 #endif
238     openssl_config_int(appname);
239     config_inited = 1;
240     return 1;
241 }
242 DEFINE_RUN_ONCE_STATIC(ossl_init_no_config)
243 {
244 #ifdef OPENSSL_INIT_DEBUG
245     fprintf(stderr,
246             "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
247 #endif
248     openssl_no_config_int();
249     config_inited = 1;
250     return 1;
251 }
252
253 static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
254 static int async_inited = 0;
255 DEFINE_RUN_ONCE_STATIC(ossl_init_async)
256 {
257 #ifdef OPENSSL_INIT_DEBUG
258     fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
259 #endif
260     if (!async_init())
261         return 0;
262     async_inited = 1;
263     return 1;
264 }
265
266 #ifndef OPENSSL_NO_ENGINE
267 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
268 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
269 {
270 # ifdef OPENSSL_INIT_DEBUG
271     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
272                     "engine_load_openssl_int()\n");
273 # endif
274     engine_load_openssl_int();
275     return 1;
276 }
277 # ifndef OPENSSL_NO_DEVCRYPTOENG
278 static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
279 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
280 {
281 #  ifdef OPENSSL_INIT_DEBUG
282     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
283                     "engine_load_devcrypto_int()\n");
284 #  endif
285     engine_load_devcrypto_int();
286     return 1;
287 }
288 # endif
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 #  ifdef OPENSSL_INIT_DEBUG
295     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
296                     "engine_load_rdrand_int()\n");
297 #  endif
298     engine_load_rdrand_int();
299     return 1;
300 }
301 # endif
302 static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
303 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
304 {
305 # ifdef OPENSSL_INIT_DEBUG
306     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
307                     "engine_load_dynamic_int()\n");
308 # endif
309     engine_load_dynamic_int();
310     return 1;
311 }
312 # ifndef OPENSSL_NO_STATIC_ENGINE
313 #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
314 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
315 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
316 {
317 #   ifdef OPENSSL_INIT_DEBUG
318     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
319                     "engine_load_padlock_int()\n");
320 #   endif
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 #   ifdef OPENSSL_INIT_DEBUG
330     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
331                     "engine_load_capi_int()\n");
332 #   endif
333     engine_load_capi_int();
334     return 1;
335 }
336 #  endif
337 #  if !defined(OPENSSL_NO_AFALGENG)
338 static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
339 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
340 {
341 #   ifdef OPENSSL_INIT_DEBUG
342     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
343                     "engine_load_afalg_int()\n");
344 #   endif
345     engine_load_afalg_int();
346     return 1;
347 }
348 #  endif
349 # endif
350 #endif
351
352 #ifndef OPENSSL_NO_COMP
353 static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
354
355 static int zlib_inited = 0;
356 DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
357 {
358     /* Do nothing - we need to know about this for the later cleanup */
359     zlib_inited = 1;
360     return 1;
361 }
362 #endif
363
364 static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
365 {
366     /* Can't do much about this */
367     if (locals == NULL)
368         return;
369
370     if (locals->async) {
371 #ifdef OPENSSL_INIT_DEBUG
372         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
373                         "async_delete_thread_state()\n");
374 #endif
375         async_delete_thread_state();
376     }
377
378     if (locals->err_state) {
379 #ifdef OPENSSL_INIT_DEBUG
380         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
381                         "err_delete_thread_state()\n");
382 #endif
383         err_delete_thread_state();
384     }
385
386     if (locals->rand) {
387 #ifdef OPENSSL_INIT_DEBUG
388         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
389                         "drbg_delete_thread_state()\n");
390 #endif
391         drbg_delete_thread_state();
392     }
393
394     OPENSSL_free(locals);
395 }
396
397 void OPENSSL_thread_stop(void)
398 {
399     ossl_init_thread_stop(
400         (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
401 }
402
403 int ossl_init_thread_start(uint64_t opts)
404 {
405     struct thread_local_inits_st *locals;
406
407     if (!OPENSSL_init_crypto(0, NULL))
408         return 0;
409
410     locals = ossl_init_get_thread_local(1);
411
412     if (locals == NULL)
413         return 0;
414
415     if (opts & OPENSSL_INIT_THREAD_ASYNC) {
416 #ifdef OPENSSL_INIT_DEBUG
417         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
418                         "marking thread for async\n");
419 #endif
420         locals->async = 1;
421     }
422
423     if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
424 #ifdef OPENSSL_INIT_DEBUG
425         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
426                         "marking thread for err_state\n");
427 #endif
428         locals->err_state = 1;
429     }
430
431     if (opts & OPENSSL_INIT_THREAD_RAND) {
432 #ifdef OPENSSL_INIT_DEBUG
433         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
434                         "marking thread for rand\n");
435 #endif
436         locals->rand = 1;
437     }
438
439     return 1;
440 }
441
442 void OPENSSL_cleanup(void)
443 {
444     OPENSSL_INIT_STOP *currhandler, *lasthandler;
445
446     /* If we've not been inited then no need to deinit */
447     if (!base_inited)
448         return;
449
450     /* Might be explicitly called and also by atexit */
451     if (stopped)
452         return;
453     stopped = 1;
454
455     /*
456      * Thread stop may not get automatically called by the thread library for
457      * the very last thread in some situations, so call it directly.
458      */
459     ossl_init_thread_stop(ossl_init_get_thread_local(0));
460
461     currhandler = stop_handlers;
462     while (currhandler != NULL) {
463         currhandler->handler();
464         lasthandler = currhandler;
465         currhandler = currhandler->next;
466         OPENSSL_free(lasthandler);
467     }
468     stop_handlers = NULL;
469
470     CRYPTO_THREAD_lock_free(init_lock);
471     init_lock = NULL;
472
473     /*
474      * We assume we are single-threaded for this function, i.e. no race
475      * conditions for the various "*_inited" vars below.
476      */
477
478 #ifndef OPENSSL_NO_COMP
479     if (zlib_inited) {
480 #ifdef OPENSSL_INIT_DEBUG
481         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
482                         "comp_zlib_cleanup_int()\n");
483 #endif
484         comp_zlib_cleanup_int();
485     }
486 #endif
487
488     if (async_inited) {
489 # ifdef OPENSSL_INIT_DEBUG
490         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
491                         "async_deinit()\n");
492 # endif
493         async_deinit();
494     }
495
496     if (load_crypto_strings_inited) {
497 #ifdef OPENSSL_INIT_DEBUG
498         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
499                         "err_free_strings_int()\n");
500 #endif
501         err_free_strings_int();
502     }
503
504     CRYPTO_THREAD_cleanup_local(&threadstopkey);
505
506 #ifdef OPENSSL_INIT_DEBUG
507     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
508                     "rand_cleanup_int()\n");
509     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
510                     "conf_modules_free_int()\n");
511 #ifndef OPENSSL_NO_ENGINE
512     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
513                     "engine_cleanup_int()\n");
514 #endif
515     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
516                     "crypto_cleanup_all_ex_data_int()\n");
517     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
518                     "bio_sock_cleanup_int()\n");
519     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
520                     "bio_cleanup()\n");
521     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
522                     "evp_cleanup_int()\n");
523     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
524                     "obj_cleanup_int()\n");
525     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
526                     "err_cleanup()\n");
527 #endif
528     /*
529      * Note that cleanup order is important:
530      * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
531      * must be called before engine_cleanup_int()
532      * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
533      * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
534      * - conf_modules_free_int() can end up in ENGINE code so must be called
535      * before engine_cleanup_int()
536      * - ENGINEs and additional EVP algorithms might use added OIDs names so
537      * obj_cleanup_int() must be called last
538      */
539     rand_cleanup_int();
540     rand_drbg_cleanup_int();
541     conf_modules_free_int();
542 #ifndef OPENSSL_NO_ENGINE
543     engine_cleanup_int();
544 #endif
545     ossl_store_cleanup_int();
546     crypto_cleanup_all_ex_data_int();
547     bio_cleanup();
548     evp_cleanup_int();
549     obj_cleanup_int();
550     err_cleanup();
551
552     CRYPTO_secure_malloc_done();
553
554     base_inited = 0;
555 }
556
557 /*
558  * If this function is called with a non NULL settings value then it must be
559  * called prior to any threads making calls to any OpenSSL functions,
560  * i.e. passing a non-null settings value is assumed to be single-threaded.
561  */
562 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
563 {
564     if (stopped) {
565         if (!(opts & OPENSSL_INIT_BASE_ONLY))
566             CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
567         return 0;
568     }
569
570     if (!RUN_ONCE(&base, ossl_init_base))
571         return 0;
572
573     if (!(opts & OPENSSL_INIT_BASE_ONLY)
574             && !RUN_ONCE(&load_crypto_nodelete,
575                          ossl_init_load_crypto_nodelete))
576         return 0;
577
578     if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
579             && !RUN_ONCE(&load_crypto_strings,
580                          ossl_init_no_load_crypto_strings))
581         return 0;
582
583     if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
584             && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
585         return 0;
586
587     if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
588             && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
589         return 0;
590
591     if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
592             && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
593         return 0;
594
595     if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
596             && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
597         return 0;
598
599     if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
600             && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
601         return 0;
602
603     if ((opts & OPENSSL_INIT_ATFORK)
604             && !openssl_init_fork_handlers())
605         return 0;
606
607     if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
608             && !RUN_ONCE(&config, ossl_init_no_config))
609         return 0;
610
611     if (opts & OPENSSL_INIT_LOAD_CONFIG) {
612         int ret;
613         CRYPTO_THREAD_write_lock(init_lock);
614         appname = (settings == NULL) ? NULL : settings->appname;
615         ret = RUN_ONCE(&config, ossl_init_config);
616         CRYPTO_THREAD_unlock(init_lock);
617         if (!ret)
618             return 0;
619     }
620
621     if ((opts & OPENSSL_INIT_ASYNC)
622             && !RUN_ONCE(&async, ossl_init_async))
623         return 0;
624
625 #ifndef OPENSSL_NO_ENGINE
626     if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
627             && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
628         return 0;
629 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
630     if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
631             && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
632         return 0;
633 # endif
634 # ifndef OPENSSL_NO_RDRAND
635     if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
636             && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
637         return 0;
638 # endif
639     if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
640             && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
641         return 0;
642 # ifndef OPENSSL_NO_STATIC_ENGINE
643 #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
644     if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
645             && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
646         return 0;
647 #  endif
648 #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
649     if ((opts & OPENSSL_INIT_ENGINE_CAPI)
650             && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
651         return 0;
652 #  endif
653 #  if !defined(OPENSSL_NO_AFALGENG)
654     if ((opts & OPENSSL_INIT_ENGINE_AFALG)
655             && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
656         return 0;
657 #  endif
658 # endif
659     if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
660                 | OPENSSL_INIT_ENGINE_OPENSSL
661                 | OPENSSL_INIT_ENGINE_AFALG)) {
662         ENGINE_register_all_complete();
663     }
664 #endif
665
666 #ifndef OPENSSL_NO_COMP
667     if ((opts & OPENSSL_INIT_ZLIB)
668             && !RUN_ONCE(&zlib, ossl_init_zlib))
669         return 0;
670 #endif
671
672     return 1;
673 }
674
675 int OPENSSL_atexit(void (*handler)(void))
676 {
677     OPENSSL_INIT_STOP *newhand;
678
679 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
680     {
681         union {
682             void *sym;
683             void (*func)(void);
684         } handlersym;
685
686         handlersym.func = handler;
687 # ifdef DSO_WIN32
688         {
689             HMODULE handle = NULL;
690             BOOL ret;
691
692             /*
693              * We don't use the DSO route for WIN32 because there is a better
694              * way
695              */
696             ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
697                                     | GET_MODULE_HANDLE_EX_FLAG_PIN,
698                                     handlersym.sym, &handle);
699
700             if (!ret)
701                 return 0;
702         }
703 # else
704         /*
705          * Deliberately leak a reference to the handler. This will force the
706          * library/code containing the handler to remain loaded until we run the
707          * atexit handler. If -znodelete has been used then this is
708          * unnecessary.
709          */
710         {
711             DSO *dso = NULL;
712
713             ERR_set_mark();
714             dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
715 #  ifdef OPENSSL_INIT_DEBUG
716             fprintf(stderr,
717                     "OPENSSL_INIT: OPENSSL_atexit: obtained DSO reference? %s\n",
718                     (dso == NULL ? "No!" : "Yes."));
719             /* See same code above in ossl_init_base() for an explanation. */
720 #  endif
721             DSO_free(dso);
722             ERR_pop_to_mark();
723         }
724 # endif
725     }
726 #endif
727
728     if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) {
729         CRYPTOerr(CRYPTO_F_OPENSSL_ATEXIT, ERR_R_MALLOC_FAILURE);
730         return 0;
731     }
732
733     newhand->handler = handler;
734     newhand->next = stop_handlers;
735     stop_handlers = newhand;
736
737     return 1;
738 }
739
740 #ifdef OPENSSL_SYS_UNIX
741 /*
742  * The following three functions are for OpenSSL developers.  This is
743  * where we set/reset state across fork (called via pthread_atfork when
744  * it exists, or manually by the application when it doesn't).
745  *
746  * WARNING!  If you put code in either OPENSSL_fork_parent or
747  * OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal-
748  * safe.  See this link, for example:
749  *      http://man7.org/linux/man-pages/man7/signal-safety.7.html
750  */
751
752 void OPENSSL_fork_prepare(void)
753 {
754 }
755
756 void OPENSSL_fork_parent(void)
757 {
758 }
759
760 void OPENSSL_fork_child(void)
761 {
762     rand_fork();
763 }
764 #endif