Coverage Report

Created: 2026-04-08 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/init.c
Line
Count
Source
1
/*
2
 * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include "internal/e_os.h"
11
#include "crypto/cryptlib.h"
12
#include <openssl/err.h>
13
#include "crypto/rand.h"
14
#include "internal/bio.h"
15
#include <openssl/evp.h>
16
#include "crypto/evp.h"
17
#include "internal/conf.h"
18
#include "crypto/async.h"
19
#include "internal/comp.h"
20
#include "internal/err.h"
21
#include "crypto/err.h"
22
#include "crypto/objects.h"
23
#include <stdlib.h>
24
#include <assert.h>
25
#include "internal/thread_once.h"
26
#include "crypto/dso_conf.h"
27
#include "internal/dso.h"
28
#include "crypto/store.h"
29
#include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
30
#include <openssl/trace.h>
31
#include <openssl/ssl.h> /* for OPENSSL_INIT_(NO_)?LOAD_SSL_STRINGS */
32
#include "crypto/bn.h"
33
#include "crypto/ctype.h"
34
#include "sslerr.h"
35
36
#ifdef S390X_MOD_EXP
37
#include "s390x_arch.h"
38
#endif
39
40
static int stopped = 0;
41
static uint64_t optsdone = 0;
42
43
/* Guards access to the optsdone variable on platforms without atomics */
44
static CRYPTO_RWLOCK *optsdone_lock = NULL;
45
/* Guards simultaneous INIT_LOAD_CONFIG calls with non-NULL settings */
46
static CRYPTO_RWLOCK *init_lock = NULL;
47
static CRYPTO_THREAD_LOCAL in_init_config_local;
48
49
static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
50
static int base_inited = 0;
51
static int do_global_cleanup = 0;
52
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
53
16
{
54
    /* no need to init trace */
55
56
16
    OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n");
57
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
58
    ossl_malloc_setup_failures();
59
#endif
60
61
16
    if ((optsdone_lock = CRYPTO_THREAD_lock_new()) == NULL
62
16
        || (init_lock = CRYPTO_THREAD_lock_new()) == NULL)
63
0
        goto err;
64
65
16
    OPENSSL_cpuid_setup();
66
67
16
    if (!ossl_init_thread())
68
0
        goto err;
69
70
16
    if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL))
71
0
        goto err;
72
73
16
    base_inited = 1;
74
16
    return 1;
75
76
0
err:
77
0
    OSSL_TRACE(INIT, "ossl_init_base failed!\n");
78
0
    CRYPTO_THREAD_lock_free(optsdone_lock);
79
0
    optsdone_lock = NULL;
80
0
    CRYPTO_THREAD_lock_free(init_lock);
81
0
    init_lock = NULL;
82
83
0
    return 0;
84
16
}
85
86
static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
87
88
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
89
16
{
90
16
    int ret = 1;
91
    /*
92
     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
93
     * pulling in all the error strings during static linking
94
     */
95
16
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
96
16
    void *err;
97
98
16
    if (!err_shelve_state(&err))
99
0
        return 0;
100
101
16
    OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n");
102
16
    ret = ossl_err_load_crypto_strings();
103
104
16
    err_unshelve_state(err);
105
16
#endif
106
16
    return ret;
107
16
}
108
109
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
110
    ossl_init_load_crypto_strings)
111
0
{
112
    /* Do nothing in this case */
113
0
    return 1;
114
0
}
115
116
static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
117
118
DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
119
16
{
120
    /*
121
     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
122
     * pulling in all the error strings during static linking
123
     */
124
16
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
125
16
    OSSL_TRACE(INIT, "ossl_init_load_ssl_strings: ossl_err_load_SSL_strings()\n");
126
16
    ossl_err_load_SSL_strings();
127
16
#endif
128
16
    return 1;
129
16
}
130
131
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_ssl_strings,
132
    ossl_init_load_ssl_strings)
