LCOV - code coverage report
Current view: top level - tls - s2n_handshake_transcript.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 65 65 100.0 %
Date: 2025-08-15 07:28:39 Functions: 3 3 100.0 %
Branches: 42 82 51.2 %

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

Generated by: LCOV version 1.14