CTR_DRBG: support set_entropy_len() before seed()
mbedtls_ctr_drbg_seed() always set the entropy length to the default,
so a call to mbedtls_ctr_drbg_set_entropy_len() before seed() had no
effect. Change this to the more intuitive behavior that
set_entropy_len() sets the entropy length and seed() respects that and
only uses the default entropy length if there was no call to
set_entropy_len().
The former test-only function mbedtls_ctr_drbg_seed_entropy_len() is
no longer used, but keep it for strict ABI compatibility.
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 766e647..c14507f 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -214,11 +214,8 @@
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
- * \p f_entropy is always called with a buffer size equal to the entropy
- * length. The entropy length is initially #MBEDTLS_CTR_DRBG_ENTROPY_LEN
- * and this value is always used for the initial seeding. You can change
- * the entropy length for subsequent seeding by calling
- * mbedtls_ctr_drbg_set_entropy_len() after this function.
+ * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
+ * You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
@@ -255,6 +252,8 @@
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
+ * \p f_entropy is always called with a buffer size
+ * equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
@@ -298,15 +297,10 @@
/**
* \brief This function sets the amount of entropy grabbed on each
- * subsequent reseed.
+ * seed or reseed.
*
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
- * \note mbedtls_ctr_drbg_seed() always sets the entropy length
- * to #MBEDTLS_CTR_DRBG_ENTROPY_LEN, so this function
- * only has an effect when it is called after
- * mbedtls_ctr_drbg_seed().
- *
* \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus:
* - When using AES-256
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 9222f4e..4e47058 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -365,29 +365,22 @@
return( ret );
}
-/*
- * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
- * NIST tests to succeed (which require known length fixed entropy)
- */
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
- * mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
- * custom, len, entropy_len)
+ * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* custom[:len] = nonce || personalization_string
- * where entropy_input comes from f_entropy for entropy_len bytes
+ * where entropy_input comes from f_entropy for ctx->entropy_len bytes
* and with outputs
* ctx = initial_working_state
*/
-int mbedtls_ctr_drbg_seed_entropy_len(
- mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t),
- void *p_entropy,
- const unsigned char *custom,
- size_t len,
- size_t entropy_len )
+int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len )
{
int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
@@ -399,7 +392,8 @@
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
- ctx->entropy_len = entropy_len;
+ if( ctx->entropy_len == 0 )
+ ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/*
@@ -417,14 +411,15 @@
return( 0 );
}
-int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t),
- void *p_entropy,
- const unsigned char *custom,
- size_t len )
+/* Backward compatibility wrapper */
+int mbedtls_ctr_drbg_seed_entropy_len(
+ mbedtls_ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
+ const unsigned char *custom, size_t len,
+ size_t entropy_len )
{
- return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
- MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
+ mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
+ return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
}
/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
@@ -678,8 +673,11 @@
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
- CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ CHK( mbedtls_ctr_drbg_seed( &ctx,
+ ctr_drbg_self_test_entropy,
+ (void *) entropy_source_pr,
+ nonce_pers_pr, 16 ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@@ -699,8 +697,11 @@
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0;
- CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ CHK( mbedtls_ctr_drbg_seed( &ctx,
+ ctr_drbg_self_test_entropy,
+ (void *) entropy_source_nopr,
+ nonce_pers_nopr, 16 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 4a97826..01050d9 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -44,11 +44,11 @@
/* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
* where nonce||perso = nonce[nonce->len] */
- TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len(
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len );
+ TEST_ASSERT( mbedtls_ctr_drbg_seed(
&ctx,
mbedtls_test_entropy_func, entropy->x,
- nonce->x, nonce->len,
- entropy_chunk_len ) == 0 );
+ nonce->x, nonce->len ) == 0 );
if( reseed_mode == RESEED_ALWAYS )
mbedtls_ctr_drbg_set_prediction_resistance(
&ctx,