Coverage Report

Created: 2026-01-07 06:09

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