LCOV - code coverage report
Current view: top level - utils - s2n_init.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 57 66 86.4 %
Date: 2025-08-15 07:28:39 Functions: 8 9 88.9 %
Branches: 32 68 47.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License").
       5                 :            :  * You may not use this file except in compliance with the License.
       6                 :            :  * A copy of the License is located at
       7                 :            :  *
       8                 :            :  *  http://aws.amazon.com/apache2.0
       9                 :            :  *
      10                 :            :  * or in the "license" file accompanying this file. This file is distributed
      11                 :            :  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
      12                 :            :  * express or implied. See the License for the specific language governing
      13                 :            :  * permissions and limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "utils/s2n_init.h"
      17                 :            : 
      18                 :            : #include <pthread.h>
      19                 :            : 
      20                 :            : #include "api/unstable/cleanup.h"
      21                 :            : #include "crypto/s2n_fips.h"
      22                 :            : #include "crypto/s2n_libcrypto.h"
      23                 :            : #include "crypto/s2n_locking.h"
      24                 :            : #include "error/s2n_errno.h"
      25                 :            : #include "openssl/opensslv.h"
      26                 :            : #include "tls/extensions/s2n_client_key_share.h"
      27                 :            : #include "tls/extensions/s2n_extension_type.h"
      28                 :            : #include "tls/s2n_cipher_suites.h"
      29                 :            : #include "tls/s2n_security_policies.h"
      30                 :            : #include "tls/s2n_tls13_secrets.h"
      31                 :            : #include "utils/s2n_mem.h"
      32                 :            : #include "utils/s2n_random.h"
      33                 :            : #include "utils/s2n_safety.h"
      34                 :            : #include "utils/s2n_safety_macros.h"
      35                 :            : 
      36                 :            : static void s2n_cleanup_atexit(void);
      37                 :            : 
      38                 :            : static pthread_t main_thread = 0;
      39                 :            : static bool initialized = false;
      40                 :            : static bool atexit_cleanup = false;
      41                 :            : int s2n_disable_atexit(void)
      42                 :          0 : {
      43 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE(!initialized, S2N_ERR_INITIALIZED);
      44                 :          0 :     atexit_cleanup = false;
      45                 :          0 :     return S2N_SUCCESS;
      46                 :          0 : }
      47                 :            : 
      48                 :            : int s2n_enable_atexit(void)
      49                 :        522 : {
      50                 :        522 :     atexit_cleanup = true;
      51                 :        522 :     return S2N_SUCCESS;
      52                 :        522 : }
      53                 :            : 
      54                 :            : int s2n_init(void)
      55                 :        549 : {
      56                 :            :     /* USAGE-GUIDE says s2n_init MUST NOT be called more than once
      57                 :            :      * Public documentation for API states s2n_init should only be called once
      58                 :            :      * https://github.com/aws/s2n-tls/issues/3446 is a result of not enforcing this
      59                 :            :      */
      60 [ +  - ][ +  + ]:        549 :     POSIX_ENSURE(!initialized, S2N_ERR_INITIALIZED);
      61                 :            : 
      62                 :        545 :     main_thread = pthread_self();
      63                 :            : 
      64         [ -  + ]:        545 :     if (getenv("S2N_INTEG_TEST")) {
      65         [ #  # ]:          0 :         POSIX_GUARD(s2n_in_integ_test_set(true));
      66                 :          0 :     }
      67                 :            : 
      68                 :            :     /* Should run before any init method that calls libcrypto methods
      69                 :            :      * to ensure we don't try to call methods that don't exist.
      70                 :            :      * It doesn't require any locks since it only deals with values that
      71                 :            :      * should be constant, so can run before s2n_locking_init. */
      72         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_libcrypto_validate_runtime());
      73                 :            :     /* Must run before any init method that allocates memory. */
      74         [ -  + ]:        545 :     POSIX_GUARD(s2n_mem_init());
      75                 :            :     /* Must run before any init method that calls libcrypto methods. */
      76         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_locking_init());
      77         [ -  + ]:        545 :     POSIX_GUARD(s2n_fips_init());
      78         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_rand_init());
      79         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_hash_algorithms_init());
      80         [ -  + ]:        545 :     POSIX_GUARD(s2n_cipher_suites_init());
      81         [ -  + ]:        545 :     POSIX_GUARD(s2n_security_policies_init());
      82         [ -  + ]:        545 :     POSIX_GUARD(s2n_config_defaults_init());
      83         [ -  + ]:        545 :     POSIX_GUARD(s2n_extension_type_init());
      84         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_tls13_empty_transcripts_init());
      85         [ -  + ]:        545 :     POSIX_GUARD_RESULT(s2n_atomic_init());
      86                 :            : 
      87         [ +  - ]:        545 :     if (atexit_cleanup) {
      88 [ -  + ][ #  # ]:        545 :         POSIX_ENSURE_OK(atexit(s2n_cleanup_atexit), S2N_ERR_ATEXIT);
      89                 :        545 :     }
      90                 :            : 
      91         [ -  + ]:        545 :     if (getenv("S2N_PRINT_STACKTRACE")) {
      92                 :          0 :         s2n_stack_traces_enabled_set(true);
      93                 :          0 :     }
      94                 :            : 
      95                 :            : #if defined(OPENSSL_IS_AWSLC)
      96                 :            :     CRYPTO_pre_sandbox_init();
      97                 :            : #endif
      98                 :            : 
      99                 :        545 :     initialized = true;
     100                 :            : 
     101                 :        545 :     return S2N_SUCCESS;
     102                 :        545 : }
     103                 :            : 
     104                 :            : static bool s2n_cleanup_atexit_impl(void)
     105                 :        576 : {
     106                 :            :     /* all of these should run, regardless of result, but the
     107                 :            :      * values to need to be consumed to prevent warnings */
     108                 :            : 
     109                 :            :     /* the configs need to be wiped before resetting the memory callbacks */
     110                 :        576 :     s2n_wipe_static_configs();
     111                 :            : 
     112         [ +  - ]:        576 :     bool cleaned_up = s2n_result_is_ok(s2n_cipher_suites_cleanup())
     113         [ +  - ]:        576 :             && s2n_result_is_ok(s2n_hash_algorithms_cleanup())
     114         [ +  - ]:        576 :             && s2n_result_is_ok(s2n_rand_cleanup_thread())
     115         [ +  + ]:        576 :             && s2n_result_is_ok(s2n_rand_cleanup())
     116         [ +  - ]:        576 :             && s2n_result_is_ok(s2n_locking_cleanup())
     117         [ +  - ]:        576 :             && (s2n_mem_cleanup() == S2N_SUCCESS);
     118                 :            : 
     119                 :        576 :     initialized = !cleaned_up;
     120                 :        576 :     return cleaned_up;
     121                 :        576 : }
     122                 :            : 
     123                 :            : int s2n_cleanup_thread(void)
     124                 :        303 : {
     125                 :            :     /* s2n_cleanup_thread is supposed to be called from each thread before exiting,
     126                 :            :      * so ensure that whatever clean ups we have here are thread safe */
     127         [ -  + ]:        303 :     POSIX_GUARD_RESULT(s2n_rand_cleanup_thread());
     128                 :        303 :     return S2N_SUCCESS;
     129                 :        303 : }
     130                 :            : 
     131                 :            : int s2n_cleanup_final(void)
     132                 :         34 : {
     133                 :            :     /* some cleanups are not idempotent (rand_cleanup, mem_cleanup) so protect */
     134 [ +  + ][ +  - ]:         34 :     POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED);
     135 [ -  + ][ #  # ]:         31 :     POSIX_ENSURE(s2n_cleanup_atexit_impl(), S2N_ERR_ATEXIT);
     136                 :            : 
     137                 :         31 :     return S2N_SUCCESS;
     138                 :         31 : }
     139                 :            : 
     140                 :            : int s2n_cleanup(void)
     141                 :        300 : {
     142         [ -  + ]:        300 :     POSIX_GUARD(s2n_cleanup_thread());
     143                 :            : 
     144                 :        300 :     return S2N_SUCCESS;
     145                 :        300 : }
     146                 :            : 
     147                 :            : static void s2n_cleanup_atexit(void)
     148                 :        545 : {
     149                 :        545 :     (void) s2n_cleanup_atexit_impl();
     150                 :        545 : }
     151                 :            : 
     152                 :            : bool s2n_is_initialized(void)
     153                 :       4153 : {
     154                 :       4153 :     return initialized;
     155                 :       4153 : }

Generated by: LCOV version 1.14