mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-29 11:41:15 +03:00
CTR_DRBG: add the possibility of grabbing entropy for a nonce
Add a new function mbedtls_ctr_drbg_set_nonce_len() which configures the DRBG instance to call f_entropy a second time during the initial seeding to grab a nonce. The default nonce length is 0, so there is no behavior change unless the user calls the new function.
This commit is contained in:
@ -86,6 +86,32 @@ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
|
||||
ctx->entropy_len = len;
|
||||
}
|
||||
|
||||
int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
|
||||
size_t len )
|
||||
{
|
||||
/* If mbedtls_ctr_drbg_seed() has already been called, it's
|
||||
* too late. Return the error code that's closest to making sense. */
|
||||
if( ctx->f_entropy != NULL )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
|
||||
if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
#if SIZE_MAX > INT_MAX
|
||||
/* This shouldn't be an issue because
|
||||
* MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
|
||||
* configuration, but make sure anyway. */
|
||||
if( len > INT_MAX )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
#endif
|
||||
|
||||
/* For backward compatibility with Mbed TLS <= 2.19, store the
|
||||
* entropy nonce length in a field that already exists, but isn't
|
||||
* used until after the initial seeding. */
|
||||
/* Due to the capping of len above, the value fits in an int. */
|
||||
ctx->reseed_counter = (int) len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
|
||||
int interval )
|
||||
{
|
||||
@ -319,7 +345,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
|
||||
* mbedtls_ctr_drbg_reseed(ctx, additional, len)
|
||||
* mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
|
||||
* implements
|
||||
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
|
||||
* -> new_working_state
|
||||
@ -327,11 +353,14 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
* ctx contains working_state
|
||||
* additional[:len] = additional_input
|
||||
* and entropy_input comes from calling ctx->f_entropy
|
||||
* for (ctx->entropy_len + nonce_len) bytes
|
||||
* and with output
|
||||
* ctx contains new_working_state
|
||||
*/
|
||||
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len )
|
||||
int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t len,
|
||||
size_t nonce_len )
|
||||
{
|
||||
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen = 0;
|
||||
@ -339,7 +368,9 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
|
||||
if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
|
||||
if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
|
||||
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
|
||||
@ -351,6 +382,16 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
}
|
||||
seedlen += ctx->entropy_len;
|
||||
|
||||
/* Gather entropy for a nonce if requested. */
|
||||
if( nonce_len != 0 )
|
||||
{
|
||||
if( 0 != ctx->f_entropy( ctx->p_entropy, seed, nonce_len ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
}
|
||||
seedlen += nonce_len;
|
||||
}
|
||||
|
||||
/* Add additional data if provided. */
|
||||
if( additional != NULL && len != 0 )
|
||||
{
|
||||
@ -372,6 +413,12 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len )
|
||||
{
|
||||
return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
|
||||
}
|
||||
|
||||
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
|
||||
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
|
||||
* implements
|
||||
@ -403,16 +450,18 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
||||
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
|
||||
/*
|
||||
* Initialize with an empty key
|
||||
*/
|
||||
/* Initialize with an empty key. */
|
||||
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
|
||||
/* Do the initial seeding.
|
||||
* ctx->reseed_counter contains the desired amount of entropy to
|
||||
* grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()). */
|
||||
if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
|
||||
ctx->reseed_counter ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
Reference in New Issue
Block a user