Merge remote-tracking branch 'upstream-restricted/pr/387' into mbedtls-1.3-restricted

This commit is contained in:
Gilles Peskine 2017-11-28 14:34:16 +01:00
commit d3dd8d2197
16 changed files with 122 additions and 84 deletions

View file

@ -11,6 +11,8 @@ Security
* Fix unsafe bounds check in ssl_parse_client_psk_identity() when adding * Fix unsafe bounds check in ssl_parse_client_psk_identity() when adding
64kB to the address of the SSL buffer wraps around. 64kB to the address of the SSL buffer wraps around.
* Tighten should-be-constant-time memcmp against compiler optimizations. * Tighten should-be-constant-time memcmp against compiler optimizations.
* Ensure that buffers are cleared after use if they contain sensitive data.
Changes were introduced in multiple places in the library.
Bugfix Bugfix
* Fix memory leak in ssl_set_hostname() when called multiple times. * Fix memory leak in ssl_set_hostname() when called multiple times.

View file

@ -1880,6 +1880,8 @@ int mpi_fill_random( mpi *X, size_t size,
MPI_CHK( mpi_read_binary( X, buf, size ) ); MPI_CHK( mpi_read_binary( X, buf, size ) );
cleanup: cleanup:
polarssl_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }

View file

@ -402,20 +402,20 @@ int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
goto exit; goto exit;
if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT ) if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
{
ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR; ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR;
goto exit; else
} ret = 0;
ret = 0;
exit: exit:
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( ret ); return( ret );
} }
int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ) int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ CTR_DRBG_MAX_INPUT ]; unsigned char buf[ CTR_DRBG_MAX_INPUT ];
@ -434,14 +434,16 @@ int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
} }
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); ctr_drbg_update( ctx, buf, n );
}
fclose( f ); fclose( f );
ctr_drbg_update( ctx, buf, n ); polarssl_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( ctr_drbg_write_seed_file( ctx, path ) ); return( ctr_drbg_write_seed_file( ctx, path ) );
} }

View file

@ -532,7 +532,10 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
if( fread( *buf, 1, *n, f ) != *n ) if( fread( *buf, 1, *n, f ) != *n )
{ {
fclose( f ); fclose( f );
polarssl_zeroize( *buf, *n + 1 );
polarssl_free( *buf ); polarssl_free( *buf );
return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); return( POLARSSL_ERR_DHM_FILE_IO_ERROR );
} }

View file

