diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 6b2c7887e..19a7c44e9 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -77,6 +77,9 @@ #define MBEDTLS_HMAC_DRBG_PR_OFF 0x55555555 /**< No prediction resistance */ #define MBEDTLS_HMAC_DRBG_PR_ON 0x2AAAAAAA /**< Prediction resistance enabled */ +#define MBEDTLS_HMAC_DRBG_RESEED 0x78547854 /**< Default environment, reseeding enabled */ +#define MBEDTLS_HMAC_DRBG_NO_RESEED 0x07AB87F0 /**< Reseeding disabled, no f_entropy required */ + #ifdef __cplusplus extern "C" { #endif @@ -91,7 +94,7 @@ typedef struct mbedtls_hmac_drbg_context mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ int reseed_counter; /*!< reseed counter */ - + int reseed_flag; /*!< disables reseeding if set to MBEDTLS_HMAC_DRBG_NO_RESEED */ /* Administrative state */ size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ int prediction_resistance; /*!< enable prediction resistance (Automatic @@ -220,6 +223,20 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, int resistance ); +/** + * \brief This function turns reseeding on or off. + * Default value is on. + * + * \note If set to MBEDTLS_HMAC_DRBG_NO_RESEED, this function + * disables reseeding, providing a no_reseed environment. + * f_entropy can then be null. + * + * \param ctx The HMAC_DRBG context. + * \param reseed_flag #MBEDTLS_HMAC_DRBG_NO_RESEED or #MBEDTLS_HMAC_DRBG_RESEED + */ +void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx, + int reseed_flag ); + /** * \brief This function sets the amount of entropy grabbed on each * seed or reseed. diff --git a/library/ecdsa.c b/library/ecdsa.c index 6cfaa08fe..a0b890dd2 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -482,6 +482,7 @@ sign: mbedtls_hmac_drbg_context rng_ctx_blind; mbedtls_hmac_drbg_init( &rng_ctx_blind ); + mbedtls_hmac_drbg_set_reseeding( &rng_ctx_blind, MBEDTLS_HMAC_DRBG_NO_RESEED ); p_rng_blind_det = &rng_ctx_blind; mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info, @@ -509,6 +510,7 @@ sign: * a valid ECDSA signature. */ p_rng_blind_det = p_rng; + mbedtls_hmac_drbg_set_reseeding( p_rng_blind_det, MBEDTLS_HMAC_DRBG_NO_RESEED ); #endif /* MBEDTLS_ECP_RESTARTABLE */ /* diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index fc7aea9b5..d8669c3c4 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -63,6 +63,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); ctx->prediction_resistance = MBEDTLS_HMAC_DRBG_PR_OFF; + ctx->reseed_flag = MBEDTLS_HMAC_DRBG_RESEED; #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &ctx->mutex ); #endif @@ -388,6 +389,15 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx ctx->prediction_resistance = resistance; } +/* + * Set the reseeding flag + */ +void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx, + int reseed_flag ) +{ + ctx->reseed_flag = reseed_flag; +} + /* * Set entropy length grabbed for seeding */ @@ -434,14 +444,20 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); /* 1. (aka VII and IX) Check reseed counter and PR */ - if( ctx->f_entropy != NULL && /* For no-reseeding instances */ - ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || - ctx->reseed_counter > ctx->reseed_interval ) ) + if( ctx->reseed_flag != MBEDTLS_HMAC_DRBG_NO_RESEED && + ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) { - if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) - return( ret ); - - add_len = 0; /* VII.4 */ + if( ctx->f_entropy == NULL ) + { + return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + } + else + { + if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + add_len = 0; /* VII.4 */ + } } /* 2. Use additional data if any */ diff --git a/tests/suites/test_suite_hmac_drbg.function b/tests/suites/test_suite_hmac_drbg.function index 0463a89a4..b812b704a 100644 --- a/tests/suites/test_suite_hmac_drbg.function +++ b/tests/suites/test_suite_hmac_drbg.function @@ -149,6 +149,7 @@ void hmac_drbg_buf( int md_alg ) TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info, buf, sizeof( buf ) ) == 0 ); /* Make sure it never tries to reseed (would segfault otherwise) */ + mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED ); mbedtls_hmac_drbg_set_reseed_interval( &ctx, 3 ); mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); @@ -172,7 +173,7 @@ void hmac_drbg_no_reseed( int md_alg, data_t * entropy, mbedtls_hmac_drbg_context ctx; mbedtls_hmac_drbg_init( &ctx ); - + mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED ); p_entropy.p = entropy->x; p_entropy.len = entropy->len; @@ -219,6 +220,7 @@ void hmac_drbg_nopr( int md_alg, data_t * entropy, data_t * custom, mbedtls_hmac_drbg_context ctx; mbedtls_hmac_drbg_init( &ctx ); + mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED ); p_entropy.p = entropy->x; p_entropy.len = entropy->len;