From 7580ba475d60990cb9049e724a0bb106504b7a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 19 Jun 2015 10:26:32 +0200 Subject: [PATCH] Add a concept of entropy source strength. The main goal is, we want and error if cycle counter is the only source. --- include/mbedtls/entropy.h | 14 ++++++++-- include/mbedtls/error.h | 3 +-- library/entropy.c | 33 +++++++++++++++++------- programs/pkey/gen_key.c | 3 ++- tests/suites/test_suite_entropy.function | 13 +++++++--- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h index a99d20da0..597f03d0b 100644 --- a/include/mbedtls/entropy.h +++ b/include/mbedtls/entropy.h @@ -53,7 +53,8 @@ #define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ #define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ #define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ -#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x0058 /**< Read/write error in file. */ +#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */ +#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */ /** * \name SECTION: Module settings @@ -82,6 +83,9 @@ #define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES +#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ +#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ + #ifdef __cplusplus extern "C" { #endif @@ -109,6 +113,7 @@ typedef struct void * p_source; /**< The callback data pointer */ size_t size; /**< Amount received in bytes */ size_t threshold; /**< Minimum bytes required before release */ + int strong; /**< Is the source strong? */ } mbedtls_entropy_source_state; @@ -156,12 +161,17 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx ); * \param p_source Function data * \param threshold Minimum required from source before entropy is released * ( with mbedtls_entropy_func() ) (in bytes) + * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or + * MBEDTSL_ENTROPY_SOURCE_WEAK. + * At least one strong source needs to be added. + * Weaker sources (such as the cycle counter) can be used as + * a complement. * * \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES */ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold ); + size_t threshold, int strong ); /** * \brief Trigger an extra gather poll for the accumulator diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 924424929..4f4301879 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -61,9 +61,8 @@ * PADLOCK 1 0x0030-0x0030 * DES 1 0x0032-0x0032 * CTR_DBRG 4 0x0034-0x003A - * ENTROPY 3 0x003C-0x0040 + * ENTROPY 3 0x003C-0x0040 0x003D-0x003F * NET 9 0x0042-0x0052 0x0043-0x0043 - * ENTROPY 1 0x0058-0x0058 * ASN1 7 0x0060-0x006C * PBKDF2 1 0x007C-0x007C * HMAC_DRBG 4 0x0003-0x0009 diff --git a/library/entropy.c b/library/entropy.c index 4dddb7507..92717c8c6 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -77,18 +77,23 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, - MBEDTLS_ENTROPY_MIN_PLATFORM ); + MBEDTLS_ENTROPY_MIN_PLATFORM, + MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif #if defined(MBEDTLS_TIMING_C) - mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, MBEDTLS_ENTROPY_MIN_HARDCLOCK ); + mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, + MBEDTLS_ENTROPY_MIN_HARDCLOCK, + MBEDTLS_ENTROPY_SOURCE_WEAK ); #endif #if defined(MBEDTLS_HAVEGE_C) mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, - MBEDTLS_ENTROPY_MIN_HAVEGE ); + MBEDTLS_ENTROPY_MIN_HAVEGE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL - MBEDTLS_ENTROPY_MIN_HARDWARE ); + MBEDTLS_ENTROPY_MIN_HARDWARE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ } @@ -106,7 +111,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold ) + size_t threshold, int strong ) { int index, ret = 0; @@ -122,9 +127,10 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, goto exit; } - ctx->source[index].f_source = f_source; - ctx->source[index].p_source = p_source; + ctx->source[index].f_source = f_source; + ctx->source[index].p_source = p_source; ctx->source[index].threshold = threshold; + ctx->source[index].strong = strong; ctx->source_count++; @@ -198,7 +204,7 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, */ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) { - int ret, i; + int ret, i, have_one_strong = 0; unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; size_t olen; @@ -210,6 +216,9 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) */ for( i = 0; i < ctx->source_count; i++ ) { + if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) + have_one_strong = 1; + olen = 0; if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) @@ -227,6 +236,9 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) } } + if( have_one_strong == 0 ) + return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); + return( 0 ); } @@ -424,11 +436,12 @@ int mbedtls_entropy_self_test( int verbose ) mbedtls_entropy_init( &ctx ); - /* First do a gather to mek sure we have default sources */ + /* First do a gather to make sure we have default sources */ if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) goto cleanup; - ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 ); + ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, + MBEDTLS_ENTROPY_SOURCE_WEAK ); if( ret != 0 ) goto cleanup; diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 13d23fc1f..a58a80e36 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -286,7 +286,8 @@ int main( int argc, char *argv[] ) if( opt.use_dev_random ) { if( ( ret = mbedtls_entropy_add_source( &entropy, dev_random_entropy_poll, - NULL, DEV_RANDOM_THRESHOLD ) ) != 0 ) + NULL, DEV_RANDOM_THRESHOLD, + MBEDTLS_ENTROPY_SOURCE_STRONG ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_entropy_add_source returned -0x%04x\n", -ret ); goto exit; diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function index 83584e119..3b739cce9 100644 --- a/tests/suites/test_suite_entropy.function +++ b/tests/suites/test_suite_entropy.function @@ -68,9 +68,11 @@ void entropy_too_many_sources( ) * since we don't know how many sources were automatically added. */ for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ ) - (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 ); + (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, + 16, MBEDTLS_ENTROPY_SOURCE_WEAK ); - TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 ) + TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, + 16, MBEDTLS_ENTROPY_SOURCE_WEAK ) == MBEDTLS_ERR_ENTROPY_MAX_SOURCES ); exit: @@ -116,7 +118,9 @@ void entropy_source_fail( char *path ) mbedtls_entropy_init( &ctx ); - TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &fail, 16 ) + TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, + &fail, 16, + MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 ); TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) @@ -147,7 +151,8 @@ void entropy_threshold( int threshold, int chunk_size, int result ) mbedtls_entropy_init( &ctx ); TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, - &chunk_size, threshold ) == 0 ); + &chunk_size, threshold, + MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 ); entropy_dummy_calls = 0; ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );