Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 151 additions & 61 deletions include/mbedtls/ssl.h

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions library/ssl_debug_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
unsigned int flags);
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */

#if defined(MBEDTLS_SSL_EARLY_DATA)
const char *mbedtls_ssl_cli_early_data_state_str(enum mbedtls_ssl_cli_early_data_state in);
const char *mbedtls_ssl_srv_early_data_state_str(enum mbedtls_ssl_srv_early_data_state in);
#endif

#define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \
mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \
hs_msg_type, extensions_mask, NULL)
Expand Down
6 changes: 0 additions & 6 deletions library/ssl_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2130,12 +2130,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len);

#if defined(MBEDTLS_SSL_SRV_C)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
#endif /* MBEDTLS_SSL_SRV_C */

#endif /* MBEDTLS_SSL_EARLY_DATA */

#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
Expand Down
81 changes: 62 additions & 19 deletions library/ssl_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5647,13 +5647,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}

/*
* brief Read at most 'len' application data bytes from the input
* buffer.
*
* param ssl SSL context:
* - First byte of application data not read yet in the input
* buffer located at address `in_offt`.
* - The number of bytes of data not read yet is `in_msglen`.
* param buf buffer that will hold the data
* param len maximum number of bytes to read
*
* note The function updates the fields `in_offt` and `in_msglen`
* according to the number of bytes read.
*
* return The number of bytes read.
*/
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;

if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}

/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);

if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}

return (int) n;
}

/*
* Receive application data decrypted from the SSL layer
*/
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;

if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Expand Down Expand Up @@ -5817,31 +5858,33 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
#endif /* MBEDTLS_SSL_PROTO_DTLS */
}

n = (len < ssl->in_msglen)
? len : ssl->in_msglen;
ret = ssl_read_application_data(ssl, buf, len);

if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));

/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
return ret;
}

if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
{
if (ssl == NULL || (ssl->conf == NULL)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}

MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
/*
* The server may receive early data only while waiting for the End of
* Early Data handshake message.
*/
if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
(ssl->in_offt == NULL)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
}

return (int) n;
return ssl_read_application_data(ssl, buf, len);
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */

/*
* Send application data to be encrypted by the SSL layer, taking care of max
Expand Down
4 changes: 4 additions & 0 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,10 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
ssl->early_data_state.cli = 0;
#endif

/* Initialize structures */
mbedtls_ssl_session_init(ssl->session_negotiate);
ssl_handshake_params_init(ssl->handshake);
Expand Down
14 changes: 7 additions & 7 deletions library/ssl_tls13_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,10 +1195,10 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
* `accepted` if the EncryptedExtension message contain an early data
* indication extension.
*/
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED;
} else {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension"));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

Expand Down Expand Up @@ -1235,7 +1235,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
size_t psk_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;

if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));

Expand Down Expand Up @@ -1916,7 +1916,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
* cases we compute it here.
*/
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT ||
if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT ||
handshake->key_exchange_mode ==
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
#endif
Expand Down Expand Up @@ -2228,7 +2228,7 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}

ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED;
}
#endif

Expand Down Expand Up @@ -2565,9 +2565,9 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
} else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
} else if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
} else
#endif /* MBEDTLS_SSL_EARLY_DATA */
Expand Down
81 changes: 38 additions & 43 deletions library/ssl_tls13_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1780,19 +1780,20 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
static void ssl_tls13_update_early_data_state(mbedtls_ssl_context *ssl,
int hrr_required)
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;

if ((handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received."));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED;
ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED;
return;
}

ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED;

if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
Expand All @@ -1801,6 +1802,11 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
return;
}

if (hrr_required) {
MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required."));
return;
}

if (!handshake->resume) {
/* We currently support early data only in the case of PSKs established
via a NewSessionTicket message thus in the case of a session
Expand Down Expand Up @@ -1850,15 +1856,16 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
return;
}

ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING;

}
#endif /* MBEDTLS_SSL_EARLY_DATA */

/* Update the handshake state machine */

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

Expand All @@ -1882,17 +1889,19 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data state. */
ssl_tls13_update_early_data_status(ssl);
/* There is enough information, update early data status. */
ssl_tls13_update_early_data_state(ssl, hrr_required);

if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_compute_early_transform", ret);
return ret;
}
}
#else
((void) hrr_required);
#endif /* MBEDTLS_SSL_EARLY_DATA */

return 0;
Expand Down Expand Up @@ -1947,7 +1956,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
return 0;
}

MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl));
MBEDTLS_SSL_PROC_CHK(
ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret ==
SSL_CLIENT_HELLO_HRR_REQUIRED));

if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
Expand Down Expand Up @@ -2530,7 +2541,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len);
if (ret != 0) {
Expand Down Expand Up @@ -2857,7 +2868,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) {
/* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. "
Expand Down Expand Up @@ -2911,6 +2922,17 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)

if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
if (ssl->in_offt == NULL) {
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
}
return SSL_GOT_EARLY_DATA;
}

Expand All @@ -2936,37 +2958,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
return 0;
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
return ret;
}

/*
* Output early data
*
* For the time being, we print received data via debug message.
*
* TODO: Remove it when `mbedtls_ssl_read_early_data` is ready.
*/
ssl->in_msg[ssl->in_msglen] = 0;
MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg));

/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/

return 0;
}

/*
* RFC 8446 section A.2
*
Expand Down Expand Up @@ -3024,6 +3015,9 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data(
ssl, buf, buf + buf_len));

ssl->early_data_state.srv =
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED;

MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to handshake keys for inbound traffic"
"( K_recv = handshake )"));
Expand All @@ -3037,7 +3031,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
ssl_tls13_prepare_for_handshake_second_flight(ssl);

} else if (ret == SSL_GOT_EARLY_DATA) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl));
ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Expand Down
Loading