ssl_tls13_client: Add downgrade attack protection
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
This commit is contained in:
parent
217d699d85
commit
fd6193c285
@ -711,6 +711,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
/*
|
||||
* Functions for parsing and processing Server Hello
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Detect if the ServerHello contains a supported_versions extension
|
||||
* or not.
|
||||
@ -792,6 +793,36 @@ static int ssl_tls13_is_supported_versions_ext_present(
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Returns a negative value on failure, and otherwise
|
||||
* - 1 if the last eight bytes of the ServerHello random bytes indicate that
|
||||
* the server is TLS 1.3 capable but negotiating TLS 1.2 or below.
|
||||
* - 0 otherwise
|
||||
*/
|
||||
static int ssl_tls13_is_downgrade_negotiation( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
/* First seven bytes of the magic downgrade strings, see RFC 8446 4.1.3 */
|
||||
static const unsigned char magic_downgrade_string[] =
|
||||
{ 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44 };
|
||||
const unsigned char *last_eight_bytes_of_random;
|
||||
unsigned char last_byte_of_random;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2 );
|
||||
last_eight_bytes_of_random = buf + 2 + MBEDTLS_SERVER_HELLO_RANDOM_LEN - 8;
|
||||
|
||||
if( memcmp( last_eight_bytes_of_random,
|
||||
magic_downgrade_string,
|
||||
sizeof( magic_downgrade_string ) ) == 0 )
|
||||
{
|
||||
last_byte_of_random = last_eight_bytes_of_random[7];
|
||||
return( last_byte_of_random == 0 ||
|
||||
last_byte_of_random == 1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Returns a negative value on failure, and otherwise
|
||||
* - SSL_SERVER_HELLO_COORDINATE_HELLO or
|
||||
* - SSL_SERVER_HELLO_COORDINATE_HRR
|
||||
@ -846,20 +877,27 @@ static int ssl_tls13_server_hello_coordinate( mbedtls_ssl_context *ssl,
|
||||
size_t *buf_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned char *end;
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_fetch_handshake_msg( ssl,
|
||||
MBEDTLS_SSL_HS_SERVER_HELLO,
|
||||
buf, buf_len ) );
|
||||
end = *buf + *buf_len;
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK_NEG( ssl_tls13_is_supported_versions_ext_present(
|
||||
ssl, *buf, *buf + *buf_len ) );
|
||||
ssl, *buf, end ) );
|
||||
if( ret == 0 )
|
||||
{
|
||||
/* If the supported versions extension is not present but we were
|
||||
* expecting it, abort the handshake. Otherwise, switch to TLS 1.2
|
||||
* handshake.
|
||||
MBEDTLS_SSL_PROC_CHK_NEG(
|
||||
ssl_tls13_is_downgrade_negotiation( ssl, *buf, end ) );
|
||||
|
||||
/* If the server is negotiating TLS 1.2 or below and:
|
||||
* . we did not propose TLS 1.2 or
|
||||
* . the server responded it is TLS 1.3 capable but negotiating a lower
|
||||
* version of the protocol and thus we are under downgrade attack
|
||||
* abort the handshake with an "illegal parameter" alert.
|
||||
*/
|
||||
if( ssl->handshake->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 )
|
||||
if( ssl->handshake->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 || ret )
|
||||
{
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
@ -881,7 +919,7 @@ static int ssl_tls13_server_hello_coordinate( mbedtls_ssl_context *ssl,
|
||||
return( SSL_SERVER_HELLO_COORDINATE_TLS1_2 );
|
||||
}
|
||||
|
||||
ret = ssl_server_hello_is_hrr( ssl, *buf, *buf + *buf_len );
|
||||
ret = ssl_server_hello_is_hrr( ssl, *buf, end );
|
||||
switch( ret )
|
||||
{
|
||||
case SSL_SERVER_HELLO_COORDINATE_HELLO:
|
||||
|
Loading…
Reference in New Issue
Block a user