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 "tls/s2n_crypto.h" 17 : : 18 : : #include "api/s2n.h" 19 : : #include "tls/s2n_cipher_suites.h" 20 : : #include "utils/s2n_result.h" 21 : : #include "utils/s2n_safety.h" 22 : : 23 : : S2N_RESULT s2n_crypto_parameters_new(struct s2n_crypto_parameters **new_params) 24 : 251241 : { 25 [ # # ][ - + ]: 251241 : RESULT_ENSURE_REF(new_params); 26 [ - + ][ # # ]: 251241 : RESULT_ENSURE_EQ(*new_params, NULL); 27 : : 28 : 251241 : DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free); 29 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crypto_parameters))); 30 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_blob_zero(&mem)); 31 : : 32 : 251241 : DEFER_CLEANUP(struct s2n_crypto_parameters *params = (struct s2n_crypto_parameters *) (void *) mem.data, 33 : 251241 : s2n_crypto_parameters_free); 34 : 251241 : ZERO_TO_DISABLE_DEFER_CLEANUP(mem); 35 : : 36 : : /* Allocate long-term memory for the HMAC states */ 37 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_hmac_new(¶ms->client_record_mac)); 38 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_hmac_new(¶ms->server_record_mac)); 39 : : 40 : : /* Allocate key memory */ 41 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_session_key_alloc(¶ms->client_key)); 42 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_session_key_alloc(¶ms->server_key)); 43 : : 44 : : /* Setup */ 45 [ - + ]: 251241 : RESULT_GUARD(s2n_crypto_parameters_wipe(params)); 46 : : 47 : 251241 : *new_params = params; 48 : 251241 : ZERO_TO_DISABLE_DEFER_CLEANUP(params); 49 : 251241 : return S2N_RESULT_OK; 50 : 251241 : } 51 : : 52 : : S2N_RESULT s2n_crypto_parameters_wipe(struct s2n_crypto_parameters *params) 53 : 6841185 : { 54 [ - + ][ # # ]: 6841185 : RESULT_ENSURE_REF(params); 55 : : 56 : : /* Wipe the hmacs for reuse */ 57 : 6841185 : struct s2n_hmac_state client_state = params->client_record_mac; 58 : 6841185 : struct s2n_hmac_state server_state = params->server_record_mac; 59 [ - + ]: 6841185 : RESULT_GUARD_POSIX(s2n_hmac_init(&client_state, S2N_HMAC_NONE, NULL, 0)); 60 [ - + ]: 6841185 : RESULT_GUARD_POSIX(s2n_hmac_init(&server_state, S2N_HMAC_NONE, NULL, 0)); 61 : : 62 : : /* Wipe the keys for reuse */ 63 : 6841185 : struct s2n_session_key client_key = params->client_key; 64 : 6841185 : struct s2n_session_key server_key = params->server_key; 65 [ + + ]: 6841185 : if (params->cipher_suite 66 [ + - ]: 6841185 : && params->cipher_suite->record_alg 67 [ + - ]: 6841185 : && params->cipher_suite->record_alg->cipher 68 [ + - ]: 6841185 : && params->cipher_suite->record_alg->cipher->destroy_key) { 69 [ - + ]: 6589944 : RESULT_GUARD(params->cipher_suite->record_alg->cipher->destroy_key(¶ms->client_key)); 70 [ - + ]: 6589944 : RESULT_GUARD(params->cipher_suite->record_alg->cipher->destroy_key(¶ms->server_key)); 71 : 6589944 : } 72 : : 73 : 6841185 : *params = (struct s2n_crypto_parameters){ 0 }; 74 : : 75 : 6841185 : params->client_record_mac = client_state; 76 : 6841185 : params->server_record_mac = server_state; 77 : 6841185 : params->client_key = client_key; 78 : 6841185 : params->server_key = server_key; 79 : 6841185 : params->cipher_suite = &s2n_null_cipher_suite; 80 : 6841185 : return S2N_RESULT_OK; 81 : 6841185 : } 82 : : 83 : : S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **params) 84 : 503032 : { 85 [ - + ][ + + ]: 503032 : if (params == NULL || *params == NULL) { 86 : 251791 : return S2N_RESULT_OK; 87 : 251791 : } 88 : : 89 : : /* Free HMAC states */ 90 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->client_record_mac)); 91 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->server_record_mac)); 92 : : 93 : : /* Free session keys */ 94 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->client_key)); 95 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->server_key)); 96 : : 97 [ - + ]: 251241 : RESULT_GUARD_POSIX(s2n_free_object((uint8_t **) params, sizeof(struct s2n_crypto_parameters))); 98 : 251241 : return S2N_RESULT_OK; 99 : 251241 : } 100 : : 101 : : S2N_RESULT s2n_crypto_parameters_switch(struct s2n_connection *conn) 102 : 3595 : { 103 [ - + ][ # # ]: 3595 : RESULT_ENSURE_REF(conn); 104 [ - + ][ # # ]: 3595 : RESULT_ENSURE_REF(conn->secure); 105 [ # # ][ - + ]: 3595 : RESULT_ENSURE_REF(conn->initial); 106 : : 107 : : /* Only start encryption if we have not already switched to secure parameters */ 108 [ + + ][ + + ]: 3595 : if (conn->mode == S2N_CLIENT && conn->client == conn->initial) { 109 : 2230 : struct s2n_blob seq = { 0 }; 110 [ - + ]: 2230 : RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN)); 111 [ - + ]: 2230 : RESULT_GUARD_POSIX(s2n_blob_zero(&seq)); 112 : 2230 : conn->client = conn->secure; 113 [ + + ][ + - ]: 2230 : } else if (conn->mode == S2N_SERVER && conn->server == conn->initial) { 114 : 1363 : struct s2n_blob seq = { 0 }; 115 [ - + ]: 1363 : RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN)); 116 [ - + ]: 1363 : RESULT_GUARD_POSIX(s2n_blob_zero(&seq)); 117 : 1363 : conn->server = conn->secure; 118 : 1363 : } 119 : : 120 : 3595 : return S2N_RESULT_OK; 121 : 3595 : } 122 : : 123 : : int s2n_connection_get_master_secret(const struct s2n_connection *conn, 124 : : uint8_t *secret_bytes, size_t max_size) 125 : 20 : { 126 [ + + ][ + - ]: 20 : POSIX_ENSURE_REF(conn); 127 [ + - ][ + + ]: 19 : POSIX_ENSURE_REF(secret_bytes); 128 [ + - ][ + + ]: 18 : POSIX_ENSURE(max_size >= S2N_TLS_SECRET_LEN, S2N_ERR_INSUFFICIENT_MEM_SIZE); 129 [ + + ][ + - ]: 15 : POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_INVALID_STATE); 130 : : /* Technically the master secret is available earlier, but after the handshake 131 : : * is the simplest rule and matches our TLS1.3 exporter behavior. */ 132 [ + - ][ + + ]: 14 : POSIX_ENSURE(is_handshake_complete(conn), S2N_ERR_HANDSHAKE_NOT_COMPLETE); 133 : : /* Final sanity check: TLS1.2 doesn't use the extract_secret_type field */ 134 [ - + ][ # # ]: 13 : POSIX_ENSURE_EQ(conn->secrets.extract_secret_type, S2N_NONE_SECRET); 135 [ - + ][ # # ]: 13 : POSIX_CHECKED_MEMCPY(secret_bytes, conn->secrets.version.tls12.master_secret, S2N_TLS_SECRET_LEN); [ + - ] 136 : 13 : return S2N_SUCCESS; 137 : 13 : }