diff --git a/include/polarssl/hmac_drbg.h b/include/polarssl/hmac_drbg.h index d88b50d3f2..1f830d8436 100644 --- a/include/polarssl/hmac_drbg.h +++ b/include/polarssl/hmac_drbg.h @@ -51,18 +51,22 @@ extern "C" { /** * HMAC_DRBG context. - * TODO: reseed counter. */ typedef struct { - md_context_t md_ctx; - unsigned char V[POLARSSL_MD_MAX_SIZE]; - unsigned char K[POLARSSL_MD_MAX_SIZE]; + /* Working state */ + md_context_t md_ctx; /*!< HMAC context */ + unsigned char V[POLARSSL_MD_MAX_SIZE]; /*!< V in the spec */ + unsigned char K[POLARSSL_MD_MAX_SIZE]; /*!< Key in the spec */ + int reseed_counter; /*!< reseed counter */ + /* Administrative state */ size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ int prediction_resistance; /*!< enable prediction resistance (Automatic reseed before every random generation) */ + int reseed_interval; /*!< reseed interval */ + /* Callbacks */ int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ void *p_entropy; /*!< context for the entropy function */ } hmac_drbg_context; @@ -128,14 +132,25 @@ void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, /** * \brief Set the amount of entropy grabbed on each reseed - * (Default: HMAC_DRBG_ENTROPY_LEN) + * (Default: given by the security strength, which + * depends on the hash used, see \c hmac_drbg_init() ) * * \param ctx HMAC_DRBG context - * \param len Amount of entropy to grab + * \param len Amount of entropy to grab, in bytes */ void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len ); +/** + * \brief Set the reseed interval + * (Default: HMAC_DRBG_RESEED_INTERVAL) + * + * \param ctx HMAC_DRBG context + * \param interval Reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, + int interval ); + /** * \brief HMAC_DRBG update state * @@ -165,7 +180,7 @@ int hmac_drbg_reseed( hmac_drbg_context *ctx, /** * \brief HMAC_DRBG generate random with additional update input * - * Note: Automatically reseeds if reseed_counter is reached. + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * * \param p_rng HMAC_DRBG context * \param output Buffer to fill @@ -185,7 +200,7 @@ int hmac_drbg_random_with_add( void *p_rng, /** * \brief HMAC_DRBG generate random * - * Note: Automatically reseeds if reseed_counter is reached. + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. * * \param p_rng HMAC_DRBG context * \param output Buffer to fill diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index 808be61471..328ba9272e 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -114,7 +114,8 @@ int hmac_drbg_reseed( hmac_drbg_context *ctx, /* 2. Update state */ hmac_drbg_update( ctx, seed, seedlen ); - /* 3. Reset reseed_counter (TODO) */ + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; /* 4. Done */ return( 0 ); @@ -145,6 +146,8 @@ int hmac_drbg_init( hmac_drbg_context *ctx, ctx->f_entropy = f_entropy; ctx->p_entropy = p_entropy; + ctx->reseed_interval = HMAC_DRBG_RESEED_INTERVAL; + /* * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by * each hash function, then according to SP800-90A rev1 10.1 table 2, @@ -187,6 +190,14 @@ void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len ) ctx->entropy_len = len; } +/* + * Set reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + /* * HMAC_DRBG random function with optional additional data (10.1.2.5) */ @@ -200,9 +211,10 @@ int hmac_drbg_random_with_add( void *p_rng, size_t left = out_len; unsigned char *out = output; - /* 1. Check reseed counter (TODO) and PR */ + /* 1. Check reseed counter and PR */ if( ctx->f_entropy != NULL && - ctx->prediction_resistance == HMAC_DRBG_PR_ON ) + ( ctx->prediction_resistance == HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) { if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) return( ret ); @@ -229,7 +241,8 @@ int hmac_drbg_random_with_add( void *p_rng, /* 6. Update */ hmac_drbg_update( ctx, additional, add_len ); - /* 7. Update reseed counter (TODO) */ + /* 7. Update reseed counter */ + ctx->reseed_counter++; /* 8. Done */ return( 0 );