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.
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 1106ac8..2db4021 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -10,9 +10,13 @@
* Bit Generators</em>.
*
* 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 @@
* 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 @@
* 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 @@
* 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 @@
/**
* \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.