From 12b89cbc0b6685367975a8da60f25a04f149fd7b Mon Sep 17 00:00:00 2001 From: Victor Krasnoshchok Date: Thu, 27 Aug 2020 00:19:55 +0300 Subject: [PATCH] Fix premature fopen() call in mbedtls_entropy_write_seed_file #3175 Signed-off-by: Victor Krasnoshchok --- ChangeLog.d/bugfix_PR3616.txt | 5 +++++ library/entropy.c | 18 +++++++++++++----- tests/suites/test_suite_entropy.data | 3 +++ tests/suites/test_suite_entropy.function | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 ChangeLog.d/bugfix_PR3616.txt diff --git a/ChangeLog.d/bugfix_PR3616.txt b/ChangeLog.d/bugfix_PR3616.txt new file mode 100644 index 000000000..47d104492 --- /dev/null +++ b/ChangeLog.d/bugfix_PR3616.txt @@ -0,0 +1,5 @@ +Bugfix + * Fix premature fopen() call in mbedtls_entropy_write_seed_file which may + lead to the seed file corruption in case if the path to the seed file is + equal to MBEDTLS_PLATFORM_STD_NV_SEED_FILE. Contributed by Victor + Krasnoshchok in #3616. diff --git a/library/entropy.c b/library/entropy.c index 666c55654..22fa71304 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -489,14 +489,20 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) { int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - FILE *f; + FILE *f = NULL; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) + { + ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; goto exit; + } + + if( ( f = fopen( path, "wb" ) ) == NULL ) + { + ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; + goto exit; + } if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) { @@ -509,7 +515,9 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p exit: mbedtls_platform_zeroize( buf, sizeof( buf ) ); - fclose( f ); + if( f != NULL ) + fclose( f ); + return( ret ); } diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data index 5cff39984..3595c716d 100644 --- a/tests/suites/test_suite_entropy.data +++ b/tests/suites/test_suite_entropy.data @@ -7,6 +7,9 @@ entropy_seed_file:"data_files/entropy_seed":0 Entropy write/update seed file entropy_seed_file:"no_such_dir/file":MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR +Entropy write/update seed file: base NV seed file +entropy_write_base_seed_file:0 + Entropy too many sources entropy_too_many_sources: diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function index 889d3bca7..c275257ba 100644 --- a/tests/suites/test_suite_entropy.function +++ b/tests/suites/test_suite_entropy.function @@ -140,6 +140,21 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */ +void entropy_write_base_seed_file( int ret ) +{ + mbedtls_entropy_context ctx; + + mbedtls_entropy_init( &ctx ); + + TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret ); + TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret ); + +exit: + mbedtls_entropy_free( &ctx ); +} +/* END_CASE */ + /* BEGIN_CASE */ void entropy_too_many_sources( ) {