mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-25 13:43:31 +00:00
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:
commit
22589f0a72
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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.
|
||||||
|
@ -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 §10.2.1.4.2)
|
/* 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
|
* 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 §10.2.1.3.2)
|
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §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,
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
@ -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 );
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user