Fix integer overflows in buffer bound checks

Fix potential integer overflows in the following functions:
  * mbedtls_md2_update() to be bypassed and cause
  * mbedtls_cipher_update()
  * mbedtls_ctr_drbg_reseed()
This overflows would mainly be exploitable in 32-bit systems and could
cause buffer bound checks to be bypassed.
This commit is contained in:
Andres Amaya Garcia 2017-01-17 23:04:22 +00:00 committed by Simon Butcher
parent 49d29337fa
commit 6a54336897
5 changed files with 16 additions and 4 deletions

View File

@ -21,6 +21,12 @@ Bugfix
* Fixed multiple buffer overreads in mbedtls_pem_read_buffer() when parsing * Fixed multiple buffer overreads in mbedtls_pem_read_buffer() when parsing
the input string in PEM format to extract the different components. Found the input string in PEM format to extract the different components. Found
by Eyal Itkin. by Eyal Itkin.
* Fixed potential arithmetic overflow in mbedtls_ctr_drbg_reseed() that could
cause buffer bound checks to be bypassed. Found by Eyal Itkin.
* Fixed potential arithmetic overflows in mbedtls_cipher_update() that could
cause buffer bound checks to be bypassed. Found by Eyal Itkin.
* Fixed potential arithmetic overflow in mbedtls_md2_update() that could
cause buffer bound checks to be bypassed. Found by Eyal Itkin.
= mbed TLS 2.4.1 branch released 2016-12-13 = mbed TLS 2.4.1 branch released 2016-12-13

View File

@ -326,9 +326,9 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
* If there is not enough data for a full block, cache it. * If there is not enough data for a full block, cache it.
*/ */
if( ( ctx->operation == MBEDTLS_DECRYPT && if( ( ctx->operation == MBEDTLS_DECRYPT &&
ilen + ctx->unprocessed_len <= block_size ) || ilen <= block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_ENCRYPT && ( ctx->operation == MBEDTLS_ENCRYPT &&
ilen + ctx->unprocessed_len < block_size ) ) ilen < block_size - ctx->unprocessed_len ) )
{ {
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
ilen ); ilen );

View File

@ -290,7 +290,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0; size_t seedlen = 0;
if( ctx->entropy_len + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );

View File

@ -158,7 +158,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s
while( ilen > 0 ) while( ilen > 0 )
{ {
if( ctx->left + ilen > 16 ) if( ilen > 16 - ctx->left )
fill = 16 - ctx->left; fill = 16 - ctx->left;
else else
fill = ilen; fill = ilen;

View File

@ -39,6 +39,11 @@ void ctr_drbg_special_behaviours( )
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional, TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) == MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
exit: exit:
mbedtls_ctr_drbg_free( &ctx ); mbedtls_ctr_drbg_free( &ctx );
} }