mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-30 05:14:15 +01:00
Add counter-measure to cache-based Lucky 13
The basis for the Lucky 13 family of attacks is for an attacker to be able to distinguish between (long) valid TLS-CBC padding and invalid TLS-CBC padding. Since our code sets padlen = 0 for invalid padding, the length of the input to the HMAC function, and the location where we read the MAC, give information about that. A local attacker could gain information about that by observing via a cache attack whether the bytes at the end of the record (at the location of would-be padding) have been read during MAC verification (computation + comparison). Let's make sure they're always read.
This commit is contained in:
parent
69675d056a
commit
99b6a711c8
@ -23,6 +23,14 @@ Security
|
|||||||
a cache attack targetting an internal MD/SHA buffer. Connections using
|
a cache attack targetting an internal MD/SHA buffer. Connections using
|
||||||
GCM or CCM instead of CBC or using Encrypt-then-Mac (RFC 7366) were not
|
GCM or CCM instead of CBC or using Encrypt-then-Mac (RFC 7366) were not
|
||||||
affected. Found by Kenny Paterson, Eyal Ronen and Adi Shamir.
|
affected. Found by Kenny Paterson, Eyal Ronen and Adi Shamir.
|
||||||
|
* Add a counter-measure against a vulnerability in TLS ciphersuites based
|
||||||
|
on CBC, in (D)TLS 1.0 to 1.2, that allowed a local attacker, able to
|
||||||
|
execute code on the local machine as well as manipulate network packets,
|
||||||
|
to partially recover the plaintext of messages under some conditions (see
|
||||||
|
previous entry) by using a cache attack targeting the SSL input record
|
||||||
|
buffer. Connections using GCM or CCM instead of CBC or using
|
||||||
|
Encrypt-then-Mac (RFC 7366) were not affected. Found by Kenny Paterson,
|
||||||
|
Eyal Ronen and Adi Shamir.
|
||||||
|
|
||||||
Bugfix
|
Bugfix
|
||||||
* Fix braces in mbedtls_memory_buffer_alloc_status(). Found by sbranden, #552.
|
* Fix braces in mbedtls_memory_buffer_alloc_status(). Found by sbranden, #552.
|
||||||
|
@ -1257,6 +1257,27 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx,
|
|||||||
#define SSL_SOME_MODES_USE_MAC
|
#define SSL_SOME_MODES_USE_MAC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The function below is only used in the Lucky 13 counter-measure in
|
||||||
|
* ssl_decrypt_buf(). These are the defines that guard the call site. */
|
||||||
|
#if defined(SSL_SOME_MODES_USE_MAC) && \
|
||||||
|
( defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||||
|
defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||||
|
defined(MBEDTLS_SSL_PROTO_TLS1_2) )
|
||||||
|
/* This function makes sure every byte in the memory region is accessed
|
||||||
|
* (in ascending addresses order) */
|
||||||
|
static void ssl_read_memory( unsigned char *p, size_t len )
|
||||||
|
{
|
||||||
|
unsigned char acc = 0;
|
||||||
|
volatile unsigned char force;
|
||||||
|
|
||||||
|
for( ; len != 0; p++, len-- )
|
||||||
|
acc ^= *p;
|
||||||
|
|
||||||
|
force = acc;
|
||||||
|
(void) force;
|
||||||
|
}
|
||||||
|
#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encryption/decryption functions
|
* Encryption/decryption functions
|
||||||
*/
|
*/
|
||||||
@ -1992,6 +2013,20 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|||||||
* linking an extra division function in some builds).
|
* linking an extra division function in some builds).
|
||||||
*/
|
*/
|
||||||
size_t j, extra_run = 0;
|
size_t j, extra_run = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next two sizes are the minimum and maximum values of
|
||||||
|
* in_msglen over all padlen values.
|
||||||
|
*
|
||||||
|
* They're independent of padlen, since we previously did
|
||||||
|
* in_msglen -= padlen.
|
||||||
|
*
|
||||||
|
* Note that max_len + maclen is never more than the buffer
|
||||||
|
* length, as we previously did in_msglen -= maclen too.
|
||||||
|
*/
|
||||||
|
const size_t max_len = ssl->in_msglen + padlen;
|
||||||
|
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
|
||||||
|
|
||||||
switch( ssl->transform_in->ciphersuite_info->mac )
|
switch( ssl->transform_in->ciphersuite_info->mac )
|
||||||
{
|
{
|
||||||
#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
|
#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
|
||||||
@ -2023,12 +2058,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|||||||
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
|
||||||
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
|
||||||
ssl->in_msglen );
|
ssl->in_msglen );
|
||||||
|
/* Make sure we access everything even when padlen > 0. This
|
||||||
|
* makes the synchronisation requirements for just-in-time
|
||||||
|
* Prime+Probe attacks much tighter and hopefully impractical. */
|
||||||
|
ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen );
|
||||||
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
|
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
|
||||||
/* Call mbedtls_md_process at least once due to cache attacks */
|
|
||||||
|
/* Call mbedtls_md_process at least once due to cache attacks
|
||||||
|
* that observe whether md_process() was called of not */
|
||||||
for( j = 0; j < extra_run + 1; j++ )
|
for( j = 0; j < extra_run + 1; j++ )
|
||||||
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
|
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
|
||||||
|
|
||||||
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
|
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
|
||||||
|
|
||||||
|
/* Make sure we access all the memory that could contain the MAC,
|
||||||
|
* before we check it in the next code block. This makes the
|
||||||
|
* synchronisation requirements for just-in-time Prime+Probe
|
||||||
|
* attacks much tighter and hopefully impractical. */
|
||||||
|
ssl_read_memory( ssl->in_msg + min_len,
|
||||||
|
max_len - min_len + ssl->transform_in->maclen );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
||||||
@ -2038,9 +2086,11 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|||||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
||||||
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
|
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
|
||||||
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
|
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
|
||||||
ssl->transform_in->maclen );
|
ssl->transform_in->maclen );
|
||||||
|
#endif
|
||||||
|
|
||||||
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
|
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
|
||||||
ssl->transform_in->maclen ) != 0 )
|
ssl->transform_in->maclen ) != 0 )
|
||||||
|
Loading…
Reference in New Issue
Block a user