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.
This commit is contained in:
Gilles Peskine 2019-10-04 12:15:55 +02:00
parent 845ac103a9
commit b729e1b9ba
3 changed files with 38 additions and 36 deletions

View file

@ -190,11 +190,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* with mbedtls_entropy_init() (which registers the platform's default * with mbedtls_entropy_init() (which registers the platform's default
* entropy sources). * entropy sources).
* *
* \p f_entropy is always called with a buffer size equal to the entropy * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* length. The entropy length is initially #MBEDTLS_CTR_DRBG_ENTROPY_LEN * You can override it by calling mbedtls_ctr_drbg_set_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.
* *
* You can provide a personalization string in addition to the * You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible. * entropy source, to make this instantiation as unique as possible.
@ -230,6 +227,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* \param f_entropy The entropy callback, taking as arguments the * \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the * \p p_entropy context, the buffer to fill, and the
* length of the buffer. * 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 p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string. * \param custom The personalization string.
* This can be \c NULL, in which case the personalization * This can be \c NULL, in which case the personalization
@ -273,15 +272,10 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
/** /**
* \brief This function sets the amount of entropy grabbed on each * \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. * 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 * \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus \p len must be at least * entropy length. Thus \p len must be at least
* 32 (in bytes) to achieve a 256-bit strength. * 32 (in bytes) to achieve a 256-bit strength.

View file

@ -336,17 +336,11 @@ exit:
return( ret ); return( ret );
} }
/* int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
* Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow int (*f_entropy)(void *, unsigned char *, size_t),
* NIST tests to succeed (which require known length fixed entropy) void *p_entropy,
*/ const unsigned char *custom,
int mbedtls_ctr_drbg_seed_entropy_len( size_t 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 ret; int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
@ -358,7 +352,8 @@ int mbedtls_ctr_drbg_seed_entropy_len(
ctx->f_entropy = f_entropy; ctx->f_entropy = f_entropy;
ctx->p_entropy = p_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; ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
/* /*
@ -376,14 +371,15 @@ int mbedtls_ctr_drbg_seed_entropy_len(
return( 0 ); return( 0 );
} }
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, /* Backward compatibility wrapper */
int (*f_entropy)(void *, unsigned char *, size_t), int mbedtls_ctr_drbg_seed_entropy_len(
void *p_entropy, mbedtls_ctr_drbg_context *ctx,
const unsigned char *custom, int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
size_t len ) 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_set_entropy_len( ctx, entropy_len );
MBEDTLS_CTR_DRBG_ENTROPY_LEN ) ); return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
} }
int mbedtls_ctr_drbg_random_with_add( void *p_rng, int mbedtls_ctr_drbg_random_with_add( void *p_rng,
@ -617,8 +613,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0; test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
(void *) entropy_source_pr, nonce_pers_pr, 16, 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 ); 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 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@ -638,8 +637,11 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_ctr_drbg_init( &ctx ); mbedtls_ctr_drbg_init( &ctx );
test_offset = 0; test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
(void *) entropy_source_nopr, nonce_pers_nopr, 16, 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_random( &ctx, buf, 16 ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );

View file

@ -72,7 +72,10 @@ void ctr_drbg_validate_pr( char *add_init_string, char *entropy_string,
add2_len = unhexify( add2, add2_string ); add2_len = unhexify( add2, add2_string );
test_offset_idx = 0; test_offset_idx = 0;
TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx,
mbedtls_test_entropy_func, entropy,
add_init, add_init_len ) == 0 );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
@ -110,7 +113,10 @@ void ctr_drbg_validate_nopr( char *add_init_string, char *entropy_string,
add2_len = unhexify( add2, add2_string ); add2_len = unhexify( add2, add2_string );
test_offset_idx = 0; test_offset_idx = 0;
TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx,
mbedtls_test_entropy_func, entropy,
add_init, add_init_len ) == 0 );
TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, add_reseed, add_reseed_len ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, add_reseed, add_reseed_len ) == 0 );