@ -166,6 +166,8 @@ static int entropy_update( entropy_context *ctx, unsigned char source_id,
sha256_update( &ctx->accumulator, p, use_len ); sha256_update( &ctx->accumulator, p, use_len );
#endif #endif
polarssl_zeroize( tmp, sizeof( tmp ) );
return( 0 ); return( 0 );
} }
@ -194,13 +196,11 @@ int entropy_update_manual( entropy_context *ctx,
*/ */
static int entropy_gather_internal( entropy_context *ctx ) static int entropy_gather_internal( entropy_context *ctx )
{ {
int ret, i; int ret = POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED;
int i;
unsigned char buf[ENTROPY_MAX_GATHER]; unsigned char buf[ENTROPY_MAX_GATHER];
size_t olen; size_t olen;
if( ctx->source_count == 0 )
return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED );
/* /*
* Run through our entropy sources * Run through our entropy sources
*/ */
@ -210,7 +210,7 @@ static int entropy_gather_internal( entropy_context *ctx )
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 ) buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 )
{ {
return( ret ); goto cleanup;
} }
/* /*
@ -223,7 +223,10 @@ static int entropy_gather_internal( entropy_context *ctx )
} }
} }
return( 0 ); cleanup:
polarssl_zeroize( buf, sizeof( buf ) );
return( ret );
} }
/* /*
@ -324,6 +327,8 @@ int entropy_func( void *data, unsigned char *output, size_t len )
ret = 0; ret = 0;
exit: exit:
polarssl_zeroize( buf, sizeof( buf ) );
#if defined(POLARSSL_THREADING_C) #if defined(POLARSSL_THREADING_C)
if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) if( polarssl_mutex_unlock( &ctx->mutex ) != 0 )
return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); return( POLARSSL_ERR_THREADING_MUTEX_ERROR );
@ -354,12 +359,15 @@ int entropy_write_seed_file( entropy_context *ctx, const char *path )
ret = 0; ret = 0;
exit: exit:
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( ret ); return( ret );
} }
int entropy_update_seed_file( entropy_context *ctx, const char *path ) int entropy_update_seed_file( entropy_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ ENTROPY_MAX_SEED_SIZE ]; unsigned char buf[ ENTROPY_MAX_SEED_SIZE ];
@ -375,14 +383,16 @@ int entropy_update_seed_file( entropy_context *ctx, const char *path )
n = ENTROPY_MAX_SEED_SIZE; n = ENTROPY_MAX_SEED_SIZE;
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); ret = entropy_update_manual( ctx, buf, n );
}
fclose( f ); fclose( f );
entropy_update_manual( ctx, buf, n ); polarssl_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( entropy_write_seed_file( ctx, path ) ); return( entropy_write_seed_file( ctx, path ) );
} }

View file

@ -342,11 +342,14 @@ int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path )
exit: exit:
fclose( f ); fclose( f );
polarssl_zeroize( buf, sizeof( buf ) );
return( ret ); return( ret );
} }
int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ) int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
@ -365,14 +368,16 @@ int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
} }
if( fread( buf, 1, n, f ) != n ) if( fread( buf, 1, n, f ) != n )
{ ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); hmac_drbg_update( ctx, buf, n );
}
fclose( f ); fclose( f );
hmac_drbg_update( ctx, buf, n ); polarssl_zeroize( buf, sizeof( buf ) );
if( ret != 0 )
return( ret );
return( hmac_drbg_write_seed_file( ctx, path ) ); return( hmac_drbg_write_seed_file( ctx, path ) );
} }

View file

@ -217,6 +217,7 @@ void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
*/ */
int md2_file( const char *path, unsigned char output[16] ) int md2_file( const char *path, unsigned char output[16] )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
md2_context ctx; md2_context ctx;
@ -231,17 +232,16 @@ int md2_file( const char *path, unsigned char output[16] )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md2_update( &ctx, buf, n ); md2_update( &ctx, buf, n );
md2_finish( &ctx, output );
md2_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_MD2_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_MD2_FILE_IO_ERROR ); md2_finish( &ctx, output );
}
md2_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -313,6 +313,7 @@ void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
*/ */
int md4_file( const char *path, unsigned char output[16] ) int md4_file( const char *path, unsigned char output[16] )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
md4_context ctx; md4_context ctx;
@ -327,17 +328,16 @@ int md4_file( const char *path, unsigned char output[16] )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md4_update( &ctx, buf, n ); md4_update( &ctx, buf, n );
md4_finish( &ctx, output );
md4_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_MD4_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); md4_finish( &ctx, output );
}
md4_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -330,6 +330,7 @@ void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
*/ */
int md5_file( const char *path, unsigned char output[16] ) int md5_file( const char *path, unsigned char output[16] )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
md5_context ctx; md5_context ctx;
@ -344,17 +345,16 @@ int md5_file( const char *path, unsigned char output[16] )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md5_update( &ctx, buf, n ); md5_update( &ctx, buf, n );
md5_finish( &ctx, output );
md5_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_MD5_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); md5_finish( &ctx, output );
}
md5_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -333,6 +333,7 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer,
if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
{ {
polarssl_zeroize( buf, len );
polarssl_free( buf ); polarssl_free( buf );
return( POLARSSL_ERR_PEM_INVALID_DATA + ret ); return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
} }
@ -343,6 +344,7 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer,
( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
if( pwd == NULL ) if( pwd == NULL )
{ {
polarssl_zeroize( buf, len );
polarssl_free( buf ); polarssl_free( buf );
return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED ); return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED );
} }
@ -371,10 +373,12 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer,
*/ */
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
{ {
polarssl_zeroize( buf, len );
polarssl_free( buf ); polarssl_free( buf );
return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH ); return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );
} }
#else #else
polarssl_zeroize( buf, len );
polarssl_free( buf ); polarssl_free( buf );
return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE ); return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && #endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC &&

View file

