From 66ff70dd48dd66467cda78bd91ac06ab83e31125 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 | 1 +
include/polarssl/entropy.h | 30 +++++++++++++++++++
include/polarssl/error.h | 1 +
library/entropy.c | 60 ++++++++++++++++++++++++++++++++++++++
library/error.c | 2 ++
5 files changed, 94 insertions(+)
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)