Skip to content

Commit

Permalink
Merge pull request #6720 from yuhaoth/pr/tls13-early-data-receive-0_r…
Browse files Browse the repository at this point in the history
…tt-and-eoed

TLS 1.3: EarlyData SRV: Write early data extension  in EncryptedExtension
  • Loading branch information
tom-cosgrove-arm authored Nov 7, 2023
2 parents 4122c16 + 7ef9fd8 commit 53199b1
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 33 deletions.
66 changes: 34 additions & 32 deletions library/ssl_tls13_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1892,36 +1892,6 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
goto cleanup;
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA) &&
(handshake->selected_identity != 0 ||
handshake->ciphersuite_info->id !=
ssl->session_negotiate->ciphersuite)) {
/* RFC8446 4.2.11
* If the server supplies an "early_data" extension, the
* client MUST verify that the server's selected_identity
* is 0. If any other value is returned, the client MUST
* abort the handshake with an "illegal_parameter" alert.
*
* RFC 8446 4.2.10
* In order to accept early data, the server MUST have accepted a PSK
* cipher suite and selected the first key offered in the client's
* "pre_shared_key" extension. In addition, it MUST verify that the
* following values are the same as those associated with the
* selected PSK:
* - The TLS version number
* - The selected cipher suite
* - The selected ALPN [RFC7301] protocol, if any
*
* We check here that when early data is involved the server
* selected the cipher suite associated to the pre-shared key
* as it must have.
*/
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
#endif

if (!mbedtls_ssl_conf_tls13_check_kex_modes(
ssl, handshake->key_exchange_mode)) {
Expand Down Expand Up @@ -2197,6 +2167,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
int ret;
unsigned char *buf;
size_t buf_len;
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
#endif

MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));

Expand All @@ -2209,8 +2182,37 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
ssl_tls13_parse_encrypted_extensions(ssl, buf, buf + buf_len));

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) {
if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) {
/* RFC8446 4.2.11
* If the server supplies an "early_data" extension, the
* client MUST verify that the server's selected_identity
* is 0. If any other value is returned, the client MUST
* abort the handshake with an "illegal_parameter" alert.
*
* RFC 8446 4.2.10
* In order to accept early data, the server MUST have accepted a PSK
* cipher suite and selected the first key offered in the client's
* "pre_shared_key" extension. In addition, it MUST verify that the
* following values are the same as those associated with the
* selected PSK:
* - The TLS version number
* - The selected cipher suite
* - The selected ALPN [RFC7301] protocol, if any
*
* We check here that when early data is involved the server
* selected the cipher suite associated to the pre-shared key
* as it must have.
*/
if (handshake->selected_identity != 0 ||
handshake->ciphersuite_info->id !=
ssl->session_negotiate->ciphersuite) {

MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}

ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
}
#endif
Expand Down
68 changes: 67 additions & 1 deletion library/ssl_tls13_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
/* We delete the temporary buffer */
mbedtls_free(ticket_buffer);

if (ret == 0 && session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
/* TODO: Define new return value for this case. */
ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
}

if (ret != 0) {
goto exit;
}
Expand Down Expand Up @@ -1784,9 +1790,59 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
return;
}

/* We do not accept early data for the time being */
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;

if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, feature disabled in server configuration."));
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
resumption. */
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption."));
return;
}

/* RFC 8446 4.2.10
*
* In order to accept early data, the server MUST have accepted a PSK cipher
* suite and selected the first key offered in the client's "pre_shared_key"
* extension. In addition, it MUST verify that the following values are the
* same as those associated with the selected PSK:
* - The TLS version number
* - The selected cipher suite
* - The selected ALPN [RFC7301] protocol, if any
*
* NOTE:
* - The TLS version number is checked in
* ssl_tls13_offered_psks_check_identity_match_ticket().
* - ALPN is not checked for the time being (TODO).
*/

if (handshake->selected_identity != 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one."));
return;
}

if (handshake->ciphersuite_info->id !=
ssl->session_negotiate->ciphersuite) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key."));
return;

}


ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;

}
#endif /* MBEDTLS_SSL_EARLY_DATA */

Expand Down Expand Up @@ -2446,6 +2502,16 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
p += output_len;
#endif /* MBEDTLS_SSL_ALPN */

#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
ret = mbedtls_ssl_tls13_write_early_data_ext(ssl, p, end, &output_len);
if (ret != 0) {
return ret;
}
p += output_len;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

extensions_len = (p - p_extensions_len) - 2;
MBEDTLS_PUT_UINT16_BE(extensions_len, p_extensions_len, 0);

Expand Down
20 changes: 20 additions & 0 deletions tests/opt-testcases/tls13-misc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,9 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \
-s "found matched identity" \
-s "key exchange mode: psk_ephemeral"

EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 ))
EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 ))

requires_gnutls_next
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
Expand All @@ -500,3 +503,20 @@ run_test "TLS 1.3 G->m: EarlyData: feature is disabled, fail." \
-s "EncryptedExtensions: early_data(42) extension does not exist." \
-s "NewSessionTicket: early_data(42) extension does not exist." \
-s "Last error was: -29056 - SSL - Verification of the message MAC failed"

requires_gnutls_next
requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
run_test "TLS 1.3 G->m: EarlyData: feature is enabled, fail." \
"$P_SRV force_version=tls13 debug_level=4 max_early_data_size=$EARLY_DATA_INPUT_LEN" \
"$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \
-d 10 -r --earlydata $EARLY_DATA_INPUT " \
1 \
-s "ClientHello: early_data(42) extension exists." \
-s "EncryptedExtensions: early_data(42) extension exists." \
-s "NewSessionTicket: early_data(42) extension does not exist." \
-s "Last error was: -29056 - SSL - Verification of the message MAC failed"

0 comments on commit 53199b1

Please sign in to comment.