133
0
{
134
    /* Do nothing in this case */
135
0
    return 1;
136
0
}
137
138
static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
139
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
140
16
{
141
    /*
142
     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
143
     * pulling in all the ciphers during static linking
144
     */
145
16
#ifndef OPENSSL_NO_AUTOALGINIT
146
16
    OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n");
147
16
    openssl_add_all_ciphers_int();
148
16
#endif
149
16
    return 1;
150
16
}
151
152
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
153
    ossl_init_add_all_ciphers)
154
0
{
155
    /* Do nothing */
156
0
    return 1;
157
0
}
158
159
static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
160
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
161
16
{
162
    /*
163
     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
164
     * pulling in all the ciphers during static linking
165
     */
166
16
#ifndef OPENSSL_NO_AUTOALGINIT
167
16
    OSSL_TRACE(INIT, "openssl_add_all_digests()\n");
168
16
    openssl_add_all_digests_int();
169
16
#endif
170
16
    return 1;
171
16
}
172
173
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
174
    ossl_init_add_all_digests)
175
0
{
176
    /* Do nothing */
177
0
    return 1;
178
0
}
179
180
static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
181
static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
182
DEFINE_RUN_ONCE_STATIC(ossl_init_config)
183
16
{
184
16
    int ret = ossl_config_int(NULL);
185
186
16
    return ret;
187
16
}
188
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config)
189
0
{
190
0
    int ret = ossl_config_int(conf_settings);
191
192
0
    return ret;
193
0
}
194
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
195
0
{
196
0
    OSSL_TRACE(INIT, "ossl_no_config_int()\n");
197
0
    ossl_no_config_int();
198
199
0
    return 1;
200
0
}
201
202
static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
203
static int async_inited = 0;
204
DEFINE_RUN_ONCE_STATIC(ossl_init_async)
205
0
{
206
0
    OSSL_TRACE(INIT, "async_init()\n");
207
0
    if (!async_init())
208
0
        return 0;
209
0
    async_inited = 1;
210
0
    return 1;
211
0
}
212
213
/*
214
 * Global cleanup function. This is optional, and not strictly
215
 * necessary to run. Operating systems have successfully been
216
 * recovering memory from exiting tasks since the days when I amused
217
 * myself by drawing dinosaurs in crayon on used punch cards.
218
 *
219
 * If we have destructor support, this function is installed and
220
 * always run as a global destructor. It only does anything if
221
 * someone has called OPENSSL_cleanup() before it is run.
222
 *
223
 * This ensures that we do the actual cleanup requested by an
224
 * OPENSSL_cleanup() only after subordinate library destructors which
225
 * may call into OpenSSL have run.
226
 *
227
 * If we do not have destructor support, then this function is not
228
 * normally run, and OPENSSL_cleanup() will do nothing. If we are
229
 * compiled with the compile time define of
230
 * DO_NOT_SKIP_OPENSSL_CLEANUP, this function will be called
231
 * directly from OPENSSL_cleanup() so that cleanup will happen
232
 * when OPENSSL_cleanup() is called.
233
 */
