Add automatic periodic reseeding
diff --git a/include/polarssl/hmac_drbg.h b/include/polarssl/hmac_drbg.h
index d88b50d..1f830d8 100644
--- a/include/polarssl/hmac_drbg.h
+++ b/include/polarssl/hmac_drbg.h
@@ -51,18 +51,22 @@
/**
* 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,15 +132,26 @@
/**
* \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
*
* \param ctx HMAC_DRBG context
@@ -165,7 +180,7 @@
/**
* \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 @@
/**
* \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 808be61..328ba92 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -114,7 +114,8 @@
/* 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 @@
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,
@@ -188,6 +191,14 @@
}
/*
+ * 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)
*/
int hmac_drbg_random_with_add( void *p_rng,
@@ -200,9 +211,10 @@
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 @@
/* 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 );