LCOV - code coverage report
Current view: top level - tls - s2n_record_read.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 134 136 98.5 %
Date: 2026-08-22 07:27:53 Functions: 6 6 100.0 %
Branches: 102 146 69.9 %

           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_record_read.h"
      17                 :            : 
      18                 :            : #include "crypto/s2n_cipher.h"
      19                 :            : #include "crypto/s2n_hmac.h"
      20                 :            : #include "crypto/s2n_sequence.h"
      21                 :            : #include "error/s2n_errno.h"
      22                 :            : #include "stuffer/s2n_stuffer.h"
      23                 :            : #include "tls/s2n_cipher_suites.h"
      24                 :            : #include "tls/s2n_connection.h"
      25                 :            : #include "tls/s2n_crypto.h"
      26                 :            : #include "utils/s2n_blob.h"
      27                 :            : #include "utils/s2n_safety.h"
      28                 :            : 
      29                 :            : int s2n_sslv2_record_header_parse(
      30                 :            :         struct s2n_connection *conn,
      31                 :            :         uint8_t *record_type,
      32                 :            :         uint8_t *client_protocol_version,
      33                 :            :         uint16_t *fragment_length)
      34                 :        449 : {
      35                 :        449 :     struct s2n_stuffer *header_in = &conn->header_in;
      36                 :            : 
      37 [ -  + ][ #  # ]:        449 :     POSIX_ENSURE(s2n_stuffer_data_available(header_in) >= S2N_TLS_RECORD_HEADER_LENGTH,
      38                 :        449 :             S2N_ERR_BAD_MESSAGE);
      39                 :            : 
      40         [ -  + ]:        449 :     POSIX_GUARD(s2n_stuffer_read_uint16(header_in, fragment_length));
      41                 :            : 
      42                 :            :     /* The first bit of the SSLv2 message would usually indicate whether the
      43                 :            :      * length is 2 bytes long or 3 bytes long.
      44                 :            :      * See https://www.ietf.org/archive/id/draft-hickman-netscape-ssl-00.txt
      45                 :            :      *
      46                 :            :      * However, s2n-tls only supports SSLv2 for ClientHellos as defined in the
      47                 :            :      * TLS1.2 RFC. In that case, the first bit must always be set to distinguish
      48                 :            :      * SSLv2 from non-SSLv2 headers. The length is always 2 bytes.
      49                 :            :      * See https://datatracker.ietf.org/doc/html/rfc5246#appendix-E.2
      50                 :            :      *
      51                 :            :      * Since the first bit is not actually used to indicate length, we need to
      52                 :            :      * remove it from the length.
      53                 :            :      *
      54                 :            :      *= https://www.rfc-editor.org/rfc/rfc5246#appendix-E.2
      55                 :            :      *# msg_length
      56                 :            :      *#    The highest bit MUST be 1; the remaining bits contain the length
      57                 :            :      *#    of the following data in bytes.
      58                 :            :      */
      59 [ #  # ][ -  + ]:        449 :     POSIX_ENSURE(*fragment_length & S2N_TLS_SSLV2_HEADER_FLAG_UINT16, S2N_ERR_BAD_MESSAGE);
      60                 :        449 :     *fragment_length ^= S2N_TLS_SSLV2_HEADER_FLAG_UINT16;
      61                 :            : 
      62                 :            :     /* We read 5 bytes into header_in because we expected a standard, non-SSLv2 record header
      63                 :            :      * instead of an SSLv2 message. We have therefore already read 3 bytes of the payload.
      64                 :            :      * We need to adjust "fragment_length" to account for the bytes we have already
      65                 :            :      * read so that we will only attempt to read the remainder of the payload on
      66                 :            :      * our next call to conn->recv.
      67                 :            :      */
      68 [ +  + ][ +  - ]:        449 :     POSIX_ENSURE(*fragment_length >= s2n_stuffer_data_available(header_in), S2N_ERR_BAD_MESSAGE);
      69                 :        447 :     *fragment_length -= s2n_stuffer_data_available(header_in);
      70                 :            : 
      71                 :            :     /* By reading 5 bytes for a standard header we have also read the first
      72                 :            :      * 3 bytes of the SSLv2 ClientHello message.
      73                 :            :      * So we now need to parse those three bytes.
      74                 :            :      *
      75                 :            :      * The first field of an SSLv2 ClientHello is the msg_type.
      76                 :            :      * This is always '1', matching the ClientHello msg_type used by later
      77                 :            :      * handshake messages.
      78                 :            :      */
      79         [ -  + ]:        447 :     POSIX_GUARD(s2n_stuffer_read_uint8(header_in, record_type));
      80                 :            : 
      81                 :            :     /*
      82                 :            :      * The second field of an SSLv2 ClientHello is the version.
      83                 :            :      *
      84                 :            :      * The protocol version read here will likely not be SSLv2, since we only
      85                 :            :      * accept SSLv2 ClientHellos offering higher protocol versions.
      86                 :            :      * See s2n_sslv2_client_hello_parse.
      87                 :            :      */
      88                 :        447 :     uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
      89         [ -  + ]:        447 :     POSIX_GUARD(s2n_stuffer_read_bytes(header_in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
      90                 :        447 :     *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1];
      91                 :            : 
      92         [ -  + ]:        447 :     POSIX_GUARD(s2n_stuffer_reread(header_in));
      93                 :        447 :     return 0;
      94                 :        447 : }
      95                 :            : 
      96                 :            : /**
      97                 :            :  * - `conn`: connection with record header available in internal buffers
      98                 :            :  * - `header`: output parameter, populated after the header is parsed
      99                 :            :  */
     100                 :            : int s2n_record_header_parse(
     101                 :            :         struct s2n_connection *conn,
     102                 :            :         struct s2n_record_header *header)
     103                 :    7326434 : {
     104                 :    7326434 :     struct s2n_stuffer *in = &conn->header_in;
     105                 :            : 
     106 [ -  + ][ #  # ]:    7326434 :     S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
     107                 :            : 
     108         [ -  + ]:    7326434 :     POSIX_GUARD(s2n_stuffer_read_uint8(in, &header->content_type));
     109                 :            : 
     110                 :            :     /* Once the protocol version is established, reject records with
     111                 :            :      * content_type values outside the valid TLS set {20, 21, 22, 23}.
     112                 :            :      * This is the earliest possible rejection point, before any buffer
     113                 :            :      * allocation or cryptographic work.
     114                 :            :      *
     115                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
     116                 :            :      *# type:  The higher-level protocol used to process the enclosed
     117                 :            :      *#    fragment.
     118                 :            :      *
     119                 :            :      * Before the protocol version is established, we must be lenient
     120                 :            :      * because the first record (ClientHello) may arrive before we know
     121                 :            :      * the protocol version.
     122                 :            :      */
     123         [ +  + ]:    7326434 :     if (conn->actual_protocol_version_established) {
     124                 :    6807906 :         switch (header->content_type) {
     125         [ +  + ]:      21842 :             case TLS_CHANGE_CIPHER_SPEC:
     126         [ +  + ]:      24402 :             case TLS_ALERT:
     127         [ +  + ]:      64273 :             case TLS_HANDSHAKE:
     128         [ +  + ]:    6807781 :             case TLS_APPLICATION_DATA:
     129                 :    6807781 :                 break;
     130         [ +  + ]:        125 :             default:
     131         [ +  - ]:        125 :                 POSIX_BAIL(S2N_ERR_BAD_MESSAGE);
     132                 :    6807906 :         }
     133                 :    6807906 :     }
     134                 :            : 
     135         [ -  + ]:    7326309 :     POSIX_GUARD(s2n_stuffer_read_uint16(in, &header->version));
     136                 :    7326309 :     uint8_t major_version = header->version >> 8;
     137                 :    7326309 :     uint8_t minor_version = header->version & 0xFF;
     138                 :            : 
     139                 :            :     /* s2n has it's own legacy format for storing version numbers */
     140                 :    7326309 :     const uint8_t version = (major_version * 10) + minor_version;
     141                 :            :     /* We record the protocol version in the first record seen by the server for fingerprinting usecases */
     142         [ +  + ]:    7326309 :     if (!conn->client_hello.record_version_recorded) {
     143                 :    3307945 :         conn->client_hello.legacy_record_version = version;
     144                 :    3307945 :         conn->client_hello.record_version_recorded = 1;
     145                 :    3307945 :     }
     146                 :            : 
     147                 :            :     /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record
     148                 :            :      * layer version number for the first TLS record. There is some ambiguity here because the client does not know
     149                 :            :      * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use
     150                 :            :      * a garbage value(not {03,XX}) in the ClientHello.
     151                 :            :      * Choose to be lenient to these clients. After protocol negotiation, we will enforce that all record versions
     152                 :            :      * match the negotiated version.
     153                 :            :      */
     154                 :            : 
     155 [ +  + ][ +  + ]:    7326309 :     S2N_ERROR_IF(conn->actual_protocol_version_established && S2N_MIN(conn->actual_protocol_version, S2N_TLS12) /* check against legacy record version (1.2) in tls 1.3 */
         [ +  + ][ +  - ]
     156                 :    7326309 :                             != version,
     157                 :    7326309 :             S2N_ERR_BAD_MESSAGE);
     158                 :            : 
     159                 :            :     /* Some servers send fragments that are above the maximum length (e.g.
     160                 :            :      * Openssl 1.0.1), so we don't check if the fragment length is >
     161                 :            :      * S2N_TLS_MAXIMUM_FRAGMENT_LENGTH. We allow up to 2^16.
     162                 :            :      *
     163                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
     164                 :            :      *= type=exception
     165                 :            :      *= reason=Incorrect implementations exist in the wild. Ignoring instead.
     166                 :            :      *# The length MUST NOT exceed 2^14 bytes.  An
     167                 :            :      *# endpoint that receives a record that exceeds this length MUST
     168                 :            :      *# terminate the connection with a "record_overflow" alert.
     169                 :            :      */
     170         [ -  + ]:    7326307 :     POSIX_GUARD(s2n_stuffer_read_uint16(in, &header->length));
     171         [ -  + ]:    7326307 :     POSIX_GUARD(s2n_stuffer_reread(in));
     172                 :            : 
     173                 :    7326307 :     return 0;
     174                 :    7326307 : }
     175                 :            : 
     176                 :            : /* In TLS 1.3, handle CCS message as unprotected records all the time.
     177                 :            :  * https://tools.ietf.org/html/rfc8446#section-5
     178                 :            :  *
     179                 :            :  * In TLS 1.2 and TLS 1.3 Alert messages are plaintext or encrypted
     180                 :            :  * depending on the context of the connection. If we receive an encrypted
     181                 :            :  * alert, the record type is TLS_APPLICATION_DATA at this point. It will
     182                 :            :  * be decrypted and processed in s2n_handshake_io. We may receive a
     183                 :            :  * plaintext alert if we hit an error before the handshake completed
     184                 :            :  * (like a certificate failed to validate).
     185                 :            :  * https://tools.ietf.org/html/rfc8446#section-6
     186                 :            :  *
     187                 :            :  * This function is specific to TLS 1.3 to avoid changing the behavior
     188                 :            :  * of existing interpretation of TLS 1.2 alerts. */
     189                 :            : static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t content_type)
     190                 :    7227482 : {
     191         [ +  + ]:    7227482 :     if (conn->actual_protocol_version != S2N_TLS13) {
     192                 :    7050280 :         return false;
     193                 :    7050280 :     }
     194                 :            : 
     195                 :            :     /*
     196                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-5.2
     197                 :            :      *# The outer opaque_type field of a TLSCiphertext record
     198                 :            :      *# is always set to the value 23 (application_data)
     199                 :            :      *
     200                 :            :      * Plaintext alerts are only valid during the handshake (e.g., if
     201                 :            :      * certificate validation fails before encryption is established).
     202                 :            :      * After the handshake completes, RFC 8446 Section 5.2 requires all
     203                 :            :      * records to be encrypted, so post-handshake alerts must arrive as
     204                 :            :      * APPLICATION_DATA records with an inner content type of ALERT.
     205                 :            :      *
     206                 :            :      * Accepting plaintext alerts post-handshake would allow an on-path
     207                 :            :      * attacker to flip the outer content_type of an encrypted record
     208                 :            :      * from APPLICATION_DATA (0x17) to ALERT (0x15), routing the raw
     209                 :            :      * AEAD ciphertext through the null cipher and into the alert parser.
     210                 :            :      * If the first two ciphertext bytes happen to form a close_notify
     211                 :            :      * (probability 1/256) or user_canceled (probability 1/256), the
     212                 :            :      * record is silently consumed — either as a fake shutdown or as a
     213                 :            :      * discarded warning — without incrementing the AEAD sequence number.
     214                 :            :      * This enables repeated, non-desynchronizing attempts at targeted
     215                 :            :      * connection kills or silent record drops.
     216                 :            :      */
     217 [ +  + ][ +  + ]:     177202 :     if (content_type == TLS_ALERT && !s2n_handshake_is_complete(conn)) {
     218                 :       1510 :         return true;
     219                 :       1510 :     }
     220                 :            : 
     221                 :            :     /*
     222                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-5
     223                 :            :      *# An implementation may receive an unencrypted record of type
     224                 :            :      *# change_cipher_spec consisting of the single byte value 0x01
     225                 :            :      *# at any time after the first ClientHello message has been
     226                 :            :      *# sent or received and before the peer's Finished message has
     227                 :            :      *# been received
     228                 :            :      *
     229                 :            :      * CCS is only valid during the handshake. Once the handshake is
     230                 :            :      * complete, a CCS record is a protocol violation and must not be
     231                 :            :      * routed through the plaintext path, as that would allow it to
     232                 :            :      * bypass the content_type validation in s2n_record_parse.
     233                 :            :      */
     234 [ +  + ][ +  + ]:     175692 :     if (content_type == TLS_CHANGE_CIPHER_SPEC && !s2n_handshake_is_complete(conn)) {
     235                 :      19378 :         return true;
     236                 :      19378 :     }
     237                 :            : 
     238                 :     156314 :     return false;
     239                 :     175692 : }
     240                 :            : 
     241                 :            : int s2n_record_parse(struct s2n_connection *conn)
     242                 :    3613741 : {
     243                 :    3613741 :     struct s2n_record_header header = { 0 };
     244         [ -  + ]:    3613741 :     POSIX_GUARD(s2n_record_header_parse(conn, &header));
     245                 :            : 
     246                 :    3613741 :     struct s2n_crypto_parameters *current_client_crypto = conn->client;
     247                 :    3613741 :     struct s2n_crypto_parameters *current_server_crypto = conn->server;
     248         [ +  + ]:    3613741 :     if (s2n_is_tls13_plaintext_content(conn, header.content_type)) {
     249 [ #  # ][ -  + ]:      10444 :         POSIX_ENSURE_REF(conn->initial);
     250                 :      10444 :         conn->client = conn->initial;
     251                 :      10444 :         conn->server = conn->initial;
     252                 :      10444 :     }
     253                 :            : 
     254                 :    3613741 :     const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
     255                 :    3613741 :     uint8_t *implicit_iv = conn->client->client_implicit_iv;
     256                 :    3613741 :     struct s2n_hmac_state *mac = &conn->client->client_record_mac;
     257                 :    3613741 :     uint8_t *sequence_number = conn->client->client_sequence_number;
     258                 :    3613741 :     struct s2n_session_key *session_key = &conn->client->client_key;
     259                 :            : 
     260         [ +  + ]:    3613741 :     if (conn->mode == S2N_CLIENT) {
     261                 :      95039 :         cipher_suite = conn->server->cipher_suite;
     262                 :      95039 :         implicit_iv = conn->server->server_implicit_iv;
     263                 :      95039 :         mac = &conn->server->server_record_mac;
     264                 :      95039 :         sequence_number = conn->server->server_sequence_number;
     265                 :      95039 :         session_key = &conn->server->server_key;
     266                 :      95039 :     }
     267                 :            : 
     268         [ +  + ]:    3613741 :     if (s2n_is_tls13_plaintext_content(conn, header.content_type)) {
     269                 :      10444 :         conn->client = current_client_crypto;
     270                 :      10444 :         conn->server = current_server_crypto;
     271                 :      10444 :     }
     272                 :            : 
     273                 :            :     /* The NULL stream cipher MUST NEVER be used for ApplicationData.
     274                 :            :      * If ApplicationData is unencrypted, we can't trust it. */
     275         [ +  + ]:    3613741 :     if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
     276 [ +  - ][ +  + ]:      77279 :         POSIX_ENSURE(header.content_type != TLS_APPLICATION_DATA, S2N_ERR_DECRYPT);
     277                 :      77279 :     }
     278                 :            : 
     279                 :            :     /*
     280                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-5.2
     281                 :            :      *# The outer opaque_type field of a TLSCiphertext record
     282                 :            :      *# is always set to the value 23 (application_data)
     283                 :            :      *
     284                 :            :      * For TLS 1.3 encrypted records, the outer content_type MUST be
     285                 :            :      * TLS_APPLICATION_DATA. The AEAD AAD hardcodes this value, so the
     286                 :            :      * outer byte is not covered by the authentication tag. Without this
     287                 :            :      * check, records with unrecognized content_type values would be
     288                 :            :      * discarded after decryption without surfacing an error, which
     289                 :            :      * violates the record integrity guarantees of TLS 1.3.
     290                 :            :      *
     291                 :            :      * This check only applies to encrypted records (non-null cipher).
     292                 :            :      * During the handshake, plaintext records with other content_types
     293                 :            :      * (HANDSHAKE, ALERT, CCS) are legitimate and handled by
     294                 :            :      * s2n_is_tls13_plaintext_content above.
     295                 :            :      */
     296         [ +  + ]:    3613288 :     if (conn->actual_protocol_version == S2N_TLS13
     297         [ +  + ]:    3613288 :             && cipher_suite->record_alg->cipher != &s2n_null_cipher) {
     298 [ +  + ][ +  - ]:      70055 :         POSIX_ENSURE(header.content_type == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
     299                 :      70055 :     }
     300                 :            : 
     301                 :    3613280 :     switch (cipher_suite->record_alg->cipher->type) {
     302         [ +  + ]:    3387030 :         case S2N_AEAD:
     303         [ +  + ]:    3387030 :             POSIX_GUARD(s2n_record_parse_aead(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
     304                 :     194489 :             break;
     305         [ +  + ]:     194489 :         case S2N_CBC:
     306         [ -  + ]:      41812 :             POSIX_GUARD(s2n_record_parse_cbc(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
     307                 :      41812 :             break;
     308         [ +  + ]:     107612 :         case S2N_COMPOSITE:
     309         [ -  + ]:     107612 :             POSIX_GUARD(s2n_record_parse_composite(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
     310                 :     107612 :             break;
     311         [ +  + ]:     107612 :         case S2N_STREAM:
     312         [ +  + ]:      76826 :             POSIX_GUARD(s2n_record_parse_stream(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
     313                 :      60648 :             break;
     314         [ -  + ]:      60648 :         default:
     315         [ #  # ]:          0 :             POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
     316                 :          0 :             break;
     317                 :    3613280 :     }
     318                 :            : 
     319                 :     404561 :     return 0;
     320                 :    3613280 : }
     321                 :            : 
     322                 :            : int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_type)
     323                 :      70003 : {
     324                 :      70003 :     uint32_t bytes_left = s2n_stuffer_data_available(stuffer);
     325                 :            : 
     326                 :            :     /* From rfc8446 Section 5.4
     327                 :            :      * The presence of padding does not change the overall record size
     328                 :            :      * limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
     329                 :            :      * + 1 octets
     330                 :            :      *
     331                 :            :      * Certain versions of Java can generate inner plaintexts with lengths up to
     332                 :            :      * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16 (See JDK-8221253)
     333                 :            :      * However, after the padding is stripped, the result will always be no more than
     334                 :            :      * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1
     335                 :            :      */
     336 [ +  + ][ +  - ]:      70003 :     S2N_ERROR_IF(bytes_left > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
     337                 :            : 
     338                 :            :     /* set cursor to the end of the stuffer */
     339         [ -  + ]:      70002 :     POSIX_GUARD(s2n_stuffer_skip_read(stuffer, bytes_left));
     340                 :            : 
     341                 :            :     /* Record type should have values greater than zero.
     342                 :            :      * If zero, treat as padding, keep reading and wiping from the back
     343                 :            :      * until a non-zero value is found
     344                 :            :      */
     345                 :      70002 :     *record_type = 0;
     346         [ +  + ]:     172821 :     while (*record_type == 0) {
     347                 :            :         /* back the cursor by one to read off the last byte */
     348         [ +  + ]:     102823 :         POSIX_GUARD(s2n_stuffer_rewind_read(stuffer, 1));
     349                 :            : 
     350                 :            :         /* set the record type */
     351         [ -  + ]:     102819 :         POSIX_GUARD(s2n_stuffer_read_uint8(stuffer, record_type));
     352                 :            : 
     353                 :            :         /* wipe the last byte at the end of the stuffer */
     354         [ -  + ]:     102819 :         POSIX_GUARD(s2n_stuffer_wipe_n(stuffer, 1));
     355                 :     102819 :     }
     356                 :            : 
     357                 :            :     /* only the original plaintext should remain */
     358                 :            :     /* now reset the read cursor at where it should be */
     359         [ -  + ]:      69998 :     POSIX_GUARD(s2n_stuffer_reread(stuffer));
     360                 :            : 
     361                 :            :     /* Even in the incorrect case above with up to 16 extra bytes, we should never see too much data after unpadding */
     362 [ +  + ][ +  - ]:      69998 :     S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
     363                 :            : 
     364                 :      69997 :     return 0;
     365                 :      69998 : }
     366                 :            : 
     367                 :            : S2N_RESULT s2n_record_wipe(struct s2n_connection *conn)
     368                 :     240945 : {
     369 [ -  + ][ #  # ]:     240945 :     RESULT_ENSURE_REF(conn);
     370         [ -  + ]:     240945 :     RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->header_in));
     371         [ -  + ]:     240945 :     RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->in));
     372                 :     240945 :     conn->in_status = ENCRYPTED;
     373                 :            : 
     374                 :            :     /* Release the memory in conn->in, which un-taints buffer_in */
     375         [ -  + ]:     240945 :     RESULT_GUARD_POSIX(s2n_stuffer_free(&conn->in));
     376                 :     240945 :     conn->buffer_in.tainted = false;
     377                 :            : 
     378                 :            :     /* Reclaim any memory in buffer_in if possible.
     379                 :            :      * We want to avoid an expensive shift / copy later if possible.
     380                 :            :      */
     381         [ +  + ]:     240945 :     if (s2n_stuffer_is_consumed(&conn->buffer_in)) {
     382         [ -  + ]:     240449 :         RESULT_GUARD_POSIX(s2n_stuffer_rewrite(&conn->buffer_in));
     383                 :     240449 :     }
     384                 :     240945 :     return S2N_RESULT_OK;
     385                 :     240945 : }

Generated by: LCOV version 1.14