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 "stuffer/s2n_stuffer.h" 17 : : #include "tls/s2n_connection.h" 18 : : #include "tls/s2n_tls.h" 19 : : #include "tls/s2n_tls13_handshake.h" 20 : : #include "utils/s2n_blob.h" 21 : : 22 : : /* Length of the synthetic message header */ 23 : 1300 : #define MESSAGE_HASH_HEADER_LENGTH 4 24 : : 25 : : S2N_RESULT s2n_handshake_transcript_update(struct s2n_connection *conn) 26 : 80698 : { 27 [ # # ][ - + ]: 80698 : RESULT_ENSURE_REF(conn); 28 : : 29 : 80698 : struct s2n_stuffer message = conn->handshake.io; 30 [ - + ]: 80698 : RESULT_GUARD_POSIX(s2n_stuffer_reread(&message)); 31 : : 32 : 80698 : struct s2n_blob data = { 0 }; 33 : 80698 : uint32_t len = s2n_stuffer_data_available(&message); 34 : 80698 : uint8_t *bytes = s2n_stuffer_raw_read(&message, len); 35 [ - + ][ # # ]: 80698 : RESULT_ENSURE_REF(bytes); 36 [ - + ]: 80698 : RESULT_GUARD_POSIX(s2n_blob_init(&data, bytes, len)); 37 : : 38 [ - + ]: 80698 : RESULT_GUARD_POSIX(s2n_conn_update_handshake_hashes(conn, &data)); 39 : 80698 : return S2N_RESULT_OK; 40 : 80698 : } 41 : : 42 : : int s2n_conn_update_handshake_hashes(struct s2n_connection *conn, struct s2n_blob *data) 43 : 83306 : { 44 [ - + ][ # # ]: 83306 : POSIX_ENSURE_REF(conn); 45 [ - + ][ # # ]: 83306 : POSIX_ENSURE_REF(data); 46 : 83306 : struct s2n_handshake_hashes *hashes = conn->handshake.hashes; 47 [ - + ][ # # ]: 83306 : POSIX_ENSURE_REF(hashes); 48 : : 49 : : /* MD5 and SHA1 are not permitted in FIPS mode, but an exception is made in 50 : : * order to continue to support TLS1.0 and TLS1.1. NIST SP 800-52r1 approves 51 : : * their continued use for the signature check in the CertificateVerify message 52 : : * and the PRF when negotiating TLS1.0 or TLS1.1 (see footnotes 15 and 20, 53 : : * and section 3.3.2) 54 : : */ 55 : : 56 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5)) { 57 [ - + ]: 43871 : POSIX_GUARD(s2n_hash_update(&hashes->md5, data->data, data->size)); 58 : 43871 : } 59 : : 60 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1)) { 61 [ - + ]: 43871 : POSIX_GUARD(s2n_hash_update(&hashes->sha1, data->data, data->size)); 62 : 43871 : } 63 : : 64 : 83306 : const uint8_t md5_sha1_required = 65 [ + + ]: 83306 : (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_MD5) 66 [ + - ]: 83306 : && s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA1)); 67 : : 68 [ + + ]: 83306 : if (md5_sha1_required) { 69 [ - + ]: 43871 : POSIX_GUARD(s2n_hash_update(&hashes->md5_sha1, data->data, data->size)); 70 : 43871 : } 71 : : 72 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA224)) { 73 [ - + ]: 41779 : POSIX_GUARD(s2n_hash_update(&hashes->sha224, data->data, data->size)); 74 : 41779 : } 75 : : 76 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA256)) { 77 [ - + ]: 80191 : POSIX_GUARD(s2n_hash_update(&hashes->sha256, data->data, data->size)); 78 : 80191 : } 79 : : 80 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA384)) { 81 [ - + ]: 42802 : POSIX_GUARD(s2n_hash_update(&hashes->sha384, data->data, data->size)); 82 : 42802 : } 83 : : 84 [ + + ]: 83306 : if (s2n_handshake_is_hash_required(&conn->handshake, S2N_HASH_SHA512)) { 85 [ - + ]: 41779 : POSIX_GUARD(s2n_hash_update(&hashes->sha512, data->data, data->size)); 86 : 41779 : } 87 : : 88 : 83306 : return S2N_SUCCESS; 89 : 83306 : } 90 : : 91 : : /* When a HelloRetryRequest message is used, the hash transcript needs to be recreated. 92 : : * This is done with a synthetic message header, and the hash of ClientHello1. 93 : : * 94 : : * https://tools.ietf.org/html/rfc8446#section-4.4.1 95 : : */ 96 : : int s2n_server_hello_retry_recreate_transcript(struct s2n_connection *conn) 97 : 1300 : { 98 [ - + ][ # # ]: 1300 : POSIX_ENSURE_REF(conn); 99 : 1300 : struct s2n_handshake_hashes *hashes = conn->handshake.hashes; 100 [ - + ][ # # ]: 1300 : POSIX_ENSURE_REF(hashes); 101 : : 102 [ - + ]: 1300 : s2n_tls13_connection_keys(keys, conn); 103 : 1300 : uint8_t hash_digest_length = keys.size; 104 : : 105 : : /* Create the MessageHash (our synthetic message) */ 106 : 1300 : uint8_t msghdr[MESSAGE_HASH_HEADER_LENGTH] = { 0 }; 107 : 1300 : msghdr[0] = TLS_MESSAGE_HASH; 108 : 1300 : msghdr[MESSAGE_HASH_HEADER_LENGTH - 1] = hash_digest_length; 109 : : 110 : : /* Grab the current transcript hash to use as the ClientHello1 value. */ 111 : 1300 : struct s2n_hash_state *client_hello1_hash = &hashes->hash_workspace; 112 : 1300 : uint8_t client_hello1_digest_out[S2N_MAX_DIGEST_LEN] = { 0 }; 113 [ - + ]: 1300 : POSIX_GUARD_RESULT(s2n_handshake_copy_hash_state(conn, keys.hash_algorithm, client_hello1_hash)); 114 [ - + ]: 1300 : POSIX_GUARD(s2n_hash_digest(client_hello1_hash, client_hello1_digest_out, hash_digest_length)); 115 : : 116 : : /* Step 1: Reset the hash state */ 117 [ - + ]: 1300 : POSIX_GUARD_RESULT(s2n_handshake_reset_hash_state(conn, keys.hash_algorithm)); 118 : : 119 : : /* Step 2: Update the transcript with the synthetic message */ 120 : 1300 : struct s2n_blob msg_blob = { 0 }; 121 [ - + ]: 1300 : POSIX_GUARD(s2n_blob_init(&msg_blob, msghdr, MESSAGE_HASH_HEADER_LENGTH)); 122 [ - + ]: 1300 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob)); 123 : : 124 : : /* Step 3: Update the transcript with the ClientHello1 hash */ 125 [ - + ]: 1300 : POSIX_GUARD(s2n_blob_init(&msg_blob, client_hello1_digest_out, hash_digest_length)); 126 [ - + ]: 1300 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &msg_blob)); 127 : : 128 : 1300 : return S2N_SUCCESS; 129 : 1300 : }