2 * Written by Matt Caswell for the OpenSSL project.
4 /* ====================================================================
5 * Copyright (c) 2016 The OpenSSL Project. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * openssl-core@openssl.org.
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
33 * 6. Redistributions of any form whatsoever must retain the following
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
58 #include <openssl/e_os2.h>
60 #if defined(OPENSSL_SYS_WINDOWS) && !defined(_WIN32_WINNT)
62 * We default to requiring Windows Vista, Windows Server 2008 or later. We can
63 * support lower versions if _WIN32_WINNT is explicity defined to something
66 # define _WIN32_WINNT 0x0600
69 #include <internal/cryptlib_int.h>
70 #include <openssl/err.h>
71 #include <openssl/evp.h>
72 #include <internal/evp_int.h>
73 #include <internal/conf.h>
74 #include <internal/async.h>
75 #include <internal/engine.h>
76 #include <openssl/comp.h>
77 #include <internal/err.h>
80 /* Implement "once" functionality */
81 #if !defined(OPENSSL_THREADS)
82 typedef int OPENSSL_INIT_ONCE;
83 # define OPENSSL_INIT_ONCE_STATIC_INIT 0
84 # define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = 0)
86 static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
88 if (*once == OPENSSL_INIT_ONCE_STATIC_INIT) {
94 static int ossl_init_setup_thread_stop(void)
97 * There are no threads to stop. Do nothing.
102 static void ossl_init_thread_stop_cleanup(void)
106 static struct thread_local_inits_st *local = NULL;
107 void *ossl_init_get_thread_local(int alloc)
109 if (local == NULL && alloc)
110 local = OPENSSL_zalloc(sizeof(*local));
114 #elif defined(OPENSSL_SYS_WINDOWS)
116 # include <windows.h>
118 # if _WIN32_WINNT < 0x0600
121 * Versions before 0x0600 (Windows Vista, Windows Server 2008 or later) do not
122 * have InitOnceExecuteOnce, so we fall back to using a spinlock instead.
124 typedef LONG OPENSSL_INIT_ONCE;
125 # define OPENSSL_INIT_ONCE_STATIC_INIT 0
126 # define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = 0)
128 # define ONCE_UNINITED 0
129 # define ONCE_ININIT 1
132 static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
134 LONG volatile *lock = (LONG *)once;
137 if (*lock == ONCE_DONE)
141 result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
142 if (result == ONCE_UNINITED) {
147 } while (result == ONCE_ININIT);
152 typedef INIT_ONCE OPENSSL_INIT_ONCE;
153 # define OPENSSL_INIT_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
154 # define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) \
155 InitOnceInitialize((PINIT_ONCE)(once))
157 static BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID initfp, PVOID *unused)
159 void (*init)(void) = initfp;
166 static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
168 InitOnceExecuteOnce((INIT_ONCE *)once, once_cb, init, NULL);
172 DWORD threadstopkey = TLS_OUT_OF_INDEXES;
174 static int ossl_init_setup_thread_stop(void)
177 * We use a dummy thread local key here. We use the destructor to detect
178 * when the thread is going to stop
180 threadstopkey = TlsAlloc();
181 if (threadstopkey == TLS_OUT_OF_INDEXES)
187 static void ossl_init_thread_stop_cleanup(void)
189 if (threadstopkey != TLS_OUT_OF_INDEXES) {
190 TlsFree(threadstopkey);
194 void *ossl_init_get_thread_local(int alloc)
196 struct thread_local_inits_st *local = TlsGetValue(threadstopkey);
198 if (local == NULL && alloc) {
199 local = OPENSSL_zalloc(sizeof *local);
200 TlsSetValue(threadstopkey, local);
207 # include <pthread.h>
209 pthread_key_t threadstopkey;
211 typedef pthread_once_t OPENSSL_INIT_ONCE;
212 # define OPENSSL_INIT_ONCE_STATIC_INIT PTHREAD_ONCE_INIT
213 # define OPENSSL_INIT_ONCE_DYNAMIC_INIT(once) (*(once) = PTHREAD_ONCE_INIT)
215 static void ossl_init_once_run(OPENSSL_INIT_ONCE *once, void (*init)(void))
217 pthread_once(once, init);
220 static void ossl_init_thread_stop_wrap(void *local)
222 ossl_init_thread_stop((struct thread_local_inits_st *)local);
225 static int ossl_init_setup_thread_stop(void)
228 * We use a dummy thread local key here. We use the destructor to detect
229 * when the thread is going to stop
231 return (pthread_key_create(&threadstopkey,
232 ossl_init_thread_stop_wrap) == 0);
235 static void ossl_init_thread_stop_cleanup(void)
239 void *ossl_init_get_thread_local(int alloc)
241 struct thread_local_inits_st *local = pthread_getspecific(threadstopkey);
243 if (local == NULL && alloc) {
244 local = OPENSSL_zalloc(sizeof *local);
245 pthread_setspecific(threadstopkey, local);
253 struct ossl_init_stop_st {
254 void (*handler)(void);
255 OPENSSL_INIT_STOP *next;
258 static OPENSSL_INIT_STOP *stop_handlers = NULL;
260 static OPENSSL_INIT_ONCE base = OPENSSL_INIT_ONCE_STATIC_INIT;
261 static int base_inited = 0;
262 static void ossl_init_base(void)
264 #ifdef OPENSSL_INIT_DEBUG
265 fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
267 ossl_init_setup_thread_stop();
268 atexit(OPENSSL_INIT_library_stop);
269 OPENSSL_cpuid_setup();
273 static OPENSSL_INIT_ONCE load_crypto_strings = OPENSSL_INIT_ONCE_STATIC_INIT;
274 static int load_crypto_strings_inited = 0;
275 static void ossl_init_no_load_crypto_strings(void)
277 /* Do nothing in this case */
281 static void ossl_init_load_crypto_strings(void)
283 #ifndef OPENSSL_NO_ERR
284 # ifdef OPENSSL_INIT_DEBUG
285 fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
286 "err_load_crypto_strings_intern()\n");
288 err_load_crypto_strings_intern();
290 load_crypto_strings_inited = 1;
293 static OPENSSL_INIT_ONCE add_all_ciphers = OPENSSL_INIT_ONCE_STATIC_INIT;
294 static void ossl_init_add_all_ciphers(void)
297 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
298 * pulling in all the ciphers during static linking
300 #ifndef OPENSSL_NO_AUTOALGINIT
301 # ifdef OPENSSL_INIT_DEBUG
302 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
303 "openssl_add_all_ciphers_internal()\n");
305 openssl_add_all_ciphers_internal();
306 # ifndef OPENSSL_NO_ENGINE
307 # if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
308 ENGINE_setup_bsd_cryptodev();
314 static OPENSSL_INIT_ONCE add_all_digests = OPENSSL_INIT_ONCE_STATIC_INIT;
315 static void ossl_init_add_all_digests(void)
318 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
319 * pulling in all the ciphers during static linking
321 #ifndef OPENSSL_NO_AUTOALGINIT
322 # ifdef OPENSSL_INIT_DEBUG
323 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
324 "openssl_add_all_digests_internal()\n");
326 openssl_add_all_digests_internal();
327 # ifndef OPENSSL_NO_ENGINE
328 # if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
329 ENGINE_setup_bsd_cryptodev();
335 static void ossl_init_no_add_algs(void)
341 static OPENSSL_INIT_ONCE config = OPENSSL_INIT_ONCE_STATIC_INIT;
342 static int config_inited = 0;
343 static const char *config_filename;
344 static void ossl_init_config(void)
346 #ifdef OPENSSL_INIT_DEBUG
348 "OPENSSL_INIT: ossl_init_config: openssl_config_internal(%s)\n",
349 config_filename==NULL?"NULL":config_filename);
351 openssl_config_internal(config_filename);
354 static void ossl_init_no_config(void)
356 #ifdef OPENSSL_INIT_DEBUG
358 "OPENSSL_INIT: ossl_init_config: openssl_no_config_internal()\n");
360 openssl_no_config_internal();
364 static OPENSSL_INIT_ONCE async = OPENSSL_INIT_ONCE_STATIC_INIT;
365 static int async_inited = 0;
366 static void ossl_init_async(void)
368 #ifdef OPENSSL_INIT_DEBUG
369 fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
375 #ifndef OPENSSL_NO_ENGINE
376 static int engine_inited = 0;
377 static OPENSSL_INIT_ONCE engine_openssl = OPENSSL_INIT_ONCE_STATIC_INIT;
378 static void ossl_init_engine_openssl(void)
380 # ifdef OPENSSL_INIT_DEBUG
381 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
382 "engine_load_openssl_internal()\n");
384 engine_load_openssl_internal();
387 # if !defined(OPENSSL_NO_HW) && \
388 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
389 static OPENSSL_INIT_ONCE engine_cryptodev = OPENSSL_INIT_ONCE_STATIC_INIT;
390 static void ossl_init_engine_cryptodev(void)
392 # ifdef OPENSSL_INIT_DEBUG
393 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: "
394 "engine_load_cryptodev_internal()\n");
396 engine_load_cryptodev_internal();
401 # ifndef OPENSSL_NO_RDRAND
402 static OPENSSL_INIT_ONCE engine_rdrand = OPENSSL_INIT_ONCE_STATIC_INIT;
403 static void ossl_init_engine_rdrand(void)
405 # ifdef OPENSSL_INIT_DEBUG
406 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
407 "engine_load_rdrand_internal()\n");
409 engine_load_rdrand_internal();
413 static OPENSSL_INIT_ONCE engine_dynamic = OPENSSL_INIT_ONCE_STATIC_INIT;
414 static void ossl_init_engine_dynamic(void)
416 # ifdef OPENSSL_INIT_DEBUG
417 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
418 "engine_load_dynamic_internal()\n");
420 engine_load_dynamic_internal();
423 # ifndef OPENSSL_NO_STATIC_ENGINE
424 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
425 static OPENSSL_INIT_ONCE engine_padlock = OPENSSL_INIT_ONCE_STATIC_INIT;
426 static void ossl_init_engine_padlock(void)
428 # ifdef OPENSSL_INIT_DEBUG
429 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
430 "engine_load_padlock_internal()\n");
432 engine_load_padlock_internal();
436 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
437 static OPENSSL_INIT_ONCE engine_capi = OPENSSL_INIT_ONCE_STATIC_INIT;
438 static void ossl_init_engine_capi(void)
440 # ifdef OPENSSL_INIT_DEBUG
441 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
442 "engine_load_capi_internal()\n");
444 engine_load_capi_internal();
448 static OPENSSL_INIT_ONCE engine_dasync = OPENSSL_INIT_ONCE_STATIC_INIT;
449 static void ossl_init_engine_dasync(void)
451 # ifdef OPENSSL_INIT_DEBUG
452 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dasync: "
453 "engine_load_dasync_internal()\n");
455 engine_load_dasync_internal();
461 static OPENSSL_INIT_ONCE zlib = OPENSSL_INIT_ONCE_STATIC_INIT;
462 static int zlib_inited = 0;
463 static void ossl_init_zlib(void)
465 /* Do nothing - we need to know about this for the later cleanup */
469 void ossl_init_thread_stop(struct thread_local_inits_st *locals)
471 /* Can't do much about this */
476 #ifdef OPENSSL_INIT_DEBUG
477 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
478 "ASYNC_cleanup_thread()\n");
480 ASYNC_cleanup_thread();
483 if (locals->err_state) {
484 #ifdef OPENSSL_INIT_DEBUG
485 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
486 "ERR_remove_thread_state(NULL)\n");
488 ERR_remove_thread_state(NULL);
491 OPENSSL_free(locals);
492 ossl_init_thread_stop_cleanup();
495 int ossl_init_thread_start(uint64_t opts)
497 struct thread_local_inits_st *locals = ossl_init_get_thread_local(1);
502 if (opts & OPENSSL_INIT_THREAD_ASYNC) {
503 #ifdef OPENSSL_INIT_DEBUG
504 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
505 "marking thread for async\n");
510 if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
511 #ifdef OPENSSL_INIT_DEBUG
512 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
513 "marking thread for err_state\n");
515 locals->err_state = 1;
521 void OPENSSL_INIT_library_stop(void)
523 OPENSSL_INIT_STOP *currhandler, *lasthandler;
526 * Thread stop may not get automatically called by the thread library for
527 * the very last thread in some situations, so call it directly.
529 ossl_init_thread_stop(ossl_init_get_thread_local(0));
531 currhandler = stop_handlers;
532 while (currhandler != NULL) {
533 currhandler->handler();
534 lasthandler = currhandler;
535 currhandler = currhandler->next;
536 OPENSSL_free(lasthandler);
538 stop_handlers = NULL;
540 * We assume we are single-threaded for this function, i.e. no race
541 * conditions for the various "*_inited" vars below.
545 #ifdef OPENSSL_INIT_DEBUG
546 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
547 "COMP_zlib_cleanup()\n");
551 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&zlib);
554 #ifndef OPENSSL_NO_ENGINE
556 # ifdef OPENSSL_INIT_DEBUG
557 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
558 "ENGINE_cleanup()\n");
562 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_openssl);
563 # if !defined(OPENSSL_NO_HW) && \
564 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
565 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_cryptodev);
567 # ifndef OPENSSL_NO_RDRAND
568 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_rdrand);
570 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_dynamic);
571 # ifndef OPENSSL_NO_STATIC_ENGINE
572 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
573 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_padlock);
575 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
576 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_capi);
578 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&engine_dasync);
584 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&async);
587 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&config);
588 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&add_all_ciphers);
589 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&add_all_digests);
591 if (load_crypto_strings_inited) {
592 #ifdef OPENSSL_INIT_DEBUG
593 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
594 "ERR_free_strings()\n");
597 load_crypto_strings_inited = 0;
598 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&load_crypto_strings);
602 #ifdef OPENSSL_INIT_DEBUG
603 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
604 "CRYPTO_cleanup_all_ex_data()\n");
605 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
607 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
608 "CONF_modules_free()\n");
609 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
612 CRYPTO_cleanup_all_ex_data();
617 OPENSSL_INIT_ONCE_DYNAMIC_INIT(&base);
621 static const OPENSSL_INIT_SETTINGS *ossl_init_get_setting(
622 const OPENSSL_INIT_SETTINGS *settings, int name)
624 if (settings == NULL)
627 while (settings->name != OPENSSL_INIT_SET_END) {
628 if (settings->name == name)
637 * If this function is called with a non NULL settings value then it must be
638 * called prior to any threads making calls to any OpenSSL functions,
639 * i.e. passing a non-null settings value is assumed to be single-threaded.
641 void OPENSSL_INIT_crypto_library_start(uint64_t opts,
642 const OPENSSL_INIT_SETTINGS *settings)
644 ossl_init_once_run(&base, ossl_init_base);
646 if (opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
647 ossl_init_once_run(&load_crypto_strings,
648 ossl_init_no_load_crypto_strings);
650 if (opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
651 ossl_init_once_run(&load_crypto_strings, ossl_init_load_crypto_strings);
653 if (opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
654 ossl_init_once_run(&add_all_ciphers, ossl_init_no_add_algs);
656 if (opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
657 ossl_init_once_run(&add_all_ciphers, ossl_init_add_all_ciphers);
659 if (opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
660 ossl_init_once_run(&add_all_digests, ossl_init_no_add_algs);
662 if (opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
663 ossl_init_once_run(&add_all_digests, ossl_init_add_all_digests);
665 if (opts & OPENSSL_INIT_NO_LOAD_CONFIG) {
666 ossl_init_once_run(&config, ossl_init_no_config);
669 if (opts & OPENSSL_INIT_LOAD_CONFIG) {
670 if (settings != NULL) {
671 const OPENSSL_INIT_SETTINGS *curr;
672 curr = ossl_init_get_setting(settings,
673 OPENSSL_INIT_SET_CONF_FILENAME);
674 config_filename = curr == NULL ? NULL : curr->value.type_string;
676 ossl_init_once_run(&config, ossl_init_config);
679 if (opts & OPENSSL_INIT_ASYNC) {
680 ossl_init_once_run(&async, ossl_init_async);
683 #ifndef OPENSSL_NO_ENGINE
684 if (opts & OPENSSL_INIT_ENGINE_OPENSSL) {
685 ossl_init_once_run(&engine_openssl, ossl_init_engine_openssl);
687 # if !defined(OPENSSL_NO_HW) && \
688 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
689 if (opts & OPENSSL_INIT_ENGINE_CRYPTODEV) {
690 ossl_init_once_run(&engine_cryptodev, ossl_init_engine_cryptodev);
693 # ifndef OPENSSL_NO_RDRAND
694 if (opts & OPENSSL_INIT_ENGINE_RDRAND) {
695 ossl_init_once_run(&engine_rdrand, ossl_init_engine_rdrand);
698 if (opts & OPENSSL_INIT_ENGINE_DYNAMIC) {
699 ossl_init_once_run(&engine_dynamic, ossl_init_engine_dynamic);
701 # ifndef OPENSSL_NO_STATIC_ENGINE
702 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
703 if (opts & OPENSSL_INIT_ENGINE_PADLOCK) {
704 ossl_init_once_run(&engine_padlock, ossl_init_engine_padlock);
707 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
708 if (opts & OPENSSL_INIT_ENGINE_CAPI) {
709 ossl_init_once_run(&engine_capi, ossl_init_engine_capi);
712 if (opts & OPENSSL_INIT_ENGINE_DASYNC) {
713 ossl_init_once_run(&engine_dasync, ossl_init_engine_dasync);
716 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
717 | OPENSSL_INIT_ENGINE_DASYNC | OPENSSL_INIT_ENGINE_OPENSSL)) {
718 ENGINE_register_all_complete();
722 if (opts & OPENSSL_INIT_ZLIB) {
723 ossl_init_once_run(&zlib, ossl_init_zlib);
727 int OPENSSL_INIT_register_stop_handler(void (*handler)(void))
729 OPENSSL_INIT_STOP *newhand;
731 newhand = OPENSSL_malloc(sizeof(*newhand));
735 newhand->handler = handler;
736 newhand->next = stop_handlers;
737 stop_handlers = newhand;