tls13: Introduce early_data_state SSL context field

Introduce early_data_state SSL context field to
distinguish better this internal state from
the status values defined for the
mbedtls_ssl_get_early_data_status() API.
Distinguish also between the client and
server states. Note that the client state
are going to be documented and reworked
as part of the implementation of
mbedtls_ssl_write_early_data().

Signed-off-by: Ronald Cron <ronald.cron@arm.com>
This commit is contained in:
Ronald Cron 2024-01-30 16:13:34 +01:00
parent 7d21cded3f
commit 0883b8b625
7 changed files with 74 additions and 66 deletions

View file

@ -1621,6 +1621,49 @@ struct mbedtls_ssl_config {
#endif #endif
}; };
#if defined(MBEDTLS_SSL_EARLY_DATA)
enum mbedtls_ssl_cli_early_data_state {
MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT,
MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED,
MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED
};
/*
* MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH:
* The server is waiting for the ClientHello.
*
* MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING:
* The server has received a ClientHello indicating early data and has
* accepted them. It is now expecting early data and the end of early
* data message.
*
* MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED:
* The server has received a ClientHello indicating early data and has
* rejected them.
*
* MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED:
* The server has received a ClientHello, no indication of early data.
*
* MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED
* The server has received the early data extension, it has accepted early
* data and received the end of early data message from the client marking
* the end of early data reception.
*/
enum mbedtls_ssl_srv_early_data_state {
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH,
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING,
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED,
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED,
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED
};
union mbedtls_ssl_early_data_state {
enum mbedtls_ssl_cli_early_data_state cli;
enum mbedtls_ssl_srv_early_data_state srv;
};
#endif /* MBEDTLS_SSL_EARLY_DATA */
struct mbedtls_ssl_context { struct mbedtls_ssl_context {
const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */ const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */
@ -1655,22 +1698,10 @@ struct mbedtls_ssl_context {
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
/** /**
* On client side, status of the negotiation of the use of early data. * State of the sending (client side) or reception (server side) of early
* See the documentation of mbedtls_ssl_get_early_data_status() for more * data. Reset to the initial state at the beginning of a new handshake.
* information.
*
* On server side, internal only, status of early data in the course of an
* handshake. One of MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN,
* #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED,
* #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED,
* MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED and
* MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED.
*
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or
* MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, at the beginning of a new
* handshake.
*/ */
int MBEDTLS_PRIVATE(early_data_status); union mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state);
#endif #endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */

View file

@ -49,6 +49,11 @@ void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
unsigned int flags); unsigned int flags);
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ #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) \ #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \
mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \ mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \
hs_msg_type, extensions_mask, NULL) hs_msg_type, extensions_mask, NULL)

View file

@ -2130,30 +2130,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
const unsigned char *end, const unsigned char *end,
size_t *out_len); size_t *out_len);
#if defined(MBEDTLS_SSL_SRV_C)
/* Additional internal early data status, server side only. */
/*
* The server has not received the ClientHello yet, the status of early data
* is thus unknown.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN \
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
/*
* The server has received the ClientHello, it contained no early data
* extension.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED 3
/*
* The server has received the early data extension, it has accepted early
* data and received the end of early data message from the client marking the
* end of early data reception.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED 4
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -5888,8 +5888,10 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
} }
if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) && if ((ssl->early_data_state.srv !=
(ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH) &&
(ssl->early_data_state.srv !=
MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
} }

View file

@ -1099,13 +1099,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_SRV_C) ssl->early_data_state.cli = 0;
MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN == 0,
"MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN not equal to 0");
#endif
MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT == 0,
"MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT not equal to 0");
ssl->early_data_status = 0;
#endif #endif
/* Initialize structures */ /* Initialize structures */

View file

@ -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 * `accepted` if the EncryptedExtension message contain an early data
* indication extension. * 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 { } else {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension")); 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 */ #endif /* MBEDTLS_SSL_EARLY_DATA */
@ -1235,7 +1235,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
size_t psk_len; size_t psk_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; 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( MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk")); 1, ("Set hs psk for early data when writing the first psk"));
@ -1916,7 +1916,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
* cases we compute it here. * cases we compute it here.
*/ */
#if defined(MBEDTLS_SSL_EARLY_DATA) #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 == handshake->key_exchange_mode ==
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
#endif #endif
@ -2228,7 +2228,7 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 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 #endif
@ -2565,9 +2565,9 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #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); 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); mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
} else } else
#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_EARLY_DATA */

View file

@ -1780,7 +1780,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #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) int hrr_required)
{ {
mbedtls_ssl_handshake_params *handshake = ssl->handshake; mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@ -1789,11 +1789,11 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) { MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received.")); 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; 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) { if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
@ -1856,7 +1856,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl,
return; 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 */ #endif /* MBEDTLS_SSL_EARLY_DATA */
@ -1890,9 +1890,9 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data status. */ /* There is enough information, update early data status. */
ssl_tls13_update_early_data_status(ssl, hrr_required); 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); ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) { if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET( MBEDTLS_SSL_DEBUG_RET(
@ -2541,7 +2541,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */ #endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA) #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( ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len); ssl, 0, p, end, &output_len);
if (ret != 0) { if (ret != 0) {
@ -2868,7 +2868,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
} }
#if defined(MBEDTLS_SSL_EARLY_DATA) #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 */ /* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. " 1, ("Switch to early keys for inbound traffic. "
@ -3011,8 +3011,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data(
ssl, buf, buf + buf_len)); ssl, buf, buf + buf_len));
ssl->early_data_status = ssl->early_data_state.srv =
MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED; MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED;
MBEDTLS_SSL_DEBUG_MSG( MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to handshake keys for inbound traffic" 1, ("Switch to handshake keys for inbound traffic"