234
void ossl_cleanup_destructor(void)
235
0
{
236
    /*
237
     * At some point we should consider looking at this function with a view to
238
     * moving most/all of this into onfree handlers in OSSL_LIB_CTX.
239
     */
240
241
    /* If we've not been inited then no need to deinit */
242
0
    if (!base_inited)
243
0
        return;
244
245
    /* If we have not been told to clean up, and we are invoked, return */
246
0
    if (!do_global_cleanup)
247
0
        return;
248
249
    /* Might be explicitly called */
250
0
    if (stopped)
251
0
        return;
252
0
    stopped = 1;
253
254
    /*
255
     * Thread stop may not get automatically called by the thread library for
256
     * the very last thread in some situations, so call it directly.
257
     */
258
0
    OPENSSL_thread_stop();
259
260
0
    CRYPTO_THREAD_lock_free(optsdone_lock);
261
0
    optsdone_lock = NULL;
262
0
    CRYPTO_THREAD_lock_free(init_lock);
263
0
    init_lock = NULL;
264
265
0
    CRYPTO_THREAD_cleanup_local(&in_init_config_local);
266
267
    /*
268
     * We assume we are single-threaded for this function, i.e. no race
269
     * conditions for the various "*_inited" vars below.
270
     */
271
272
0
#ifndef OPENSSL_NO_COMP
273
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n");
274
0
    ossl_comp_zlib_cleanup();
275
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_brotli_cleanup()\n");
276
0
    ossl_comp_brotli_cleanup();
277
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zstd_cleanup()\n");
278
0
    ossl_comp_zstd_cleanup();
279
0
#endif
280
281
0
    if (async_inited) {
282
0
        OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n");
283
0
        async_deinit();
284
0
    }
285
286
    /*
287
     * Note that cleanup order is important:
288
     * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so
289
     * must be called before engine_cleanup_int()
290
     * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
291
     * before the ex data handlers are wiped during default ossl_lib_ctx deinit.
292
     * - ossl_config_modules_free() can end up in ENGINE code so must be called
293
     * before engine_cleanup_int()
294
     * - ENGINEs and additional EVP algorithms might use added OIDs names so
295
     * ossl_obj_cleanup_int() must be called last
296
     */
297
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n");
298
0
    ossl_rand_cleanup_int();
299
300
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n");
301
0
    ossl_config_modules_free();
302
303
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
304
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
305
0
    ossl_store_cleanup_int();
306
0
#endif
307
308
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n");
309
0
    ossl_lib_ctx_default_deinit();
310
311
0
    ossl_cleanup_thread();
312
313
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
314
0
    bio_cleanup();
315
316
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n");
317
0
    evp_cleanup_int();
318
319
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n");
320
0
    ossl_obj_cleanup_int();
321
322
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n");
323
0
    err_cleanup();
324
325
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n");
326
0
    CRYPTO_secure_malloc_done();
327
328
0
#ifndef OPENSSL_NO_CMP
329
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n");
330
0
    OSSL_CMP_log_close();
331
0
#endif
332
333
0
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
334
0
    ossl_trace_cleanup();
335
336
#ifdef S390X_MOD_EXP
337
    OPENSSL_s390x_cleanup();
338
#endif
339
340
0
    base_inited = 0;
341
0
}
342
343
/*
344
 * If this function is called with a non NULL settings value then it must be
345
 * called prior to any threads making calls to any OpenSSL functions,
346
 * i.e. passing a non-null settings value is assumed to be single-threaded.
347
 */
348
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
349
247k
{
350
247k
    uint64_t tmp;
351
247k
    int aloaddone = 0;
352
353
    /* Applications depend on 0 being returned when cleanup was already done */
354
247k
    if (ossl_unlikely(stopped)) {
355
0
        if (!(opts & OPENSSL_INIT_BASE_ONLY))
356
0
            ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL);
357
0
        return 0;
358
0
    }
359
360
    /*
361
     * We ignore failures from this function. It is probably because we are
362
     * on a platform that doesn't support lockless atomic loads (we may not
363
     * have created optsdone_lock yet so we can't use it). This is just an
364
     * optimisation to skip the full checks in this function if we don't need
365
     * to, so we carry on regardless in the event of failure.
366
     *
367
     * There could be a race here with other threads, so that optsdone has not
368
     * been updated yet, even though the options have in fact been initialised.
369
     * This doesn't matter - it just means we will run the full function
370
     * unnecessarily - but all the critical code is contained in RUN_ONCE
371
     * functions anyway so we are safe.
372
     */
373
247k
    if (ossl_likely(CRYPTO_atomic_load(&optsdone, &tmp, NULL))) {
374
247k
        if ((tmp & opts) == opts)
375
154
            return 1;
376
247k
        aloaddone = 1;
377
247k
    }
