Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support set *_drbg reseed interval before seed #3393

Merged
merged 2 commits into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog.d/bugfix-2927.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Bugfix
* In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
Fixes #2927.
8 changes: 7 additions & 1 deletion include/mbedtls/ctr_drbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ mbedtls_ctr_drbg_context;
* and prepares it for mbedtls_ctr_drbg_seed()
* or mbedtls_ctr_drbg_free().
*
* \note The reseed interval is
* #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
* You can override it by calling
* mbedtls_ctr_drbg_set_reseed_interval().
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a changelog entry file in ChangeLog.d. Suggested content:

Bugfix
   * In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
     Fixes #2927.

* \param ctx The CTR_DRBG context to initialize.
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
Expand Down Expand Up @@ -309,7 +314,8 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
size_t len );

/**
* \brief This function clears CTR_CRBG context data.
* \brief This function resets CTR_DRBG context to the state immediately
* after initial call of mbedtls_ctr_drbg_init().
*
* \param ctx The CTR_DRBG context to clear.
*/
Expand Down
7 changes: 6 additions & 1 deletion include/mbedtls/hmac_drbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ typedef struct mbedtls_hmac_drbg_context
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
*
* \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
* by default. Override this value by calling
* mbedtls_hmac_drbg_set_reseed_interval().
*
* \param ctx HMAC_DRBG context to be initialized.
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
Expand Down Expand Up @@ -334,7 +338,8 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );

/**
* \brief Free an HMAC_DRBG context
* \brief This function resets HMAC_DRBG context to the state immediately
* after initial call of mbedtls_hmac_drbg_init().
*
* \param ctx The HMAC_DRBG context to free.
*/
Expand Down
13 changes: 11 additions & 2 deletions library/ctr_drbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,17 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
* See mbedtls_ctr_drbg_set_nonce_len(). */
ctx->reseed_counter = -1;

ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;

#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
}

/*
* This function resets CTR_DRBG context to the state immediately
* after initial call of mbedtls_ctr_drbg_init().
*/
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
{
if( ctx == NULL )
Expand All @@ -70,6 +76,11 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
#endif
mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
ctx->reseed_counter = -1;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
}

void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
Expand Down Expand Up @@ -468,8 +479,6 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
(size_t) ctx->reseed_counter :
good_nonce_len( ctx->entropy_len ) );

ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;

/* Initialize with an empty key. */
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
Expand Down
11 changes: 8 additions & 3 deletions library/hmac_drbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );

ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;

#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
Expand Down Expand Up @@ -266,8 +268,6 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;

ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;

if( ctx->entropy_len == 0 )
{
/*
Expand Down Expand Up @@ -412,7 +412,8 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len
}

/*
* Free an HMAC_DRBG context
* This function resets HMAC_DRBG context to the state immediately
* after initial call of mbedtls_hmac_drbg_init().
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
{
Expand All @@ -424,6 +425,10 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
#endif
mbedtls_md_free( &ctx->md_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
}

#if defined(MBEDTLS_FS_IO)
Expand Down
18 changes: 11 additions & 7 deletions tests/suites/test_suite_ctr_drbg.function
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ void ctr_drbg_entropy_usage( int entropy_nonce_len )
if( entropy_nonce_len >= 0 )
TEST_ASSERT( mbedtls_ctr_drbg_set_nonce_len( &ctx, entropy_nonce_len ) == 0 );

/* Set reseed interval before seed */
mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );

/* Init must use entropy */
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
Expand All @@ -249,8 +252,8 @@ void ctr_drbg_entropy_usage( int entropy_nonce_len )
expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN;
TEST_EQUAL( test_offset_idx, expected_idx );

/* By default, PR is off and reseed_interval is large,
* so the next few calls should not use entropy */
/* By default, PR is off, and reseed interval was set to
* 2 * reps so the next few calls should not use entropy */
for( i = 0; i < reps; i++ )
{
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
Expand All @@ -265,15 +268,16 @@ void ctr_drbg_entropy_usage( int entropy_nonce_len )
TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
TEST_ASSERT( out[sizeof( out ) - 1] == 0 );

/* Set reseed_interval to the number of calls done,
* so the next call should reseed */
mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
/* There have been 2 * reps calls to random. The next call should reseed */
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
TEST_EQUAL( test_offset_idx, expected_idx );

/* The new few calls should not reseed */
for( i = 0; i < reps / 2; i++ )
/* Set reseed interval after seed */
mbedtls_ctr_drbg_set_reseed_interval( &ctx, 4 * reps + 1 );

/* The next few calls should not reseed */
for( i = 0; i < (2 * reps); i++ )
{
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
Expand Down
18 changes: 11 additions & 7 deletions tests/suites/test_suite_hmac_drbg.function
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,18 @@ void hmac_drbg_entropy_usage( int md_alg )
else
default_entropy_len = 32;

/* Set reseed interval before seed */
mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );

/* Init must use entropy */
TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy,
NULL, 0 ) == 0 );
/* default_entropy_len of entropy, plus half as much for the nonce */
expected_consumed_entropy += default_entropy_len * 3 / 2;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );

/* By default, PR is off and reseed_interval is large,
* so the next few calls should not use entropy */
/* By default, PR is off, and reseed interval was set to
* 2 * reps so the next few calls should not use entropy */
for( i = 0; i < reps; i++ )
{
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
Expand All @@ -80,15 +83,16 @@ void hmac_drbg_entropy_usage( int md_alg )
TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
TEST_ASSERT( out[sizeof( out ) - 1] == 0 );

/* Set reseed_interval to the number of calls done,
* so the next call should reseed */
mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
/* There have been 2 * reps calls to random. The next call should reseed */
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
expected_consumed_entropy += default_entropy_len;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );

/* Set reseed interval after seed */
mbedtls_hmac_drbg_set_reseed_interval( &ctx, 4 * reps + 1);

/* The new few calls should not reseed */
for( i = 0; i < reps / 2; i++ )
for( i = 0; i < (2 * reps); i++ )
{
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) ,
Expand Down Expand Up @@ -199,7 +203,7 @@ void hmac_drbg_no_reseed( int md_alg, data_t * entropy,
TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
add2->x, add2->len ) == 0 );

/* clear for second run */
/* Reset context for second run */
mbedtls_hmac_drbg_free( &ctx );

TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
Expand Down