From 85485c73380e44e6d6e00a340883d1972d5f9e21 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 8 Oct 2019 15:04:16 +0200 Subject: [PATCH] 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. --- library/entropy.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/library/entropy.c b/library/entropy.c index f8db1a550..565525396 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -325,7 +325,8 @@ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) 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 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) 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 );