mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-25 19:45:44 +01:00
Make entropy bias self test poll multiple times
Instead of polling the hardware entropy source a single time and comparing the output with itself, the source is polled at least twice and make sure that the separate outputs are different.
This commit is contained in:
parent
b34e42e69e
commit
e7723ec284
@ -259,14 +259,14 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
|
|||||||
*/
|
*/
|
||||||
int mbedtls_entropy_self_test( int verbose );
|
int mbedtls_entropy_self_test( int verbose );
|
||||||
|
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) && defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or 1 if a test failed
|
* \return 0 if successful, or 1 if a test failed
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_self_test_bias( int verbose );
|
int mbedtls_entropy_source_self_test( int verbose );
|
||||||
#endif /* !MBEDTLS_TEST_NULL_ENTROPY && MBEDTLS_ENTROPY_HARDWARE_ALT */
|
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||||
#endif /* MBEDTLS_SELF_TEST */
|
#endif /* MBEDTLS_SELF_TEST */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -470,80 +470,89 @@ static int entropy_dummy_source( void *data, unsigned char *output,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) && defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
|
|
||||||
#define MBEDTLS_SELF_TEST_BIAS_PATTERN( buf_len, type ) \
|
static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len )
|
||||||
{ \
|
{
|
||||||
size_t i; \
|
int ret = 0;
|
||||||
int has_pat = 1; \
|
size_t entropy_len = 0;
|
||||||
for( i = 0; i < buf_len; i += sizeof( type ) ) \
|
size_t olen = 0;
|
||||||
{ \
|
size_t attempts = buf_len;
|
||||||
has_pat &= memcmp( buf, buf + i, sizeof( type ) ) == 0; \
|
|
||||||
} \
|
while( attempts > 0 && entropy_len < buf_len )
|
||||||
if( ( ret = has_pat ) != 0 ) \
|
{
|
||||||
goto cleanup; \
|
if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len,
|
||||||
} while( 0 ) \
|
buf_len - entropy_len, &olen ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
entropy_len += olen;
|
||||||
|
attempts--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( entropy_len < buf_len )
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf,
|
||||||
|
size_t buf_len )
|
||||||
|
{
|
||||||
|
unsigned char set= 0xFF;
|
||||||
|
unsigned char unset = 0x00;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for( i = 0; i < buf_len; i++ )
|
||||||
|
{
|
||||||
|
set &= buf[i];
|
||||||
|
unset |= buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return( set == 0xFF || unset == 0x00 );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A quick test to ensure hat the entropy sources are functioning correctly
|
* A test to ensure hat the entropy sources are functioning correctly
|
||||||
* and there is no obvious bias. The test performs the following checks:
|
* and there is no obvious failure. The test performs the following checks:
|
||||||
* - The entropy source is not providing only 0s (all bits unset) or 1s (all
|
* - The entropy source is not providing only 0s (all bits unset) or 1s (all
|
||||||
* bits set).
|
* bits set).
|
||||||
* - The entropy source is not providing values in a pattern. Because the
|
* - The entropy source is not providing values in a pattern. Because the
|
||||||
* hardware could be providing data in an arbitrary length, this check is
|
* hardware could be providing data in an arbitrary length, this check polls
|
||||||
* only perform for bytes, words and long words.
|
* the hardware entropy source twice and compares the result to ensure they
|
||||||
|
* are not equal.
|
||||||
* - The error code returned by the entropy source is not an error.
|
* - The error code returned by the entropy source is not an error.
|
||||||
*/
|
*/
|
||||||
int mbedtls_entropy_self_test_bias( int verbose )
|
int mbedtls_entropy_source_self_test( int verbose )
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned char buf[2 * sizeof( unsigned long long int )];
|
unsigned char buf0[2 * sizeof( unsigned long long int )];
|
||||||
mbedtls_entropy_context ctx;
|
unsigned char buf1[2 * sizeof( unsigned long long int )];
|
||||||
size_t entropy_len;
|
|
||||||
size_t olen;
|
|
||||||
size_t gather_tries;
|
|
||||||
|
|
||||||
if( verbose != 0 )
|
if( verbose != 0 )
|
||||||
mbedtls_printf( " ENTROPY_BIAS test: " );
|
mbedtls_printf( " ENTROPY_BIAS test: " );
|
||||||
|
|
||||||
memset( buf, 0x00, sizeof( buf ) );
|
memset( buf0, 0x00, sizeof( buf0 ) );
|
||||||
|
memset( buf1, 0x00, sizeof( buf1 ) );
|
||||||
|
|
||||||
mbedtls_entropy_init( &ctx );
|
if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
|
||||||
|
goto cleanup;
|
||||||
/* The hardware entropy source could return less than the amount of
|
if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 )
|
||||||
* bytes we requested, so we poll the source as many times as there are
|
|
||||||
* bytes */
|
|
||||||
gather_tries = sizeof( buf );
|
|
||||||
entropy_len = 0;
|
|
||||||
while( gather_tries > 0 && entropy_len < sizeof( buf ) )
|
|
||||||
{
|
|
||||||
if( ( ret = mbedtls_hardware_poll( &ctx, buf + entropy_len,
|
|
||||||
sizeof( buf ) - entropy_len, &olen ) ) != 0 )
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
entropy_len += olen;
|
/* Make sure that the returned values are not all 0 or 1 */
|
||||||
gather_tries--;
|
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
|
||||||
}
|
goto cleanup;
|
||||||
|
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
|
||||||
if( entropy_len < sizeof( buf ) )
|
|
||||||
{
|
|
||||||
/* We still do not have enough entropy: fail */
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure that the entropy source is not returning values in a
|
/* Make sure that the entropy source is not returning values in a
|
||||||
* pattern */
|
* pattern */
|
||||||
/* Byte */
|
ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0;
|
||||||
MBEDTLS_SELF_TEST_BIAS_PATTERN( 2 * sizeof( unsigned long long int ), unsigned char );
|
|
||||||
/* Word */
|
|
||||||
MBEDTLS_SELF_TEST_BIAS_PATTERN( 2 * sizeof( unsigned long long int ), unsigned long );
|
|
||||||
/* Long word */
|
|
||||||
MBEDTLS_SELF_TEST_BIAS_PATTERN( 2 * sizeof( unsigned long long int ), unsigned long long int );
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_entropy_free( &ctx );
|
|
||||||
|
|
||||||
if( verbose != 0 )
|
if( verbose != 0 )
|
||||||
{
|
{
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
@ -556,7 +565,8 @@ cleanup:
|
|||||||
|
|
||||||
return( ret != 0 );
|
return( ret != 0 );
|
||||||
}
|
}
|
||||||
#endif /* !MBEDTLS_TEST_NULL_ENTROPY && MBEDTLS_ENTROPY_HARDWARE_ALT */
|
|
||||||
|
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The actual entropy quality is hard to test, but we can at least
|
* The actual entropy quality is hard to test, but we can at least
|
||||||
@ -614,6 +624,11 @@ int mbedtls_entropy_self_test( int verbose )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||||
|
if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
#endif
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_entropy_free( &ctx );
|
mbedtls_entropy_free( &ctx );
|
||||||
|
|
||||||
|
@ -375,12 +375,6 @@ int main( int argc, char *argv[] )
|
|||||||
{
|
{
|
||||||
suites_failed++;
|
suites_failed++;
|
||||||
}
|
}
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) && defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
|
||||||
if( mbedtls_entropy_self_test_bias( v ) != 0)
|
|
||||||
{
|
|
||||||
suites_failed++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
suites_tested++;
|
suites_tested++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -381,8 +381,5 @@ void entropy_nv_seed( char *read_seed_str )
|
|||||||
void entropy_selftest( )
|
void entropy_selftest( )
|
||||||
{
|
{
|
||||||
TEST_ASSERT( mbedtls_entropy_self_test( 0 ) == 0 );
|
TEST_ASSERT( mbedtls_entropy_self_test( 0 ) == 0 );
|
||||||
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) && defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
|
||||||
TEST_ASSERT( mbedtls_entropy_self_test_bias( 0 ) == 0 );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
Loading…
Reference in New Issue
Block a user