CTR_DRBG: grab a nonce from the entropy source if needed
Change the default entropy nonce length to be nonzero in some cases. Specifically, the default nonce length is now set in such a way that the entropy input during the initial seeding always contains enough entropy to achieve the maximum possible security strength per NIST SP 800-90A given the key size and entropy length. If MBEDTLS_CTR_DRBG_ENTROPY_LEN is kept to its default value, mbedtls_ctr_drbg_seed() now grabs extra entropy for a nonce if MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled and either MBEDTLS_ENTROPY_FORCE_SHA256 is enabled or MBEDTLS_SHA512_C is disabled. If MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled, or if the entropy module uses SHA-512, then the default value of MBEDTLS_CTR_DRBG_ENTROPY_LEN does not require a second call to the entropy function to achieve the maximum security strength. This choice of default nonce size guarantees NIST compliance with the maximum security strength while keeping backward compatibility and performance high: in configurations that do not require grabbing more entropy, the code will not grab more entropy than before.
This commit is contained in:
parent
0ed378aa02
commit
e9a3454e09
4 changed files with 88 additions and 41 deletions
|
@ -12,36 +12,14 @@
|
|||
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
|
||||
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
|
||||
* as the underlying block cipher, with a derivation function.
|
||||
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
|
||||
* See the documentation of mbedtls_ctr_drbg_seed() for more details.
|
||||
*
|
||||
* Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
|
||||
* here are the security strengths achieved in typical configuration:
|
||||
* - 256 bits under the default configuration of the library, with AES-256
|
||||
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
|
||||
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
|
||||
* to 32 or more, and the DRBG is initialized with an explicit
|
||||
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
|
||||
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
|
||||
* to 32 or more, and mbedtls_ctr_drbg_set_nonce_len() is called to set
|
||||
* an entropy nonce length of 16 bytes or more.
|
||||
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
|
||||
* between 24 and 47 and the DRBG is not initialized with an explicit
|
||||
* nonce (see mbedtls_ctr_drbg_seed()).
|
||||
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
|
||||
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
|
||||
* always the case unless it is explicitly set to a different value
|
||||
* in config.h).
|
||||
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
|
||||
* to 16 or more, and mbedtls_ctr_drbg_set_nonce_len() is called to set
|
||||
* an entropy nonce length of 8 bytes or more.
|
||||
*
|
||||
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
|
||||
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
|
||||
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
|
||||
* This is the default configuration of the library.
|
||||
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
|
||||
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
|
||||
* The security strength as defined in NIST SP 800-90A is
|
||||
* 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
|
||||
* and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
|
||||
* kept at its default value (and not overridden in config.h) and that the
|
||||
* DRBG instance is set up with default parameters.
|
||||
* See the documentation of mbedtls_ctr_drbg_seed() for more
|
||||
* information.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
|
||||
|
@ -232,6 +210,26 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
|||
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
|
||||
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
|
||||
*
|
||||
* The entropy nonce length is:
|
||||
* - \c 0 if the entropy length is at least 3/2 times the entropy length,
|
||||
* which guarantees that the security strength is the maximum permitted
|
||||
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
|
||||
* - Half the entropy length otherwise.
|
||||
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
|
||||
*/
|
||||
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
|
||||
/** With the default entropy length, the entropy nonce length is \c 0.
|
||||
*/
|
||||
#elif MBEDTLS_CTR_DRBG_ENTROPY_LEN & 1
|
||||
/** With the default entropy length, the entropy nonce length is
|
||||
* (#MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2.
|
||||
*/
|
||||
#else
|
||||
/** With the default entropy length, the entropy nonce length is
|
||||
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN / 2.
|
||||
*/
|
||||
#endif
|
||||
/**
|
||||
* You can provide a nonce and personalization string in addition to the
|
||||
* entropy source, to make this instantiation as unique as possible.
|
||||
* See SP 800-90A §8.6.7 for more details about nonces.
|
||||
|
@ -241,10 +239,20 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
|||
* is the concatenation of the following strings:
|
||||
* - A string obtained by calling \p f_entropy function for the entropy
|
||||
* length.
|
||||
* - A string obtained by calling \p f_entropy function for the nonce
|
||||
* length set with mbedtls_ctr_drbg_set_nonce_len(). If the entropy
|
||||
* nonce length is \c 0, this function does not make a second call
|
||||
* to \p f_entropy.
|
||||
*/
|
||||
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
|
||||
/**
|
||||
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
|
||||
* obtained by calling \p f_entropy function for the specified length.
|
||||
*/
|
||||
#else
|
||||
/**
|
||||
* - A string obtained by calling \p f_entropy function for the entropy nonce
|
||||
* length. If the entropy nonce length is \c 0, this function does not
|
||||
* make a second call to \p f_entropy.
|
||||
*/
|
||||
#endif
|
||||
/**
|
||||
* - The \p custom string.
|
||||
*
|
||||
* \note To achieve the nominal security strength permitted
|
||||
|
@ -256,10 +264,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
|||
*
|
||||
* In addition, if you do not pass a nonce in \p custom,
|
||||
* the sum of the entropy length
|
||||
* (#MBEDTLS_CTR_DRBG_ENTROPY_LEN unless overridden with
|
||||
* mbedtls_ctr_drbg_set_entropy_len())
|
||||
* and the entropy nonce length (\c 0 unless overridden
|
||||
* with mbedtls_ctr_drbg_set_nonce_len()) must be:
|
||||
* and the entropy nonce length must be:
|
||||
* - at least 24 bytes for a 128-bit strength
|
||||
* (maximum achievable strength when using AES-128);
|
||||
* - at least 48 bytes for a 256-bit strength
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
|
||||
/* Indicate that the entropy nonce length is not set explicitly.
|
||||
* See mbedtls_ctr_drbg_set_nonce_len(). */
|
||||
ctx->reseed_counter = -1;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
|
@ -419,6 +422,19 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
|||
return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
|
||||
}
|
||||
|
||||
/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
|
||||
* is sufficient to achieve the maximum security strength given the key
|
||||
* size and entropy length. If there is enough entropy in the initial
|
||||
* call to the entropy function to serve as both the entropy input and
|
||||
* the nonce, don't make a second call to get a nonce. */
|
||||
static size_t good_nonce_len( size_t entropy_len )
|
||||
{
|
||||
if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
|
||||
return( 0 );
|
||||
else
|
||||
return( ( entropy_len + 1 ) / 2 );
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -438,6 +454,7 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
|||
{
|
||||
int ret;
|
||||
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
|
||||
size_t nonce_len;
|
||||
|
||||
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
|
||||
|
||||
|
@ -448,6 +465,14 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
|||
|
||||
if( ctx->entropy_len == 0 )
|
||||
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
|
||||
/* ctx->reseed_counter contains the desired amount of entropy to
|
||||
* grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
|
||||
* If it's -1, indicating that the entropy nonce length was not set
|
||||
* explicitly, use a sufficiently large nonce for security. */
|
||||
nonce_len = ( ctx->reseed_counter >= 0 ?
|
||||
(size_t) ctx->reseed_counter :
|
||||
good_nonce_len( ctx->entropy_len ) );
|
||||
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
|
||||
/* Initialize with an empty key. */
|
||||
|
@ -457,11 +482,9 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
|||
return( ret );
|
||||
}
|
||||
|
||||
/* 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()). */
|
||||
/* Do the initial seeding. */
|
||||
if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
|
||||
ctx->reseed_counter ) ) != 0 )
|
||||
nonce_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
|
|
@ -1071,6 +1071,11 @@ depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
|
|||
ctr_drbg_validate_pr:"d4f1f4ae08bcb3e1":"5d4041942bcf68864a4997d8171f1f9fef55a769b7eaf03fe082029bb32a2b9d8239e865c0a42e14b964b9c09de85a20":"":"":"4155320287eedcf7d484c2c2a1e2eb64b9c9ce77c87202a1ae1616c7a5cfd1c687c7a0bfcc85bda48fdd4629fd330c22d0a76076f88fc7cd04037ee06b7af602"
|
||||
|
||||
CTR_DRBG entropy usage (entropy_nonce_len=0 by default)
|
||||
depends_on:!DEFAULT_ENTROPY_NONCE
|
||||
ctr_drbg_entropy_usage:-1
|
||||
|
||||
CTR_DRBG entropy usage (entropy_nonce_len=entropy_len/2 by default)
|
||||
depends_on:DEFAULT_ENTROPY_NONCE
|
||||
ctr_drbg_entropy_usage:-1
|
||||
|
||||
CTR_DRBG entropy usage (entropy_nonce_len=0)
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "string.h"
|
||||
|
||||
/* mbedtls_ctr_drbg_seed() grabs a nonce by default if the entropy
|
||||
* length is smaller than 3/2 times the maximum security strength. */
|
||||
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
|
||||
#undef DEFAULT_ENTROPY_NONCE
|
||||
#else
|
||||
#define DEFAULT_ENTROPY_NONCE
|
||||
#endif
|
||||
|
||||
/* Modes for ctr_drbg_validate */
|
||||
enum reseed_mode
|
||||
{
|
||||
|
@ -215,6 +223,12 @@ void ctr_drbg_entropy_usage( int entropy_nonce_len )
|
|||
expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
|
||||
if( entropy_nonce_len >= 0 )
|
||||
expected_idx += entropy_nonce_len;
|
||||
else
|
||||
{
|
||||
#if defined(DEFAULT_ENTROPY_NONCE)
|
||||
expected_idx += ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2;
|
||||
#endif
|
||||
}
|
||||
TEST_EQUAL( test_offset_idx, expected_idx );
|
||||
|
||||
/* By default, PR is off and reseed_interval is large,
|
||||
|
|
Loading…
Reference in a new issue