in tls/s2n_record_read.c [166:224]
int s2n_record_parse(struct s2n_connection *conn)
{
uint8_t content_type = 0;
uint16_t encrypted_length = 0;
POSIX_GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length));
struct s2n_crypto_parameters *current_client_crypto = conn->client;
struct s2n_crypto_parameters *current_server_crypto = conn->server;
if (s2n_is_tls13_plaintext_content(conn, content_type)) {
POSIX_ENSURE_REF(conn->initial);
conn->client = conn->initial;
conn->server = conn->initial;
}
const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
uint8_t *implicit_iv = conn->client->client_implicit_iv;
struct s2n_hmac_state *mac = &conn->client->client_record_mac;
uint8_t *sequence_number = conn->client->client_sequence_number;
struct s2n_session_key *session_key = &conn->client->client_key;
if (conn->mode == S2N_CLIENT) {
cipher_suite = conn->server->cipher_suite;
implicit_iv = conn->server->server_implicit_iv;
mac = &conn->server->server_record_mac;
sequence_number = conn->server->server_sequence_number;
session_key = &conn->server->server_key;
}
if (s2n_is_tls13_plaintext_content(conn, content_type)) {
conn->client = current_client_crypto;
conn->server = current_server_crypto;
}
/* The NULL stream cipher MUST NEVER be used for ApplicationData.
* If ApplicationData is unencrypted, we can't trust it. */
if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
POSIX_ENSURE(content_type != TLS_APPLICATION_DATA, S2N_ERR_DECRYPT);
}
switch (cipher_suite->record_alg->cipher->type) {
case S2N_AEAD:
POSIX_GUARD(s2n_record_parse_aead(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
break;
case S2N_CBC:
POSIX_GUARD(s2n_record_parse_cbc(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
break;
case S2N_COMPOSITE:
POSIX_GUARD(s2n_record_parse_composite(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
break;
case S2N_STREAM:
POSIX_GUARD(s2n_record_parse_stream(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
break;
default:
POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
break;
}
return 0;
}