LCOV - code coverage report
Current view: top level - utils - s2n_init.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 50 62 80.6 %
Date: 2026-10-06 07:26:09 Functions: 7 9 77.8 %
Branches: 29 62 46.8 %

           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 "api/unstable/cleanup.h"
      19                 :            : #include "crypto/s2n_fips.h"
      20                 :            : #include "crypto/s2n_libcrypto.h"
      21                 :            : #include "crypto/s2n_locking.h"
      22                 :            : #include "error/s2n_errno.h"
      23                 :            : #include "openssl/opensslv.h"
      24                 :            : #include "tls/extensions/s2n_client_key_share.h"
      25                 :            : #include "tls/extensions/s2n_extension_type.h"
      26                 :            : #include "tls/s2n_cipher_suites.h"
      27                 :            : #include "tls/s2n_security_policies.h"
      28                 :            : #include "tls/s2n_tls13_secrets.h"
      29                 :            : #include "utils/s2n_mem.h"
      30                 :            : #include "utils/s2n_random.h"
      31                 :            : #include "utils/s2n_safety.h"
      32                 :            : #include "utils/s2n_safety_macros.h"
      33                 :            : 
      34                 :            : static void s2n_cleanup_atexit(void);
      35                 :            : 
      36                 :            : static bool initialized = false;
      37                 :            : static bool atexit_cleanup = false;
      38                 :            : int s2n_disable_atexit(void)
      39                 :          0 : {
      40 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE(!initialized, S2N_ERR_INITIALIZED);
      41                 :          0 :     atexit_cleanup = false;
      42                 :          0 :     return S2N_SUCCESS;
      43                 :          0 : }
      44                 :            : 
      45                 :            : int s2n_enable_atexit(void)
      46                 :        328 : {
      47                 :        328 :     atexit_cleanup = true;
      48                 :        328 :     return S2N_SUCCESS;
      49                 :        328 : }
      50                 :            : 
      51                 :            : int s2n_init(void)
      52                 :        354 : {
      53                 :            :     /* USAGE-GUIDE says s2n_init MUST NOT be called more than once
      54                 :            :      * Public documentation for API states s2n_init should only be called once
      55                 :            :      * https://github.com/aws/s2n-tls/issues/3446 is a result of not enforcing this
      56                 :            :      */
      57 [ +  - ][ +  + ]:        354 :     POSIX_ENSURE(!initialized, S2N_ERR_INITIALIZED);
      58                 :            : 
      59         [ -  + ]:        350 :     if (getenv("S2N_INTEG_TEST")) {
      60         [ #  # ]:          0 :         POSIX_GUARD(s2n_in_integ_test_set(true));
      61                 :          0 :     }
      62                 :            : 
      63                 :            :     /* Should run before any init method that calls libcrypto methods
      64                 :            :      * to ensure we don't try to call methods that don't exist.
      65                 :            :      * It doesn't require any locks since it only deals with values that
      66                 :            :      * should be constant, so can run before s2n_locking_init. */
      67         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_libcrypto_validate_runtime());
      68                 :            :     /* Must run before any init method that allocates memory. */
      69         [ -  + ]:        350 :     POSIX_GUARD(s2n_mem_init());
      70                 :            :     /* Must run before any init method that calls libcrypto methods. */
      71         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_locking_init());
      72         [ -  + ]:        350 :     POSIX_GUARD(s2n_fips_init());
      73         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_rand_init());
      74         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_hash_algorithms_init());
      75         [ -  + ]:        350 :     POSIX_GUARD(s2n_cipher_suites_init());
      76         [ -  + ]:        350 :     POSIX_GUARD(s2n_security_policies_init());
      77         [ -  + ]:        350 :     POSIX_GUARD(s2n_config_defaults_init());
      78         [ -  + ]:        350 :     POSIX_GUARD(s2n_extension_type_init());
      79         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_tls13_empty_transcripts_init());
      80         [ -  + ]:        350 :     POSIX_GUARD_RESULT(s2n_atomic_init());
      81                 :            : 
      82         [ +  - ]:        350 :     if (atexit_cleanup) {
      83 [ -  + ][ #  # ]:        350 :         POSIX_ENSURE_OK(atexit(s2n_cleanup_atexit), S2N_ERR_ATEXIT);
      84                 :        350 :     }
      85                 :            : 
      86         [ -  + ]:        350 :     if (getenv("S2N_PRINT_STACKTRACE")) {
      87                 :          0 :         s2n_stack_traces_enabled_set(true);
      88                 :          0 :     }
      89                 :            : 
      90                 :            : #if defined(OPENSSL_IS_AWSLC)
      91                 :            :     CRYPTO_pre_sandbox_init();
      92                 :            : #endif
      93                 :            : 
      94                 :        350 :     initialized = true;
      95                 :            : 
      96                 :        350 :     return S2N_SUCCESS;
      97                 :        350 : }
      98                 :            : 
      99                 :            : static bool s2n_cleanup_atexit_impl(void)
     100                 :        377 : {
     101                 :            :     /* all of these should run, regardless of result, but the
     102                 :            :      * values to need to be consumed to prevent warnings */
     103                 :            : 
     104                 :            :     /* the configs need to be wiped before resetting the memory callbacks */
     105                 :        377 :     s2n_wipe_static_configs();
     106                 :            : 
     107         [ +  - ]:        377 :     bool cleaned_up = s2n_result_is_ok(s2n_cipher_suites_cleanup())
     108         [ +  - ]:        377 :             && s2n_result_is_ok(s2n_hash_algorithms_cleanup())
     109         [ +  - ]:        377 :             && s2n_result_is_ok(s2n_rand_cleanup())
     110         [ +  - ]:        377 :             && s2n_result_is_ok(s2n_locking_cleanup())
     111         [ +  + ]:        377 :             && (s2n_mem_cleanup() == S2N_SUCCESS);
     112                 :            : 
     113                 :        377 :     initialized = !cleaned_up;
     114                 :        377 :     return cleaned_up;
     115                 :        377 : }
     116                 :            : 
     117                 :            : int s2n_cleanup_final(void)
     118                 :         29 : {
     119                 :            :     /* some cleanups are not idempotent (rand_cleanup, mem_cleanup) so protect */
     120 [ +  + ][ +  - ]:         29 :     POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED);
     121 [ -  + ][ #  # ]:         27 :     POSIX_ENSURE(s2n_cleanup_atexit_impl(), S2N_ERR_ATEXIT);
     122                 :            : 
     123                 :         27 :     return S2N_SUCCESS;
     124                 :         27 : }
     125                 :            : 
     126                 :            : int s2n_cleanup(void)
     127                 :        297 : {
     128                 :            :     /* Previously cleaned up thread-local DRBG state. The custom DRBG has
     129                 :            :      * been removed, so this is now a no-op kept for API compatibility.
     130                 :            :      */
     131                 :        297 :     return S2N_SUCCESS;
     132                 :        297 : }
     133                 :            : 
     134                 :            : int s2n_cleanup_thread(void)
     135                 :          0 : {
     136                 :            :     /* Thread-local DRBG state has been removed. This is now a no-op kept
     137                 :            :      * for backwards compatibility with callers of the public API.
     138                 :            :      */
     139                 :          0 :     return S2N_SUCCESS;
     140                 :          0 : }
     141                 :            : 
     142                 :            : static void s2n_cleanup_atexit(void)
     143                 :        350 : {
     144                 :        350 :     (void) s2n_cleanup_atexit_impl();
     145                 :        350 : }
     146                 :            : 
     147                 :            : bool s2n_is_initialized(void)
     148                 :          4 : {
     149                 :          4 :     return initialized;
     150                 :          4 : }

Generated by: LCOV version 1.14