mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-04 04:32:24 -05: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
 | 
					        goto cleanup;
 | 
				
			||||||
     * bytes */
 | 
					
 | 
				
			||||||
    gather_tries = sizeof( buf );
 | 
					    /* Make sure that the returned values are not all 0 or 1 */
 | 
				
			||||||
    entropy_len = 0;
 | 
					    if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
 | 
				
			||||||
    while( gather_tries > 0 && entropy_len < sizeof( buf ) )
 | 
					        goto cleanup;
 | 
				
			||||||
    {
 | 
					    if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
 | 
				
			||||||
        if( ( ret = mbedtls_hardware_poll( &ctx, buf + entropy_len,
 | 
					 | 
				
			||||||
            sizeof( buf ) - entropy_len, &olen ) ) != 0 )
 | 
					 | 
				
			||||||
            goto cleanup;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        entropy_len += olen;
 | 
					 | 
				
			||||||
        gather_tries--;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user