From af786ff6cc30f455c2ba15b5ae1dc53ea7498490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 30 Jan 2014 18:44:18 +0100 Subject: [PATCH] Add hmac_drbg_set_prediction_resistance() --- include/polarssl/hmac_drbg.h | 26 ++++++++++++++++++++------ library/hmac_drbg.c | 18 +++++++++++++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/polarssl/hmac_drbg.h b/include/polarssl/hmac_drbg.h index 059b885de..d88b50d3f 100644 --- a/include/polarssl/hmac_drbg.h +++ b/include/polarssl/hmac_drbg.h @@ -42,13 +42,16 @@ #define HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ #define HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +#define HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ + #ifdef __cplusplus extern "C" { #endif /** * HMAC_DRBG context. - * TODO: reseed counter, prediction resistance flag. + * TODO: reseed counter. */ typedef struct { @@ -57,12 +60,11 @@ typedef struct unsigned char K[POLARSSL_MD_MAX_SIZE]; size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ + int prediction_resistance; /*!< enable prediction resistance (Automatic + reseed before every random generation) */ - /* - * Callbacks (Entropy) - */ - int (*f_entropy)(void *, unsigned char *, size_t); - void *p_entropy; /*!< context for the entropy function */ + int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ + void *p_entropy; /*!< context for the entropy function */ } hmac_drbg_context; /** @@ -112,6 +114,18 @@ int hmac_drbg_init_buf( hmac_drbg_context *ctx, const md_info_t * md_info, const unsigned char *data, size_t data_len ); +/** + * \brief Enable / disable prediction resistance (Default: Off) + * + * Note: If enabled, entropy is used for ctx->entropy_len before each call! + * Only use this if you have ample supply of good entropy! + * + * \param ctx HMAC_DRBG context + * \param resistance HMAC_DRBG_PR_ON or HMAC_DRBG_PR_OFF + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ); + /** * \brief Set the amount of entropy grabbed on each reseed * (Default: HMAC_DRBG_ENTROPY_LEN) diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index 8a4f3f09c..808be6147 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -170,6 +170,15 @@ int hmac_drbg_init( hmac_drbg_context *ctx, return( 0 ); } +/* + * Set prediction resistance + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + /* * Set entropy length grabbed for reseeds */ @@ -185,12 +194,19 @@ int hmac_drbg_random_with_add( void *p_rng, unsigned char *output, size_t out_len, const unsigned char *additional, size_t add_len ) { + int ret; hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng; size_t md_len = md_get_size( ctx->md_ctx.md_info ); size_t left = out_len; unsigned char *out = output; - /* 1. Check reseed counter (TODO) */ + /* 1. Check reseed counter (TODO) and PR */ + if( ctx->f_entropy != NULL && + ctx->prediction_resistance == HMAC_DRBG_PR_ON ) + { + if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + } /* 2. Use additional data if any */ if( additional != NULL && add_len != 0 )