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 : }