LCOV - code coverage report
Current view: top level - tls - s2n_crypto.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 79 79 100.0 %
Date: 2025-08-15 07:28:39 Functions: 5 5 100.0 %
Branches: 59 114 51.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 "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(&params->client_record_mac));
      38         [ -  + ]:     251241 :     RESULT_GUARD_POSIX(s2n_hmac_new(&params->server_record_mac));
      39                 :            : 
      40                 :            :     /* Allocate key memory */
      41         [ -  + ]:     251241 :     RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->client_key));
      42         [ -  + ]:     251241 :     RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->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(&params->client_key));
      70         [ -  + ]:    6589944 :         RESULT_GUARD(params->cipher_suite->record_alg->cipher->destroy_key(&params->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 : }

Generated by: LCOV version 1.14