Always gather MBEDTLS_ENTROPY_BLOCK_SIZE bytes of entropy
mbedtls_entropy_func returns up to MBEDTLS_ENTROPY_BLOCK_SIZE bytes.
This is the output of a hash function and does not indicate how many
bytes of entropy went into the hash computation.
Enforce that mbedtls_entropy_func gathers a total of
MBEDTLS_ENTROPY_BLOCK_SIZE bytes or more from strong sources. Weak
sources don't count for this calculation. This is complementary to the
per-source threshold mechanism.
In particular, we define system sources with a threshold of 32. But
when using SHA-512 for the entropy accumulator,
MBEDTLS_ENTROPY_BLOCK_SIZE = 64, so users can expect 64 bytes' worth
of entropy. Before, you only got 64 bytes of entropy if there were two
sources. Now you get 64 bytes of entropy even with a single source
with a threshold of 32.
diff --git a/library/entropy.c b/library/entropy.c
index f8db1a5..5655253 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -325,7 +325,8 @@
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
- int ret, count = 0, i, done;
+ int ret, count = 0, i, thresholds_reached;
+ size_t strong_size;
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
@@ -363,12 +364,17 @@
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
- done = 1;
+ thresholds_reached = 1;
+ strong_size = 0;
for( i = 0; i < ctx->source_count; i++ )
+ {
if( ctx->source[i].size < ctx->source[i].threshold )
- done = 0;
+ thresholds_reached = 0;
+ if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
+ strong_size += ctx->source[i].size;
+ }
}
- while( ! done );
+ while( ! thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE );
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );