Merge pull request #305 from gilles-peskine-arm/ctr_drbg-grab_nonce_from_entropy-set_nonce_length

CTR_DRBG: grab a nonce from the entropy source if needed
This commit is contained in:
Gilles Peskine 2019-11-04 10:39:42 +01:00 committed by GitHub
commit 22589f0a72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 317 additions and 125 deletions

View File

@ -12,30 +12,14 @@
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 * 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) * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function. * 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, * The security strength as defined in NIST SP 800-90A is
* here are the security strengths achieved in typical configuration: * 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
* - 256 bits under the default configuration of the library, with AES-256 * and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. * kept at its default value (and not overridden in config.h) and that the
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set * DRBG instance is set up with default parameters.
* to 32 or more, and the DRBG is initialized with an explicit * See the documentation of mbedtls_ctr_drbg_seed() for more
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). * information.
* - 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).
*
* 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.
*/ */
/* /*
* Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
@ -163,20 +147,47 @@
extern "C" { extern "C" {
#endif #endif
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
/** The default length of the nonce read from the entropy source.
*
* This is \c 0 because a single read from the entropy source is sufficient
* to include a nonce.
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
#else
/** The default length of the nonce read from the entropy source.
*
* This is half of the default entropy length because a single read from
* the entropy source does not provide enough material to form a nonce.
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2
#endif
/** /**
* \brief The CTR_DRBG context structure. * \brief The CTR_DRBG context structure.
*/ */
typedef struct mbedtls_ctr_drbg_context typedef struct mbedtls_ctr_drbg_context
{ {
unsigned char counter[16]; /*!< The counter (V). */ unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< The reseed counter. */ int reseed_counter; /*!< The reseed counter.
* This is the number of requests that have
* been made since the last (re)seeding,
* minus one.
* Before the initial seeding, this field
* contains the amount of entropy in bytes
* to use as a nonce for the initial seeding.
*/
int prediction_resistance; /*!< This determines whether prediction int prediction_resistance; /*!< This determines whether prediction
resistance is enabled, that is resistance is enabled, that is
whether to systematically reseed before whether to systematically reseed before
each random generation. */ each random generation. */
size_t entropy_len; /*!< The amount of entropy grabbed on each size_t entropy_len; /*!< The amount of entropy grabbed on each
seed or reseed operation. */ seed or reseed operation, in bytes. */
int reseed_interval; /*!< The reseed interval. */ int reseed_interval; /*!< The reseed interval.
* This is the maximum number of requests
* that can be made between reseedings. */
mbedtls_aes_context aes_ctx; /*!< The AES context. */ mbedtls_aes_context aes_ctx; /*!< The AES context. */
@ -217,43 +228,68 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. * 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 override it by calling mbedtls_ctr_drbg_set_entropy_len().
* *
* You can provide a personalization string in addition to the * The entropy nonce length is:
* entropy source, to make this instantiation as unique as possible. * - \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().
* With the default entropy length, the entropy nonce length is
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
* *
* \note The _seed_material_ value passed to the derivation * You can provide a nonce and personalization string in addition to the
* function in the CTR_DRBG Instantiate Process * entropy source, to make this instantiation as unique as possible.
* described in NIST SP 800-90A §10.2.1.3.2 * See SP 800-90A §8.6.7 for more details about nonces.
* is the concatenation of the string obtained from *
* calling \p f_entropy and the \p custom string. * The _seed_material_ value passed to the derivation function in
* The origin of the nonce depends on the value of * the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2
* the entropy length relative to the security strength. * is the concatenation of the following strings:
* - If the entropy length is at least 1.5 times the * - A string obtained by calling \p f_entropy function for the entropy
* security strength then the nonce is taken from the * length.
* string obtained with \p f_entropy.
* - If the entropy length is less than the security
* strength, then the nonce is taken from \p custom.
* In this case, for compliance with SP 800-90A,
* you must pass a unique value of \p custom at
* each invocation. See SP 800-90A §8.6.7 for more
* details.
*/ */
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 #if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than /**
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the * - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
* maximum security strength permitted by CTR_DRBG, * obtained by calling \p f_entropy function for the specified length.
* you must pass a value of \p custom that is a nonce: */
* this value must never be repeated in subsequent #else
* runs of the same application or on a different /**
* device. * - 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 #endif
/** /**
* - The \p custom string.
*
* \note To achieve the nominal security strength permitted
* by CTR_DRBG, the entropy length must be:
* - at least 16 bytes for a 128-bit strength
* (maximum achievable strength when using AES-128);
* - at least 32 bytes for a 256-bit strength
* (maximum achievable strength when using AES-256).
*
* In addition, if you do not pass a nonce in \p custom,
* the sum of the entropy length
* 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
* (maximum achievable strength when using AES-256).
*
* \param ctx The CTR_DRBG context to seed. * \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
* After a successful call to mbedtls_ctr_drbg_seed(),
* you may not call mbedtls_ctr_drbg_seed() again on
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* \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 * \p f_entropy is always called with a buffer size
* equal to the entropy length. * less than or 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
@ -301,11 +337,6 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
* *
* 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: * entropy length. Thus:
* - When using AES-256 * - When using AES-256
@ -320,11 +351,35 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
* *
* \param ctx The CTR_DRBG context. * \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab, in bytes. * \param len The amount of entropy to grab, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* and at most the maximum length accepted by the
* entropy function that is set in the context.
*/ */
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len ); size_t len );
/**
* \brief This function sets the amount of entropy grabbed
* as a nonce for the initial seeding.
*
* Call this function before calling mbedtls_ctr_drbg_seed() to read
* a nonce from the entropy source during the initial seeding.
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab for the nonce, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* and at most the maximum length accepted by the
* entropy function that is set in the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
* more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
* if the initial seeding has already taken place.
*/
int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/** /**
* \brief This function sets the reseed interval. * \brief This function sets the reseed interval.
* *

View File

@ -139,7 +139,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
* Note that SHA-256 is just as efficient as SHA-224. * Note that SHA-256 is just as efficient as SHA-224.
* The security strength can be reduced if a smaller * The security strength can be reduced if a smaller
* entropy length is set with * entropy length is set with
* mbedtls_hmac_drbg_set_entropy_len() afterwards. * mbedtls_hmac_drbg_set_entropy_len().
* *
* \note The default entropy length is the security strength * \note The default entropy length is the security strength
* (converted from bits to bytes). You can override * (converted from bits to bytes). You can override
@ -222,14 +222,9 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_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
* reseed. * seed or reseed.
* *
* The default value is set by mbedtls_hmac_drbg_seed(). * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
*
* \note mbedtls_hmac_drbg_seed() always sets the entropy length
* to the default value based on the chosen MD algorithm,
* so this function only has an effect if it is called
* after mbedtls_hmac_drbg_seed().
* *
* \param ctx The HMAC_DRBG context. * \param ctx The HMAC_DRBG context.
* \param len The amount of entropy to grab, in bytes. * \param len The amount of entropy to grab, in bytes.

View File

@ -56,6 +56,9 @@
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); 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) #if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex ); mbedtls_mutex_init( &ctx->mutex );
@ -86,6 +89,32 @@ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
ctx->entropy_len = len; 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, void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
int interval ) int interval )
{ {
@ -319,7 +348,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_DEPRECATED_REMOVED */
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2) /* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
* mbedtls_ctr_drbg_reseed(ctx, additional, len) * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
* implements * implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input) * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
* -> new_working_state * -> new_working_state
@ -327,51 +356,57 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
* ctx contains working_state * ctx contains working_state
* additional[:len] = additional_input * additional[:len] = additional_input
* and entropy_input comes from calling ctx->f_entropy * and entropy_input comes from calling ctx->f_entropy
* for (ctx->entropy_len + nonce_len) bytes
* and with output * and with output
* ctx contains new_working_state * ctx contains new_working_state
*/ */
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len ) const unsigned char *additional,
size_t len,
size_t nonce_len )
{ {
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0; size_t seedlen = 0;
int ret; int ret;
if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
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 ); return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
/* /* Gather entropy_len bytes of entropy to seed state. */
* Gather entropy_len bytes of entropy to seed state if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
*/
if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
ctx->entropy_len ) )
{ {
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
} }
seedlen += ctx->entropy_len; seedlen += ctx->entropy_len;
/* /* Gather entropy for a nonce if requested. */
* Add additional data if( nonce_len != 0 )
*/ {
if( additional && len ) 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 )
{ {
memcpy( seed + seedlen, additional, len ); memcpy( seed + seedlen, additional, len );
seedlen += len; seedlen += len;
} }
/* /* Reduce to 384 bits. */
* Reduce to 384 bits
*/
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 ) if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
goto exit; goto exit;
/* /* Update state. */
* Update state
*/
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 ) if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
goto exit; goto exit;
ctx->reseed_counter = 1; ctx->reseed_counter = 1;
@ -381,15 +416,33 @@ exit:
return( ret ); 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 ) );
}
/* 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 &sect;10.2.1.3.2) /* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy, * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* custom, len, entropy_len)
* implements * implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state * security_strength) -> initial_working_state
* with inputs * with inputs
* custom[:len] = nonce || personalization_string * 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 * and with outputs
* ctx = initial_working_state * ctx = initial_working_state
*/ */
@ -401,6 +454,7 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
{ {
int ret; int ret;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
size_t nonce_len;
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
@ -411,18 +465,26 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
if( ctx->entropy_len == 0 ) if( ctx->entropy_len == 0 )
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; 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; 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, if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{ {
return( ret ); return( ret );
} }
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) /* Do the initial seeding. */
if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
nonce_len ) ) != 0 )
{ {
return( ret ); return( ret );
} }
@ -693,6 +755,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
test_offset = 0; test_offset = 0;
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
CHK( mbedtls_ctr_drbg_seed( &ctx, CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy, ctr_drbg_self_test_entropy,
(void *) entropy_source_pr, (void *) entropy_source_pr,
@ -717,6 +780,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
test_offset = 0; test_offset = 0;
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
CHK( mbedtls_ctr_drbg_seed( &ctx, CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy, ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr, (void *) entropy_source_nopr,

View File

@ -686,12 +686,13 @@ int main( int argc, char *argv[] )
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_ctr_drbg_init( &ctr_drbg );
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
mbedtls_exit(1); mbedtls_exit(1);
TIME_AND_TSC( "CTR_DRBG (NOPR)", TIME_AND_TSC( "CTR_DRBG (NOPR)",
mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) ); mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_ctr_drbg_init( &ctr_drbg );
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
mbedtls_exit(1); mbedtls_exit(1);
mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON ); mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );

View File

@ -1070,8 +1070,22 @@ CTR_DRBG CAVS 14.3 (AES-128 use df,True,128,64,0,0) #0
depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
ctr_drbg_validate_pr:"d4f1f4ae08bcb3e1":"5d4041942bcf68864a4997d8171f1f9fef55a769b7eaf03fe082029bb32a2b9d8239e865c0a42e14b964b9c09de85a20":"":"":"4155320287eedcf7d484c2c2a1e2eb64b9c9ce77c87202a1ae1616c7a5cfd1c687c7a0bfcc85bda48fdd4629fd330c22d0a76076f88fc7cd04037ee06b7af602" ctr_drbg_validate_pr:"d4f1f4ae08bcb3e1":"5d4041942bcf68864a4997d8171f1f9fef55a769b7eaf03fe082029bb32a2b9d8239e865c0a42e14b964b9c09de85a20":"":"":"4155320287eedcf7d484c2c2a1e2eb64b9c9ce77c87202a1ae1616c7a5cfd1c687c7a0bfcc85bda48fdd4629fd330c22d0a76076f88fc7cd04037ee06b7af602"
CTR_DRBG entropy usage CTR_DRBG entropy usage (default entropy_nonce_len)
ctr_drbg_entropy_usage: ctr_drbg_entropy_usage:-1
CTR_DRBG entropy usage (entropy_nonce_len=0)
ctr_drbg_entropy_usage:0
CTR_DRBG entropy usage (entropy_nonce_len=7)
ctr_drbg_entropy_usage:7
CTR_DRBG entropy strength: 128 bits
depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
ctr_drbg_entropy_strength:128
CTR_DRBG entropy strength: 256 bits
depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
ctr_drbg_entropy_strength:256
CTR_DRBG write/update seed file [#1] CTR_DRBG write/update seed file [#1]
ctr_drbg_seed_file:"data_files/ctr_drbg_seed":0 ctr_drbg_seed_file:"data_files/ctr_drbg_seed":0

View File

@ -45,6 +45,7 @@ static void ctr_drbg_validate_internal( int reseed_mode, data_t * nonce,
/* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>) /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
* where nonce||perso = nonce[nonce->len] */ * where nonce||perso = nonce[nonce->len] */
mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len ); mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len );
mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
TEST_ASSERT( mbedtls_ctr_drbg_seed( TEST_ASSERT( mbedtls_ctr_drbg_seed(
&ctx, &ctx,
mbedtls_test_entropy_func, entropy->x, mbedtls_test_entropy_func, entropy->x,
@ -187,17 +188,47 @@ void ctr_drbg_validate_reseed_first( data_t * add_init, data_t * entropy,
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */
void ctr_drbg_entropy_strength( int expected_bit_strength )
{
unsigned char entropy[/*initial entropy*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN +
/*nonce*/ MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN +
/*reseed*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN];
mbedtls_ctr_drbg_context ctx;
size_t last_idx;
size_t byte_strength = expected_bit_strength / 8;
mbedtls_ctr_drbg_init( &ctx );
test_offset_idx = 0;
test_max_idx = sizeof( entropy );
memset( entropy, 0, sizeof( entropy ) );
/* The initial seeding must grab at least byte_strength bytes of entropy
* for the entropy input and byte_strength/2 bytes for a nonce. */
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx,
mbedtls_test_entropy_func, entropy,
NULL, 0 ) == 0 );
TEST_ASSERT( test_offset_idx >= ( byte_strength * 3 + 1 ) / 2 );
last_idx = test_offset_idx;
/* A reseed must grab at least byte_strength bytes of entropy. */
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) == 0 );
TEST_ASSERT( test_offset_idx - last_idx >= byte_strength );
exit:
mbedtls_ctr_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void ctr_drbg_entropy_usage( ) void ctr_drbg_entropy_usage( int entropy_nonce_len )
{ {
unsigned char out[16]; unsigned char out[16];
unsigned char add[16]; unsigned char add[16];
unsigned char entropy[1024]; unsigned char entropy[1024];
mbedtls_ctr_drbg_context ctx; mbedtls_ctr_drbg_context ctx;
size_t i, reps = 10; size_t i, reps = 10;
size_t last_idx; size_t expected_idx = 0;
mbedtls_ctr_drbg_init( &ctx ); mbedtls_ctr_drbg_init( &ctx );
test_offset_idx = 0; test_offset_idx = 0;
@ -206,21 +237,27 @@ void ctr_drbg_entropy_usage( )
memset( out, 0, sizeof( out ) ); memset( out, 0, sizeof( out ) );
memset( add, 0, sizeof( add ) ); memset( add, 0, sizeof( add ) );
if( entropy_nonce_len >= 0 )
TEST_ASSERT( mbedtls_ctr_drbg_set_nonce_len( &ctx, entropy_nonce_len ) == 0 );
/* Init must use entropy */ /* Init must use entropy */
last_idx = test_offset_idx;
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
TEST_ASSERT( last_idx < test_offset_idx ); expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
if( entropy_nonce_len >= 0 )
expected_idx += entropy_nonce_len;
else
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, /* By default, PR is off and reseed_interval is large,
* so the next few calls should not use entropy */ * so the next few calls should not use entropy */
last_idx = test_offset_idx;
for( i = 0; i < reps; i++ ) for( i = 0; i < reps; i++ )
{ {
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4, TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
add, sizeof( add ) ) == 0 ); add, sizeof( add ) ) == 0 );
} }
TEST_ASSERT( last_idx == test_offset_idx ); TEST_EQUAL( test_offset_idx, expected_idx );
/* While at it, make sure we didn't write past the requested length */ /* While at it, make sure we didn't write past the requested length */
TEST_ASSERT( out[sizeof( out ) - 4] == 0 ); TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
@ -232,17 +269,17 @@ void ctr_drbg_entropy_usage( )
* so the next call should reseed */ * so the next call should reseed */
mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps ); mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( last_idx < test_offset_idx ); expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
TEST_EQUAL( test_offset_idx, expected_idx );
/* The new few calls should not reseed */ /* The new few calls should not reseed */
last_idx = test_offset_idx;
for( i = 0; i < reps / 2; i++ ) for( i = 0; i < reps / 2; i++ )
{ {
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) , TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
add, sizeof( add ) ) == 0 ); add, sizeof( add ) ) == 0 );
} }
TEST_ASSERT( last_idx == test_offset_idx ); TEST_EQUAL( test_offset_idx, expected_idx );
/* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT). /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
* Make sure it's detected as an error and doesn't cause memory * Make sure it's detected as an error and doesn't cause memory
@ -253,18 +290,19 @@ void ctr_drbg_entropy_usage( )
/* Now enable PR, so the next few calls should all reseed */ /* Now enable PR, so the next few calls should all reseed */
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( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( last_idx < test_offset_idx ); expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
TEST_EQUAL( test_offset_idx, expected_idx );
/* Finally, check setting entropy_len */ /* Finally, check setting entropy_len */
mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 );
last_idx = test_offset_idx;
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( test_offset_idx - last_idx == 42 ); expected_idx += 42;
TEST_EQUAL( test_offset_idx, expected_idx );
mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 ); mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 );
last_idx = test_offset_idx;
TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( test_offset_idx - last_idx == 13 ); expected_idx += 13;
TEST_EQUAL( test_offset_idx, expected_idx );
exit: exit:
mbedtls_ctr_drbg_free( &ctx ); mbedtls_ctr_drbg_free( &ctx );

View File

@ -37,7 +37,9 @@ void hmac_drbg_entropy_usage( int md_alg )
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_hmac_drbg_context ctx; mbedtls_hmac_drbg_context ctx;
entropy_ctx entropy; entropy_ctx entropy;
size_t last_len, i, reps = 10; size_t i, reps = 10;
size_t default_entropy_len;
size_t expected_consumed_entropy = 0;
mbedtls_hmac_drbg_init( &ctx ); mbedtls_hmac_drbg_init( &ctx );
memset( buf, 0, sizeof( buf ) ); memset( buf, 0, sizeof( buf ) );
@ -48,23 +50,29 @@ void hmac_drbg_entropy_usage( int md_alg )
md_info = mbedtls_md_info_from_type( md_alg ); md_info = mbedtls_md_info_from_type( md_alg );
TEST_ASSERT( md_info != NULL ); TEST_ASSERT( md_info != NULL );
if( mbedtls_md_get_size( md_info ) <= 20 )
default_entropy_len = 16;
else if( mbedtls_md_get_size( md_info ) <= 28 )
default_entropy_len = 24;
else
default_entropy_len = 32;
/* Init must use entropy */ /* Init must use entropy */
last_len = entropy.len;
TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy, TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy,
NULL, 0 ) == 0 ); NULL, 0 ) == 0 );
TEST_ASSERT( entropy.len < last_len ); /* 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, /* By default, PR is off and reseed_interval is large,
* so the next few calls should not use entropy */ * so the next few calls should not use entropy */
last_len = entropy.len;
for( i = 0; i < reps; i++ ) for( i = 0; i < reps; i++ )
{ {
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) - 4, TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
buf, 16 ) == 0 ); buf, 16 ) == 0 );
} }
TEST_ASSERT( entropy.len == last_len ); TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
/* While at it, make sure we didn't write past the requested length */ /* While at it, make sure we didn't write past the requested length */
TEST_ASSERT( out[sizeof( out ) - 4] == 0 ); TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
@ -76,33 +84,34 @@ void hmac_drbg_entropy_usage( int md_alg )
* so the next call should reseed */ * so the next call should reseed */
mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps ); mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( entropy.len < last_len ); expected_consumed_entropy += default_entropy_len;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
/* The new few calls should not reseed */ /* The new few calls should not reseed */
last_len = entropy.len;
for( i = 0; i < reps / 2; i++ ) for( i = 0; i < reps / 2; i++ )
{ {
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) , TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) ,
buf, 16 ) == 0 ); buf, 16 ) == 0 );
} }
TEST_ASSERT( entropy.len == last_len ); TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
/* Now enable PR, so the next few calls should all reseed */ /* Now enable PR, so the next few calls should all reseed */
mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( entropy.len < last_len ); expected_consumed_entropy += default_entropy_len;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
/* Finally, check setting entropy_len */ /* Finally, check setting entropy_len */
mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 ); mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 );
last_len = entropy.len;
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( (int) last_len - entropy.len == 42 ); expected_consumed_entropy += 42;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 ); mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 );
last_len = entropy.len;
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( (int) last_len - entropy.len == 13 ); expected_consumed_entropy += 13;
TEST_EQUAL( sizeof( buf ) - entropy.len, expected_consumed_entropy );
exit: exit:
mbedtls_hmac_drbg_free( &ctx ); mbedtls_hmac_drbg_free( &ctx );

