Add test cases for NV seed functionality
A standard 'test' that writes a seed file is added so that regular tests still can succeed. This is in lieu of a 'SUITE_PRE_CODE' kind of arrangement where a suite can run code before (and after) all other code runs. A test is added that checks if we can read and write the standard NV seed file A test is added that actually checks if the entropy and seed file values that are the result of just using the NV seed are the same as the manual calculation.
This commit is contained in:
parent
960292337c
commit
ffbfb4c24c
2 changed files with 218 additions and 0 deletions
|
@ -1,3 +1,6 @@
|
|||
Create NV seed_file
|
||||
nv_seed_file_create:
|
||||
|
||||
Entropy write/update seed file
|
||||
entropy_seed_file:"data_files/entropy_seed":0
|
||||
|
||||
|
@ -37,5 +40,17 @@ entropy_threshold:16:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
|||
Entropy thershold #4
|
||||
entropy_threshold:1024:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||
|
||||
Check NV seed standard IO
|
||||
entropy_nv_seed_std_io:
|
||||
|
||||
Check NV seed manually #1
|
||||
entropy_nv_seed:"00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF"
|
||||
|
||||
Check NV seed manually #2
|
||||
entropy_nv_seed:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
Check NV seed manually #3
|
||||
entropy_nv_seed:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
|
||||
Entropy self test
|
||||
entropy_selftest:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
|
||||
/*
|
||||
* Number of calls made to entropy_dummy_source()
|
||||
|
@ -33,6 +34,86 @@ static int entropy_dummy_source( void *data, unsigned char *output,
|
|||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Ability to clear entropy sources to allow testing with just predefined
|
||||
* entropy sources. This function or tests depending on it might break if there
|
||||
* are internal changes to how entropy sources are registered.
|
||||
*
|
||||
* To be called immediately after mbedtls_entropy_init().
|
||||
*
|
||||
* Just resetting the counter. New sources will overwrite existing ones.
|
||||
* This might break memory checks in the future if sources need 'free-ing' then
|
||||
* as well.
|
||||
*/
|
||||
static void entropy_clear_sources( mbedtls_entropy_context *ctx )
|
||||
{
|
||||
ctx->source_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NV seed read/write functions that use a buffer instead of a file
|
||||
*/
|
||||
static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
|
||||
{
|
||||
if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
|
||||
{
|
||||
if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* NV seed read/write helpers that fill the base seedfile
|
||||
*/
|
||||
static int write_nv_seed( unsigned char *buf, size_t buf_len )
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
|
||||
return( -1 );
|
||||
|
||||
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
fclose( f );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int read_nv_seed( unsigned char *buf, size_t buf_len )
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
|
||||
return( -1 );
|
||||
|
||||
if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||
return( -1 );
|
||||
|
||||
fclose( f );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
|
@ -160,6 +241,10 @@ void entropy_threshold( int threshold, int chunk_size, int result )
|
|||
if( result >= 0 )
|
||||
{
|
||||
TEST_ASSERT( ret == 0 );
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
// Two times as much calls due to the NV seed update
|
||||
result *= 2;
|
||||
#endif
|
||||
TEST_ASSERT( entropy_dummy_calls == (size_t) result );
|
||||
}
|
||||
else
|
||||
|
@ -172,6 +257,124 @@ exit:
|
|||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
|
||||
void nv_seed_file_create()
|
||||
{
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
|
||||
void entropy_nv_seed_std_io()
|
||||
{
|
||||
unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
|
||||
mbedtls_platform_std_nv_seed_write );
|
||||
|
||||
/* Check if platform NV read and write manipulate the same data */
|
||||
TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
|
||||
memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
/* Check if platform NV write and raw read manipulate the same data */
|
||||
TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
|
||||
TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT:MBEDTLS_SHA512_C */
|
||||
void entropy_nv_seed( char *read_seed_str )
|
||||
{
|
||||
mbedtls_sha512_context accumulator;
|
||||
mbedtls_entropy_context ctx;
|
||||
|
||||
unsigned char header[2];
|
||||
unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char read_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( buffer_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
// Set the initial NV seed to read
|
||||
unhexify( read_seed, read_seed_str );
|
||||
memcpy( buffer_seed, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
// Make sure we read/write NV seed from our buffers
|
||||
mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
|
||||
|
||||
mbedtls_entropy_init( &ctx );
|
||||
entropy_clear_sources( &ctx );
|
||||
|
||||
TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE,
|
||||
MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
|
||||
|
||||
// Do an entropy run
|
||||
TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
|
||||
|
||||
// Determine what should have happened with manual entropy internal logic
|
||||
// Only use the SHA-512 version to check
|
||||
|
||||
// Init accumulator
|
||||
header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
|
||||
mbedtls_sha512_starts( &accumulator, 0 );
|
||||
|
||||
// First run for updating write_seed
|
||||
header[0] = 0;
|
||||
mbedtls_sha512_update( &accumulator, header, 2 );
|
||||
mbedtls_sha512_update( &accumulator, read_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
mbedtls_sha512_finish( &accumulator, buf );
|
||||
|
||||
memset( &accumulator, 0, sizeof( mbedtls_sha512_context ) );
|
||||
mbedtls_sha512_starts( &accumulator, 0 );
|
||||
mbedtls_sha512_update( &accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_seed, 0 );
|
||||
|
||||
// Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
|
||||
header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
|
||||
mbedtls_sha512_update( &accumulator, header, 2 );
|
||||
mbedtls_sha512_update( &accumulator, empty, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
|
||||
header[0] = 0;
|
||||
mbedtls_sha512_update( &accumulator, header, 2 );
|
||||
mbedtls_sha512_update( &accumulator, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
|
||||
mbedtls_sha512_finish( &accumulator, buf );
|
||||
|
||||
mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_entropy, 0 );
|
||||
|
||||
// Check result of both NV file and entropy received with the manual calculations
|
||||
TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
|
||||
|
||||
mbedtls_entropy_free( &ctx );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
|
||||
void entropy_selftest( )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue