From 1e9423704a2379228828152a2f05d123e181cf9f Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Wed, 26 Mar 2014 11:54:05 +0100 Subject: [PATCH] Support for seed file writing and reading in Entropy --- ChangeLog | 3 ++ include/polarssl/entropy.h | 30 +++++++++++++++++++ include/polarssl/error.h | 1 + library/entropy.c | 60 ++++++++++++++++++++++++++++++++++++++ library/error.c | 2 ++ 5 files changed, 96 insertions(+) diff --git a/ChangeLog b/ChangeLog index e7e2a7106..fe8e5e77e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ PolarSSL ChangeLog = Branch 1.2 +Features + * Entropy module now supports seed writing and reading + Changes * Introduced POLARSSL_HAVE_READDIR_R for systems without it * Improvements to the CMake build system, contributed by Julian Ospald. diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h index 039f5cd6b..ed97dcabb 100644 --- a/include/polarssl/entropy.h +++ b/include/polarssl/entropy.h @@ -39,6 +39,7 @@ #define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ #define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ #define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ +#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR -0x0058 /**< Read/write error in file. */ #if !defined(POLARSSL_CONFIG_OPTIONS) #define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ @@ -47,6 +48,7 @@ #define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ +#define ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES #ifdef __cplusplus @@ -146,6 +148,34 @@ int entropy_func( void *data, unsigned char *output, size_t len ); int entropy_update_manual( entropy_context *ctx, const unsigned char *data, size_t len ); +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, or + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_write_seed_file( entropy_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance. No more than ENTROPY_MAX_SEED_SIZE bytes are + * read from the seed file. The rest is ignored. + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_update_seed_file( entropy_context *ctx, const char *path ); +#endif + #ifdef __cplusplus } #endif diff --git a/include/polarssl/error.h b/include/polarssl/error.h index 8d7da0b59..a28842d58 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -62,6 +62,7 @@ * CTR_DBRG 3 0x0034-0x003A * ENTROPY 3 0x003C-0x0040 * NET 11 0x0042-0x0056 + * ENTROPY 1 0x0058-0x0058 * ASN1 7 0x0060-0x006C * MD2 1 0x0070-0x0070 * MD4 1 0x0072-0x0072 diff --git a/library/entropy.c b/library/entropy.c index 966245472..7409c2e72 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -30,6 +30,10 @@ #include "polarssl/entropy.h" #include "polarssl/entropy_poll.h" +#if defined(POLARSSL_FS_IO) +#include +#endif + #if defined(POLARSSL_HAVEGE_C) #include "polarssl/havege.h" #endif @@ -201,4 +205,60 @@ int entropy_func( void *data, unsigned char *output, size_t len ) return( 0 ); } +#if defined(POLARSSL_FS_IO) +int entropy_write_seed_file( entropy_context *ctx, const char *path ) +{ + int ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + if( ( ret = entropy_func( ctx, buf, ENTROPY_BLOCK_SIZE ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, ENTROPY_BLOCK_SIZE, f ) != ENTROPY_BLOCK_SIZE ) + { + ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int entropy_update_seed_file( entropy_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ ENTROPY_MAX_SEED_SIZE ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > ENTROPY_MAX_SEED_SIZE ) + n = ENTROPY_MAX_SEED_SIZE; + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + } + + fclose( f ); + + entropy_update_manual( ctx, buf, n ); + + return( entropy_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + #endif diff --git a/library/error.c b/library/error.c index 9f8941612..98c93ff30 100644 --- a/library/error.c +++ b/library/error.c @@ -508,6 +508,8 @@ void error_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); if( use_ret == -(POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED) ) snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_FILE_IO_ERROR) ) + snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); #endif /* POLARSSL_ENTROPY_C */ #if defined(POLARSSL_GCM_C)