378
379
    /*
380
     * At some point we should look at this function with a view to moving
381
     * most/all of this into OSSL_LIB_CTX.
382
     *
383
     * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
384
     * *only* option specified.  With that option we return immediately after
385
     * doing the requested limited initialization.
386
     *
387
     * If we remain the only caller of err_shelve_state() the recursion should
388
     * perhaps be removed, but if in doubt, it can be left in place.
389
     */
390
247k
    if (ossl_unlikely(!RUN_ONCE(&base, ossl_init_base)))
391
0
        return 0;
392
393
247k
    if (opts & OPENSSL_INIT_BASE_ONLY)
394
247k
        return 1;
395
396
    /*
397
     * optsdone_lock should definitely be set up now, so we can now repeat the
398
     * same check from above but be sure that it will work even on platforms
399
     * without lockless CRYPTO_atomic_load
400
     */
401
32
    if (!aloaddone) {
402
0
        if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock))
403
0
            return 0;
404
0
        if ((tmp & opts) == opts)
405
0
            return 1;
406
0
    }
407
408
32
    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
409
0
        && !RUN_ONCE_ALT(&load_crypto_strings,
410
32
            ossl_init_no_load_crypto_strings,
411
32
            ossl_init_load_crypto_strings))
412
0
        return 0;
413
414
32
    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
415
32
        && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
416
0
        return 0;
417
418
32
    if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
419
0
        && !RUN_ONCE_ALT(&ssl_strings, ossl_init_no_load_ssl_strings,
420
32
            ossl_init_load_ssl_strings))
421
0
        return 0;
422
423
32
    if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS)
424
16
        && !RUN_ONCE(&ssl_strings, ossl_init_load_ssl_strings))
425
0
        return 0;
426
427
32
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
428
0
        && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
429
32
            ossl_init_add_all_ciphers))
430
0
        return 0;
431
432
32
    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
433
16
        && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
434
0
        return 0;
435
436
32
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
437
0
        && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
438
32
            ossl_init_add_all_digests))
439
0
        return 0;
440
441
32
    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
442
16
        && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
443
0
        return 0;
444
445
32
    if ((opts & OPENSSL_INIT_ATFORK)
446
0
        && !openssl_init_fork_handlers())
447
0
        return 0;
448
449
32
    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
450
0
        && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
451
0
        return 0;
452
453
32
    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
454
16
        int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL;
455
456
        /* If called recursively from OBJ_ calls, just skip it. */
457
16
        if (!loading) {
458
16
            int ret;
459
460
16
            if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1))
461
0
                return 0;
462
16
            if (settings == NULL) {
463
16
                ret = RUN_ONCE(&config, ossl_init_config);
464
16
            } else {
465
0
                if (!CRYPTO_THREAD_write_lock(init_lock))
466
0
                    return 0;
467
0
                conf_settings = settings;
468
0
                ret = RUN_ONCE_ALT(&config, ossl_init_config_settings,
469
0
                    ossl_init_config);
470
0
                conf_settings = NULL;
471
0
                CRYPTO_THREAD_unlock(init_lock);
472
0
            }
473
474
16
            if (ret <= 0)
475
0
                return 0;
476
16
        }
477
16
    }
478
479
32
    if ((opts & OPENSSL_INIT_ASYNC)
480
0
        && !RUN_ONCE(&async, ossl_init_async))
481
0
        return 0;
482
483
32
    if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
484
0
        return 0;
485
486
32
    return 1;
487
32
}
488
489
void OPENSSL_cleanup(void)
490
0
{
491
0
    do_global_cleanup = 1;
492
0
#if defined(OSSL_CLEANUP_USING_DESTRUCTOR)
493
0
    return;
494
0
#endif /* defined(OSSL_CLEANUP_USING_DESTRUCTOR) */
495
496
#if defined(DO_NOT_SKIP_OPENSSL_CLEANUP)
497
    ossl_cleanup_destructor();
498
#endif /* defined(DO_NOT_SKIP_OPENSSL_CLEANUP) */
499
0
}