View File

@ -34,15 +34,25 @@ fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:0:PSA_ERROR_INSUFFICIENT_EN
Fake entropy: less than the block size Fake entropy: less than the block size
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY
Fake entropy: not enough for a nonce
depends_on:ENTROPY_NONCE_LEN != 0
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:ENTROPY_NONCE_LEN - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY
Fake entropy: one block eventually Fake entropy: one block eventually
depends_on:ENTROPY_NONCE_LEN == 0
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS
Fake entropy: one block in two steps Fake entropy: one block in two steps
depends_on:ENTROPY_NONCE_LEN == 0
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:1:-1:-1:PSA_SUCCESS fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:1:-1:-1:PSA_SUCCESS
Fake entropy: more than one block in two steps Fake entropy: more than one block in two steps
depends_on:ENTROPY_NONCE_LEN == 0
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:PSA_SUCCESS fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:PSA_SUCCESS
Fake entropy: two blocks eventually
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS
NV seed only: less than minimum NV seed only: less than minimum
entropy_from_nv_seed:MBEDTLS_ENTROPY_MIN_PLATFORM - 1:PSA_ERROR_INSUFFICIENT_ENTROPY entropy_from_nv_seed:MBEDTLS_ENTROPY_MIN_PLATFORM - 1:PSA_ERROR_INSUFFICIENT_ENTROPY

View File

@ -11,6 +11,12 @@
#define ENTROPY_MIN_NV_SEED_SIZE \ #define ENTROPY_MIN_NV_SEED_SIZE \
MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE) MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
/* PSA crypto uses the CTR_DRBG module. In some configurations, it needs
* to read from the entropy source twice: once for the initial entropy
* and once for a nonce. */
#include "mbedtls/ctr_drbg.h"
#define ENTROPY_NONCE_LEN MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN
typedef struct typedef struct
{ {
size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */ size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */