blob: 1cac74193fc431eb822010a3c85457a4277c3a5d [file] [log] [blame]
Matt Caswellb184e3e2016-02-09 11:26:14 +00001/*
2 * Written by Matt Caswell for the OpenSSL project.
3 */
4/* ====================================================================
5 * Copyright (c) 2016 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
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
17 * distribution.
18 *
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/)"
23 *
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.
28 *
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.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37 *
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 * ====================================================================
51 *
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).
55 *
56 */
57
Matt Caswellb1f1e7a2016-03-02 14:51:00 +000058#include <internal/threads.h>
Matt Caswellb184e3e2016-02-09 11:26:14 +000059#include <internal/cryptlib_int.h>
60#include <openssl/err.h>
Viktor Dukhovni31305cd2016-02-14 15:25:54 -050061#include <openssl/rand.h>
Matt Caswellb184e3e2016-02-09 11:26:14 +000062#include <openssl/evp.h>
Matt Caswellb184e3e2016-02-09 11:26:14 +000063#include <internal/evp_int.h>
64#include <internal/conf.h>
65#include <internal/async.h>
Rich Salz1288f262016-02-17 13:33:51 -050066#ifndef OPENSSL_NO_ENGINE
Matt Caswellb184e3e2016-02-09 11:26:14 +000067#include <internal/engine.h>
Rich Salz1288f262016-02-17 13:33:51 -050068#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +000069#include <openssl/comp.h>
Matt Caswellb184e3e2016-02-09 11:26:14 +000070#include <internal/err.h>
Matt Caswellb184e3e2016-02-09 11:26:14 +000071#include <stdlib.h>
Rich Salzdd27f162016-02-10 00:39:29 -050072#include <assert.h>
73
74static int stopped = 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +000075
Matt Caswell71567a62016-02-09 09:13:45 +000076static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
77
Matt Caswella072ed02016-03-02 15:23:57 +000078static CRYPTO_THREAD_LOCAL threadstopkey;
Matt Caswellb184e3e2016-02-09 11:26:14 +000079
Matt Caswellb184e3e2016-02-09 11:26:14 +000080static void ossl_init_thread_stop_wrap(void *local)
81{
82 ossl_init_thread_stop((struct thread_local_inits_st *)local);
83}
84
Matt Caswellb7326ea2016-02-09 23:09:44 +000085static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
Matt Caswellb184e3e2016-02-09 11:26:14 +000086{
Matt Caswella072ed02016-03-02 15:23:57 +000087 struct thread_local_inits_st *local =
88 CRYPTO_THREAD_get_local(&threadstopkey);
Matt Caswellb184e3e2016-02-09 11:26:14 +000089
90 if (local == NULL && alloc) {
91 local = OPENSSL_zalloc(sizeof *local);
Matt Caswella072ed02016-03-02 15:23:57 +000092 CRYPTO_THREAD_set_local(&threadstopkey, local);
Matt Caswellb184e3e2016-02-09 11:26:14 +000093 }
Matt Caswellb7326ea2016-02-09 23:09:44 +000094 if (!alloc) {
Matt Caswella072ed02016-03-02 15:23:57 +000095 CRYPTO_THREAD_set_local(&threadstopkey, NULL);
Matt Caswellb7326ea2016-02-09 23:09:44 +000096 }
Matt Caswellb184e3e2016-02-09 11:26:14 +000097
98 return local;
99}
100
Rich Salz7253fd52016-02-10 09:55:48 -0500101typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000102struct ossl_init_stop_st {
103 void (*handler)(void);
104 OPENSSL_INIT_STOP *next;
105};
106
107static OPENSSL_INIT_STOP *stop_handlers = NULL;
Matt Caswellc292b102016-03-07 14:39:22 +0000108static CRYPTO_RWLOCK *init_lock = NULL;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000109
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000110static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000111static int base_inited = 0;
112static void ossl_init_base(void)
113{
114#ifdef OPENSSL_INIT_DEBUG
115 fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
116#endif
Matt Caswella072ed02016-03-02 15:23:57 +0000117 /*
118 * We use a dummy thread local key here. We use the destructor to detect
119 * when the thread is going to stop (where that feature is available)
120 */
121 CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
David Woodhousec7b79382016-02-17 14:54:33 +0000122#ifndef OPENSSL_SYS_UEFI
Rich Salzf672aee2016-02-09 11:52:40 -0500123 atexit(OPENSSL_cleanup);
David Woodhousec7b79382016-02-17 14:54:33 +0000124#endif
Matt Caswellc292b102016-03-07 14:39:22 +0000125 init_lock = CRYPTO_THREAD_lock_new();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000126 OPENSSL_cpuid_setup();
127 base_inited = 1;
128}
129
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000130static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000131static int load_crypto_strings_inited = 0;
132static void ossl_init_no_load_crypto_strings(void)
133{
134 /* Do nothing in this case */
135 return;
136}
137
138static void ossl_init_load_crypto_strings(void)
139{
Matt Caswell498abff2016-02-09 09:39:07 +0000140 /*
141 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
142 * pulling in all the error strings during static linking
143 */
144#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
Matt Caswellb184e3e2016-02-09 11:26:14 +0000145# ifdef OPENSSL_INIT_DEBUG
146 fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
147 "err_load_crypto_strings_intern()\n");
148# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000149 err_load_crypto_strings_intern();
150#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000151 load_crypto_strings_inited = 1;
152}
153
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000154static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000155static void ossl_init_add_all_ciphers(void)
156{
157 /*
158 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
159 * pulling in all the ciphers during static linking
160 */
161#ifndef OPENSSL_NO_AUTOALGINIT
162# ifdef OPENSSL_INIT_DEBUG
163 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
164 "openssl_add_all_ciphers_internal()\n");
165# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000166 openssl_add_all_ciphers_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000167# ifndef OPENSSL_NO_ENGINE
168# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
169 ENGINE_setup_bsd_cryptodev();
170# endif
171# endif
172#endif
173}
174
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000175static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000176static void ossl_init_add_all_digests(void)
177{
178 /*
179 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
180 * pulling in all the ciphers during static linking
181 */
182#ifndef OPENSSL_NO_AUTOALGINIT
183# ifdef OPENSSL_INIT_DEBUG
184 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
185 "openssl_add_all_digests_internal()\n");
186# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000187 openssl_add_all_digests_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000188# ifndef OPENSSL_NO_ENGINE
189# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
190 ENGINE_setup_bsd_cryptodev();
191# endif
192# endif
193#endif
194}
195
196static void ossl_init_no_add_algs(void)
197{
198 /* Do nothing */
199 return;
200}
201
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000202static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000203static int config_inited = 0;
204static const char *config_filename;
205static void ossl_init_config(void)
206{
207#ifdef OPENSSL_INIT_DEBUG
208 fprintf(stderr,
209 "OPENSSL_INIT: ossl_init_config: openssl_config_internal(%s)\n",
210 config_filename==NULL?"NULL":config_filename);
211#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000212 openssl_config_internal(config_filename);
Matt Caswellb184e3e2016-02-09 11:26:14 +0000213 config_inited = 1;
214}
215static void ossl_init_no_config(void)
216{
217#ifdef OPENSSL_INIT_DEBUG
218 fprintf(stderr,
219 "OPENSSL_INIT: ossl_init_config: openssl_no_config_internal()\n");
220#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000221 openssl_no_config_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000222 config_inited = 1;
223}
224
Rich Salz1288f262016-02-17 13:33:51 -0500225#ifndef OPENSSL_NO_ASYNC
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000226static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000227static int async_inited = 0;
228static void ossl_init_async(void)
229{
230#ifdef OPENSSL_INIT_DEBUG
231 fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
232#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000233 async_init();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000234 async_inited = 1;
235}
Rich Salz1288f262016-02-17 13:33:51 -0500236#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000237
238#ifndef OPENSSL_NO_ENGINE
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000239static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000240static void ossl_init_engine_openssl(void)
241{
242# ifdef OPENSSL_INIT_DEBUG
243 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
244 "engine_load_openssl_internal()\n");
245# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000246 engine_load_openssl_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000247}
248# if !defined(OPENSSL_NO_HW) && \
249 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000250static CRYPTO_ONCE engine_cryptodev = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000251static void ossl_init_engine_cryptodev(void)
252{
253# ifdef OPENSSL_INIT_DEBUG
254 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: "
255 "engine_load_cryptodev_internal()\n");
256# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000257 engine_load_cryptodev_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000258}
259# endif
260
261# ifndef OPENSSL_NO_RDRAND
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000262static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000263static void ossl_init_engine_rdrand(void)
264{
265# ifdef OPENSSL_INIT_DEBUG
266 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
267 "engine_load_rdrand_internal()\n");
268# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000269 engine_load_rdrand_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000270}
271# endif
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000272static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000273static void ossl_init_engine_dynamic(void)
274{
275# ifdef OPENSSL_INIT_DEBUG
276 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
277 "engine_load_dynamic_internal()\n");
278# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000279 engine_load_dynamic_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000280}
281# ifndef OPENSSL_NO_STATIC_ENGINE
282# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000283static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000284static void ossl_init_engine_padlock(void)
285{
286# ifdef OPENSSL_INIT_DEBUG
287 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
288 "engine_load_padlock_internal()\n");
289# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000290 engine_load_padlock_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000291}
292# endif
293# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000294static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000295static void ossl_init_engine_capi(void)
296{
297# ifdef OPENSSL_INIT_DEBUG
298 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
299 "engine_load_capi_internal()\n");
300# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000301 engine_load_capi_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000302}
303# endif
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000304static CRYPTO_ONCE engine_dasync = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000305static void ossl_init_engine_dasync(void)
306{
307# ifdef OPENSSL_INIT_DEBUG
308 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dasync: "
309 "engine_load_dasync_internal()\n");
310# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000311 engine_load_dasync_internal();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000312}
clucey6cba4a62016-02-23 08:01:01 +0000313# if !defined(OPENSSL_NO_AFALGENG)
314static OPENSSL_INIT_ONCE engine_afalg = OPENSSL_INIT_ONCE_STATIC_INIT;
315static void ossl_init_engine_afalg(void)
316{
317# ifdef OPENSSL_INIT_DEBUG
318 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
319 "engine_load_afalg_internal()\n");
320# endif
321 engine_load_afalg_internal();
clucey6cba4a62016-02-23 08:01:01 +0000322}
323# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000324# endif
325#endif
326
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000327static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000328static int zlib_inited = 0;
329static void ossl_init_zlib(void)
330{
331 /* Do nothing - we need to know about this for the later cleanup */
332 zlib_inited = 1;
333}
334
Matt Caswell71567a62016-02-09 09:13:45 +0000335static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
Matt Caswellb184e3e2016-02-09 11:26:14 +0000336{
337 /* Can't do much about this */
338 if (locals == NULL)
339 return;
340
Rich Salz1288f262016-02-17 13:33:51 -0500341#ifndef OPENSSL_NO_ASYNC
Matt Caswellb184e3e2016-02-09 11:26:14 +0000342 if (locals->async) {
343#ifdef OPENSSL_INIT_DEBUG
344 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
345 "ASYNC_cleanup_thread()\n");
346#endif
347 ASYNC_cleanup_thread();
348 }
Rich Salz1288f262016-02-17 13:33:51 -0500349#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000350
351 if (locals->err_state) {
352#ifdef OPENSSL_INIT_DEBUG
353 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
Alessandro Ghedini8509dcc2016-03-02 17:36:17 +0000354 "ERR_remove_thread_state()\n");
Matt Caswellb184e3e2016-02-09 11:26:14 +0000355#endif
Alessandro Ghedini8509dcc2016-03-02 17:36:17 +0000356 ERR_remove_thread_state();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000357 }
358
359 OPENSSL_free(locals);
Matt Caswellb184e3e2016-02-09 11:26:14 +0000360}
361
Rich Salzf672aee2016-02-09 11:52:40 -0500362void OPENSSL_thread_stop(void)
Matt Caswell71567a62016-02-09 09:13:45 +0000363{
364 ossl_init_thread_stop(
365 (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
366}
367
Matt Caswellb184e3e2016-02-09 11:26:14 +0000368int ossl_init_thread_start(uint64_t opts)
369{
370 struct thread_local_inits_st *locals = ossl_init_get_thread_local(1);
371
372 if (locals == NULL)
373 return 0;
374
375 if (opts & OPENSSL_INIT_THREAD_ASYNC) {
376#ifdef OPENSSL_INIT_DEBUG
377 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
378 "marking thread for async\n");
379#endif
380 locals->async = 1;
381 }
382
383 if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
384#ifdef OPENSSL_INIT_DEBUG
385 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
386 "marking thread for err_state\n");
387#endif
388 locals->err_state = 1;
389 }
390
391 return 1;
392}
393
Rich Salzf672aee2016-02-09 11:52:40 -0500394void OPENSSL_cleanup(void)
Matt Caswellb184e3e2016-02-09 11:26:14 +0000395{
396 OPENSSL_INIT_STOP *currhandler, *lasthandler;
397
Matt Caswelldeca5df2016-02-10 09:47:51 +0000398 /* If we've not been inited then no need to deinit */
399 if (!base_inited)
400 return;
401
Rich Salzdd27f162016-02-10 00:39:29 -0500402 /* Might be explicitly called and also by atexit */
403 if (stopped)
404 return;
405 stopped = 1;
406
Matt Caswellb184e3e2016-02-09 11:26:14 +0000407 /*
408 * Thread stop may not get automatically called by the thread library for
409 * the very last thread in some situations, so call it directly.
410 */
411 ossl_init_thread_stop(ossl_init_get_thread_local(0));
412
413 currhandler = stop_handlers;
414 while (currhandler != NULL) {
415 currhandler->handler();
416 lasthandler = currhandler;
417 currhandler = currhandler->next;
418 OPENSSL_free(lasthandler);
419 }
420 stop_handlers = NULL;
Matt Caswellc292b102016-03-07 14:39:22 +0000421
422 CRYPTO_THREAD_lock_free(init_lock);
423
Matt Caswellb184e3e2016-02-09 11:26:14 +0000424 /*
425 * We assume we are single-threaded for this function, i.e. no race
426 * conditions for the various "*_inited" vars below.
427 */
428
429 if (zlib_inited) {
430#ifdef OPENSSL_INIT_DEBUG
Rich Salzf672aee2016-02-09 11:52:40 -0500431 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
Matt Caswellb184e3e2016-02-09 11:26:14 +0000432 "COMP_zlib_cleanup()\n");
433#endif
434 COMP_zlib_cleanup();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000435 }
436
Matt Caswelled49f432016-03-02 16:52:43 +0000437#ifndef OPENSSL_NO_ASYNC
438 if (async_inited) {
439# ifdef OPENSSL_INIT_DEBUG
440 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
441 "async_deinit()\n");
442# endif
443 async_deinit();
444 }
445#endif
446
Matt Caswellb184e3e2016-02-09 11:26:14 +0000447 if (load_crypto_strings_inited) {
448#ifdef OPENSSL_INIT_DEBUG
Rich Salzf672aee2016-02-09 11:52:40 -0500449 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
Matt Caswellb184e3e2016-02-09 11:26:14 +0000450 "ERR_free_strings()\n");
451#endif
452 ERR_free_strings();
Matt Caswellb184e3e2016-02-09 11:26:14 +0000453 }
454
Matt Caswella072ed02016-03-02 15:23:57 +0000455 CRYPTO_THREAD_cleanup_local(&threadstopkey);
Matt Caswell6bc7bad2016-02-18 12:24:09 +0000456
Matt Caswellb184e3e2016-02-09 11:26:14 +0000457#ifdef OPENSSL_INIT_DEBUG
Richard Levitte9749a072016-03-09 12:52:50 +0100458#ifndef OPENSSL_NO_ENGINE
Matt Caswellae6412f2016-03-09 00:53:38 +0000459 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
460 "ENGINE_cleanup()\n");
Richard Levitte9749a072016-03-09 12:52:50 +0100461#endif
Matt Caswelldeca5df2016-02-10 09:47:51 +0000462 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
463 "CRYPTO_cleanup_all_ex_data()\n");
464 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
465 "EVP_cleanup()\n");
466 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
467 "CONF_modules_free()\n");
468 fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
469 "RAND_cleanup()\n");
Matt Caswellae6412f2016-03-09 00:53:38 +0000470
Matt Caswellb184e3e2016-02-09 11:26:14 +0000471#endif
Richard Levitte9749a072016-03-09 12:52:50 +0100472#ifndef OPENSSL_NO_ENGINE
Matt Caswellae6412f2016-03-09 00:53:38 +0000473 ENGINE_cleanup();
Richard Levitte9749a072016-03-09 12:52:50 +0100474#endif
Matt Caswelldeca5df2016-02-10 09:47:51 +0000475 CRYPTO_cleanup_all_ex_data();
476 EVP_cleanup();
477 CONF_modules_free();
478 RAND_cleanup();
479 base_inited = 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000480}
481
Matt Caswellb184e3e2016-02-09 11:26:14 +0000482/*
483 * If this function is called with a non NULL settings value then it must be
484 * called prior to any threads making calls to any OpenSSL functions,
485 * i.e. passing a non-null settings value is assumed to be single-threaded.
486 */
Matt Caswell0fc32b02016-02-10 13:59:15 +0000487int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
Matt Caswellb184e3e2016-02-09 11:26:14 +0000488{
Matt Caswell302f7582016-02-10 15:16:06 +0000489 static int stoperrset = 0;
490
491 if (stopped) {
492 if (!stoperrset) {
493 /*
494 * We only ever set this once to avoid getting into an infinite
495 * loop where the error system keeps trying to init and fails so
496 * sets an error etc
497 */
498 stoperrset = 1;
Rich Salza4625292016-02-10 15:20:48 -0500499 CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
Matt Caswell302f7582016-02-10 15:16:06 +0000500 }
Matt Caswell0fc32b02016-02-10 13:59:15 +0000501 return 0;
Matt Caswell302f7582016-02-10 15:16:06 +0000502 }
Rich Salzdd27f162016-02-10 00:39:29 -0500503
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000504 if (!CRYPTO_THREAD_run_once(&base, ossl_init_base))
505 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000506
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000507 if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
508 && !CRYPTO_THREAD_run_once(&load_crypto_strings,
509 ossl_init_no_load_crypto_strings))
510 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000511
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000512 if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
513 && !CRYPTO_THREAD_run_once(&load_crypto_strings,
514 ossl_init_load_crypto_strings))
515 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000516
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000517 if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
518 && !CRYPTO_THREAD_run_once(&add_all_ciphers, ossl_init_no_add_algs))
519 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000520
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000521 if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
522 && !CRYPTO_THREAD_run_once(&add_all_ciphers,
523 ossl_init_add_all_ciphers))
524 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000525
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000526 if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
527 && !CRYPTO_THREAD_run_once(&add_all_digests, ossl_init_no_add_algs))
528 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000529
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000530 if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
531 && !CRYPTO_THREAD_run_once(&add_all_digests,
532 ossl_init_add_all_digests))
533 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000534
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000535 if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
536 && !CRYPTO_THREAD_run_once(&config, ossl_init_no_config))
537 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000538
539 if (opts & OPENSSL_INIT_LOAD_CONFIG) {
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000540 int ret;
Matt Caswellc292b102016-03-07 14:39:22 +0000541 CRYPTO_THREAD_write_lock(init_lock);
Rich Salz7253fd52016-02-10 09:55:48 -0500542 config_filename = (settings == NULL) ? NULL : settings->config_name;
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000543 ret = CRYPTO_THREAD_run_once(&config, ossl_init_config);
Matt Caswellc292b102016-03-07 14:39:22 +0000544 CRYPTO_THREAD_unlock(init_lock);
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000545 if (!ret)
546 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000547 }
548
Rich Salz1288f262016-02-17 13:33:51 -0500549#ifndef OPENSSL_NO_ASYNC
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000550 if ((opts & OPENSSL_INIT_ASYNC)
551 && !CRYPTO_THREAD_run_once(&async, ossl_init_async))
552 return 0;
Rich Salz1288f262016-02-17 13:33:51 -0500553#endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000554#ifndef OPENSSL_NO_ENGINE
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000555 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
556 && !CRYPTO_THREAD_run_once(&engine_openssl,
557 ossl_init_engine_openssl))
558 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000559# if !defined(OPENSSL_NO_HW) && \
560 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000561 if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
562 && !CRYPTO_THREAD_run_once(&engine_cryptodev,
563 ossl_init_engine_cryptodev))
564 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000565# endif
566# ifndef OPENSSL_NO_RDRAND
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000567 if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
568 && !CRYPTO_THREAD_run_once(&engine_rdrand, ossl_init_engine_rdrand))
569 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000570# endif
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000571 if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
572 && !CRYPTO_THREAD_run_once(&engine_dynamic,
573 ossl_init_engine_dynamic))
574 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000575# ifndef OPENSSL_NO_STATIC_ENGINE
576# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000577 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
578 && CRYPTO_THREAD_run_once(&engine_padlock,
579 ossl_init_engine_padlock))
580 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000581# endif
582# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000583 if ((opts & OPENSSL_INIT_ENGINE_CAPI)
584 && CRYPTO_THREAD_run_once(&engine_capi, ossl_init_engine_capi))
585 return 0;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000586# endif
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000587 if ((opts & OPENSSL_INIT_ENGINE_DASYNC)
588 && !CRYPTO_THREAD_run_once(&engine_dasync, ossl_init_engine_dasync))
589 return 0;
clucey6cba4a62016-02-23 08:01:01 +0000590# if !defined(OPENSSL_NO_AFALGENG)
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000591 if ((opts & OPENSSL_INIT_ENGINE_AFALG)
592 && !CRYPTO_THREAD_run_once(&engine_afalg, ossl_init_engine_afalg))
593 return 0;
clucey6cba4a62016-02-23 08:01:01 +0000594# endif
Matt Caswellb184e3e2016-02-09 11:26:14 +0000595# endif
596 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
clucey6cba4a62016-02-23 08:01:01 +0000597 | OPENSSL_INIT_ENGINE_DASYNC | OPENSSL_INIT_ENGINE_OPENSSL
598 | OPENSSL_INIT_ENGINE_AFALG)) {
Matt Caswellb184e3e2016-02-09 11:26:14 +0000599 ENGINE_register_all_complete();
600 }
601#endif
602
Matt Caswellb1f1e7a2016-03-02 14:51:00 +0000603 if ((opts & OPENSSL_INIT_ZLIB)
604 && CRYPTO_THREAD_run_once(&zlib, ossl_init_zlib))
605 return 0;
Matt Caswell0fc32b02016-02-10 13:59:15 +0000606
607 return 1;
Matt Caswellb184e3e2016-02-09 11:26:14 +0000608}
609
Rich Salzf672aee2016-02-09 11:52:40 -0500610int OPENSSL_atexit(void (*handler)(void))
Matt Caswellb184e3e2016-02-09 11:26:14 +0000611{
612 OPENSSL_INIT_STOP *newhand;
613
614 newhand = OPENSSL_malloc(sizeof(*newhand));
615 if (newhand == NULL)
616 return 0;
617
618 newhand->handler = handler;
619 newhand->next = stop_handlers;
620 stop_handlers = newhand;
621
622 return 1;
623}
624
625