@ -98,7 +98,10 @@ int pk_load_file( const char *path, unsigned char **buf, size_t *n )
if( fread( *buf, 1, *n, f ) != *n ) if( fread( *buf, 1, *n, f ) != *n )
{ {
fclose( f ); fclose( f );
polarssl_zeroize( *buf, *n );
polarssl_free( *buf ); polarssl_free( *buf );
return( POLARSSL_ERR_PK_FILE_IO_ERROR ); return( POLARSSL_ERR_PK_FILE_IO_ERROR );
} }

View file

@ -388,6 +388,7 @@ void ripemd160( const unsigned char *input, size_t ilen,
*/ */
int ripemd160_file( const char *path, unsigned char output[20] ) int ripemd160_file( const char *path, unsigned char output[20] )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
ripemd160_context ctx; ripemd160_context ctx;
@ -402,17 +403,16 @@ int ripemd160_file( const char *path, unsigned char output[20] )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
ripemd160_update( &ctx, buf, n ); ripemd160_update( &ctx, buf, n );
ripemd160_finish( &ctx, output );
ripemd160_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR ); ripemd160_finish( &ctx, output );
}
ripemd160_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -363,6 +363,7 @@ void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
*/ */
int sha1_file( const char *path, unsigned char output[20] ) int sha1_file( const char *path, unsigned char output[20] )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
sha1_context ctx; sha1_context ctx;
@ -377,17 +378,16 @@ int sha1_file( const char *path, unsigned char output[20] )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha1_update( &ctx, buf, n ); sha1_update( &ctx, buf, n );
sha1_finish( &ctx, output );
sha1_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_SHA1_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); sha1_finish( &ctx, output );
}
sha1_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -366,6 +366,7 @@ void sha256( const unsigned char *input, size_t ilen,
*/ */
int sha256_file( const char *path, unsigned char output[32], int is224 ) int sha256_file( const char *path, unsigned char output[32], int is224 )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
sha256_context ctx; sha256_context ctx;
@ -380,17 +381,16 @@ int sha256_file( const char *path, unsigned char output[32], int is224 )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha256_update( &ctx, buf, n ); sha256_update( &ctx, buf, n );
sha256_finish( &ctx, output );
sha256_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_SHA256_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); sha256_finish( &ctx, output );
}
sha256_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -370,6 +370,7 @@ void sha512( const unsigned char *input, size_t ilen,
*/ */
int sha512_file( const char *path, unsigned char output[64], int is384 ) int sha512_file( const char *path, unsigned char output[64], int is384 )
{ {
int ret = 0;
FILE *f; FILE *f;
size_t n; size_t n;
sha512_context ctx; sha512_context ctx;
@ -384,17 +385,16 @@ int sha512_file( const char *path, unsigned char output[64], int is384 )
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha512_update( &ctx, buf, n ); sha512_update( &ctx, buf, n );
sha512_finish( &ctx, output );
sha512_free( &ctx );
if( ferror( f ) != 0 ) if( ferror( f ) != 0 )
{ ret = POLARSSL_ERR_SHA512_FILE_IO_ERROR;
fclose( f ); else
return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); sha512_finish( &ctx, output );
}
sha512_free( &ctx );
polarssl_zeroize( buf, sizeof( buf ) );
fclose( f ); fclose( f );
return( 0 );
return( ret );
} }
#endif /* POLARSSL_FS_IO */ #endif /* POLARSSL_FS_IO */

View file

@ -4140,12 +4140,19 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
} }
if( ssl->psk != NULL || ssl->psk_identity != NULL ) if( ssl->psk != NULL )
{ {
polarssl_zeroize( ssl->psk, ssl->psk_len );
polarssl_free( ssl->psk ); polarssl_free( ssl->psk );
polarssl_free( ssl->psk_identity );
ssl->psk = NULL; ssl->psk = NULL;
ssl->psk_len = 0;
}
if( ssl->psk_identity != NULL )
{
polarssl_free( ssl->psk_identity );
ssl->psk_identity = NULL; ssl->psk_identity = NULL;
ssl->psk_identity_len = 0;
} }
if( ( ssl->psk = polarssl_malloc( psk_len ) ) == NULL || if( ( ssl->psk = polarssl_malloc( psk_len ) ) == NULL ||