diff --git a/ChangeLog b/ChangeLog index 6c285aae3..1b269c8a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ Features * Testing script ssl-opt.sh added for testing 'live' ssl option interoperability against OpenSSL and PolarSSL * Support for reading EC keys that use SpecifiedECDomain in some cases. + * Entropy module now supports seed writing and reading Changes * Deprecated the Memory layer diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h index c4d49556f..73e06f69b 100644 --- a/include/polarssl/entropy.h +++ b/include/polarssl/entropy.h @@ -52,6 +52,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 */ @@ -64,6 +65,7 @@ #define ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ #endif +#define ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES #ifdef __cplusplus @@ -182,6 +184,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 ceea3f065..feba67ba1 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -66,6 +66,7 @@ * CTR_DBRG 4 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 38171fc1e..5ee40826f 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 @@ -308,4 +312,60 @@ exit: return( ret ); } +#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 eef05f46a..9980a9100 100644 --- a/library/error.c +++ b/library/error.c @@ -590,6 +590,8 @@ void polarssl_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)