Skip to content

Commit

Permalink
use trial decryption if server rejects client 0-RTT attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
jesiegel1 committed Dec 23, 2021
1 parent e07a165 commit ae02c5e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
3 changes: 3 additions & 0 deletions library/ssl_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,9 @@ struct mbedtls_ssl_handshake_params
1 -- MBEDTLS_SSL_EARLY_DATA_ENABLED (for use early data)
*/
int early_data;
#if defined(MBEDTLS_SSL_SRV_C)
int skip_failed_decryption;
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_ZERO_RTT */

#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Expand Down
68 changes: 62 additions & 6 deletions library/ssl_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3957,10 +3957,21 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
return( ret );
}

if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
update_hs_digest == 1 )
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
{
mbedtls_ssl_update_handshake_status( ssl );
if( update_hs_digest == 1)
mbedtls_ssl_update_handshake_status( ssl );

#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_ZERO_RTT)
if( ssl->handshake != NULL &&
ssl->handshake->skip_failed_decryption != 0 &&
ssl->transform_in != NULL )
{
/* Record deprotected successfully */
ssl->handshake->skip_failed_decryption = 0;
MBEDTLS_SSL_DEBUG_MSG( 4, ( "disabling skip_failed_decryption" ) );
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_ZERO_RTT */
}
}
else
Expand Down Expand Up @@ -4554,6 +4565,41 @@ static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,

#endif /* MBEDTLS_SSL_PROTO_DTLS */

/*
* RFC 8446:
* "If the client attempts a 0-RTT handshake but the server
* rejects it, the server will generally not have the 0-RTT record
* protection keys and must instead use trial decryption (either with
* the 1-RTT handshake keys or by looking for a cleartext ClientHello in
* the case of a HelloRetryRequest) to find the first non-0-RTT message."
*/
#if defined(MBEDTLS_SSL_SRV_C)
static int ssl_should_drop_record( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_ZERO_RTT) && !defined(MBEDTLS_SSL_USE_MPS)
if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER || ssl->handshake == NULL )
return( 0 );

/*
* Drop record iff:
* 1. Client indicated early data use (skip_failed_decryption).
* 2. Server does not have early data enabled (skip_failed_decryption).
* 3. First non-0-RTT record has not yet been found (skip_failed_decryption).
* 4. 1-RTT handshake keys are in use.
*/
if( ssl->handshake->skip_failed_decryption == 1 &&
ssl->transform_in == ssl->handshake->transform_handshake )
{
return( 1 );
}

#endif /* MBEDTLS_ZERO_RTT && !MBEDTLS_SSL_USE_MPS */
((void) ssl);

return( 0 );
}
#endif /* MBEDTLS_SSL_SRV_C */

static int ssl_get_next_record( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Expand Down Expand Up @@ -4722,15 +4768,25 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl )
else
#endif
{
/* Error out (and send alert) on invalid records */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
{
#if defined(MBEDTLS_SSL_SRV_C)
if( ssl->handshake != NULL &&
ssl_should_drop_record( ssl ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid record (mac), dropping 0-RTT message" ) );
return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
}
#endif /* MBEDTLS_SSL_SRV_C */

/* Error out (and send alert) on invalid records */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
mbedtls_ssl_send_alert_message( ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
}
#endif

return( ret );
}
}
Expand Down
1 change: 1 addition & 0 deletions library/ssl_tls13_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,7 @@ int mbedtls_ssl_write_early_data_ext( mbedtls_ssl_context *ssl,
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write early_data extension" ) );
ssl->handshake->early_data = MBEDTLS_SSL_EARLY_DATA_OFF;
ssl->handshake->skip_failed_decryption = 1;
return( 0 );
}
}
Expand Down
3 changes: 3 additions & 0 deletions library/ssl_tls13_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2768,6 +2768,9 @@ static int ssl_client_hello_postprocess( mbedtls_ssl_context* ssl,
int ret = 0;
#if defined(MBEDTLS_ZERO_RTT)
mbedtls_ssl_key_set traffic_keys;

if( ssl->handshake->hello_retry_requests_sent == 1 )
ssl->handshake->skip_failed_decryption = 0;
#endif /* MBEDTLS_ZERO_RTT */

if( ssl->handshake->hello_retry_requests_sent == 0 &&
Expand Down
13 changes: 13 additions & 0 deletions tests/ssl-opt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2445,6 +2445,19 @@ run_test "TLS 1.3, TLS1-3-AES-256-GCM-SHA384, ext PSK, early data status - no
0 \
-c "early data status = 0" \

# test early data status - rejected
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_config_enabled MBEDTLS_ZERO_RTT
requires_config_disabled MBEDTLS_SSL_USE_MPS
run_test "TLS 1.3, TLS1-3-AES-256-GCM-SHA384, ext PSK, early data status - rejected" \
"$P_SRV nbio=2 debug_level=5 force_version=tls1_3 early_data=0 tls13_kex_modes=psk psk=010203 psk_identity=0a0b0c" \
"$P_CLI nbio=2 debug_level=5 force_version=tls1_3 force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 tls13_kex_modes=psk early_data=1 psk=010203 psk_identity=0a0b0c" \
0 \
-c "early data status = 1" \

# test early data status - accepted
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
requires_config_enabled MBEDTLS_DEBUG_C
Expand Down

0 comments on commit ae02c5e

Please sign in to comment.