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