From dddda81fbc874846eda78cecf7f0806642145bba Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:22:04 +0200 Subject: [PATCH] mbedtls_ctr_drbg_set_entropy_len() only matters when reseeding The documentation of CTR_DRBG erroneously claimed that mbedtls_ctr_drbg_set_entropy_len() had an impact on the initial seeding. This is in fact not the case: mbedtls_ctr_drbg_seed() forces the initial seeding to grab MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy. Fix the documentation and rewrite the discussion of the entropy length and the security strength accordingly. --- include/mbedtls/ctr_drbg.h | 106 ++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 1106ac873..2db402133 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -10,9 +10,13 @@ * Bit Generators. * * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * as the underlying block cipher, with a derivation function. The security - * strength is: * (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 @@ -102,29 +106,31 @@ * \{ */ +/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN + * + * \brief The amount of entropy used per seed by default, in bytes. + */ #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) -/** The amount of entropy used per seed by default. - * - * This is 48 bytes because the entropy module uses SHA-512 +/** This is 48 bytes because the entropy module uses SHA-512 * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). - * - * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are - * acceptable. */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 -#else -/** The amount of entropy used per seed by default. - * - * This is 32 bytes because the entropy module uses SHA-256 - * (the SHA512 module is disabled or #MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). - * - * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are - * acceptable. + +#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ + +/** This is 32 bytes because the entropy module uses SHA-256 + * (the SHA512 module is disabled or + * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). */ +#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) +/** \warning To achieve a 256-bit security strength, you must pass a nonce + * to mbedtls_ctr_drbg_seed(). + */ +#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -#endif -#endif +#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ +#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 @@ -209,7 +215,10 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * entropy sources). * * \p f_entropy is always called with a buffer size equal to the entropy - * length described in the documentation of mbedtls_ctr_drbg_set_entropy_len(). + * length. The entropy length is initially #MBEDTLS_CTR_DRBG_ENTROPY_LEN + * and this value is always used for the initial seeding. You can change + * the entropy length for subsequent seeding by calling + * mbedtls_ctr_drbg_set_entropy_len() after this function. * * You can provide a personalization string in addition to the * entropy source, to make this instantiation as unique as possible. @@ -221,9 +230,6 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * calling \p f_entropy and the \p custom string. * The origin of the nonce depends on the value of * the entropy length relative to the security strength. - * See the documentation of - * mbedtls_ctr_drbg_set_entropy_len() for information - * about the entropy length. * - If the entropy length is at least 1.5 times the * security strength then the nonce is taken from the * string obtained with \p f_entropy. @@ -233,7 +239,18 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * 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 +/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than + * #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the + * maximum security strength permitted by CTR_DRBG, + * you must pass a value of \p custom that is a nonce: + * this value must never be repeated in subsequent + * runs of the same application or on a different + * device. + */ +#endif +/** * \param ctx The CTR_DRBG context to seed. * \param f_entropy The entropy callback, taking as arguments the * \p p_entropy context, the buffer to fill, and the @@ -281,37 +298,26 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, /** * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. + * subsequent reseed. * * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * - * \note For compliance with NIST SP 800-90A, the entropy length - * (\p len bytes = \p len * 8 bits) - * must be at least the security strength. - * Furthermore, if the entropy input is used to provide - * the nonce, the entropy length must be 1.5 times - * the security strength. - * Per NIST SP 800-57A table 2, the achievable security - * strength is 128 bits if using AES-128 and - * 256 bits if using AES-256. + * \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(). * - * To achieve 256-bit security, - * you must use AES-256 and - * the entropy input must be at least: - * - 48 bytes if the \p custom argument to - * mbedtls_ctr_drbg_seed() may repeat (for example - * because it is empty, or more generally constant); - * - 32 bytes if the \p custom argument to - * mbedtls_ctr_drbg_seed() includes a nonce. - * - * To achieve 128-bit security, - * whether AES-128 or AES-256 is used, - * the entropy input must be at least: - * - 24 bytes if the \p custom argument to - * mbedtls_ctr_drbg_seed() may repeat (for example - * because it is empty, or more generally constant); - * - 16 bytes if the \p custom argument to - * mbedtls_ctr_drbg_seed() includes a nonce. + * \note The security strength of CTR_DRBG is bounded by the + * entropy length. Thus: + * - When using AES-256 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, + * which is the default), + * \p len must be at least 32 (in bytes) + * to achieve a 256-bit strength. + * - When using AES-128 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) + * \p len must be at least 16 (in bytes) + * to achieve a 128-bit strength. * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes.