hmac_drbg: make no reseeding behaviour explicit

Add a flag to the hmac_drbg context that will signal that reseeding is not required.
Change tests and one ecdsa call to not use reseeding, as was the previous case.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 6b2c788..19a7c44 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 @@
     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
@@ -221,6 +224,20 @@
                                           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 6cfaa08..a0b890d 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -482,6 +482,7 @@
         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 @@
          * 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 fc7aea9..d8669c3 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -63,6 +63,7 @@
     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
@@ -389,6 +390,15 @@
 }
 
 /*
+ * 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
  */
 int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
@@ -434,14 +444,20 @@
         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 0463a89..b812b70 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -149,6 +149,7 @@
     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 @@
     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 @@
     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;