From 6b2c50c01f7c1e8a56bb86e4d38cf90282470613 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 24 Sep 2019 14:40:40 +0200 Subject: [PATCH 01/26] CTR_DRBG documentation clarifications * State explicit whether several numbers are in bits or bytes. * Clarify whether buffer pointer parameters can be NULL. * Explain the value of constants that are dependent on the configuration. --- include/mbedtls/ctr_drbg.h | 60 ++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index cc3df7b11..1b4a24b61 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -15,7 +15,7 @@ * keys and operations that use random values generated to 128-bit security. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -56,9 +56,19 @@ #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#define MBEDTLS_CTR_DRBG_KEYSIZE 16 /**< The key size used by the cipher (compile-time choice: 128 bits). */ +#define MBEDTLS_CTR_DRBG_KEYSIZE 16 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 16 bytes (128 bits) + * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is set. + */ #else -#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher (compile-time choice: 256 bits). */ +#define MBEDTLS_CTR_DRBG_KEYSIZE 32 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 32 bytes (256 bits) + * because `MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` is not set. + */ #endif #define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ @@ -75,17 +85,25 @@ #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 + * (`MBEDTLS_ENTROPY_FORCE_SHA256` is not set). + * + * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are + * acceptable. + */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 -/**< The amount of entropy used per seed by default: - * - */ #else -#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -/**< Amount of entropy used per seed by default: - * +/** The amount of entropy used per seed by default. + * + * This is 32 bytes because the entropy module uses SHA-256 + * (the SHA-512 module is disabled or `MBEDTLS_ENTROPY_FORCE_SHA256` is set). + * + * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are + * acceptable. */ +#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 #endif #endif @@ -106,7 +124,7 @@ #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 -/**< The maximum size of seed or reseed buffer. */ +/**< The maximum size of seed or reseed buffer in bytes. */ #endif /* \} name SECTION: Module settings */ @@ -170,10 +188,12 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \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 - length of the buffer. + * length of the buffer. * \param p_entropy The entropy context. * \param custom Personalization data, that is device-specific - identifiers. Can be NULL. + * identifiers. This can be NULL, in which case the + * personalization data is empty regardless of the value + * of \p len. * \param len The length of the personalization data. * * \return \c 0 on success. @@ -213,7 +233,7 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab. + * \param len The amount of entropy to grab, in bytes. */ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ); @@ -246,7 +266,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, * \brief This function updates the state of the CTR_DRBG context. * * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. + * \param additional The data to update the state with. This must not be + * null unless \p add_len is 0. * \param add_len Length of \p additional in bytes. This must be at * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * @@ -270,8 +291,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. * \param output_len The length of the buffer. - * \param additional Additional data to update. Can be NULL. - * \param add_len The length of the additional data. + * \param additional Additional data to update. Can be NULL, in which + * case the additional data is empty regardless of + * the value of \p add_len. + * \param add_len The length of the additional data + * if \p additional is non-null. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or From 80b3f4b20aa40afa31ee580acd22703d4dc3f344 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 24 Sep 2019 14:48:30 +0200 Subject: [PATCH 02/26] CTR_DRBG: Document the maximum size of some parameters --- include/mbedtls/ctr_drbg.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 1b4a24b61..58b9a65d8 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -195,6 +195,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * personalization data is empty regardless of the value * of \p len. * \param len The length of the personalization data. + * This must be at most + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT / 2. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -234,6 +236,7 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. + * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. */ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ); @@ -255,6 +258,10 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, * \param ctx The CTR_DRBG context. * \param additional Additional data to add to the state. Can be NULL. * \param len The length of the additional data. + * This must be less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -296,6 +303,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * the value of \p add_len. * \param add_len The length of the additional data * if \p additional is non-null. + * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT + * and less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or From 1eb7ba7cdd6ec4938c8791b5759bafb3cbc175d4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 24 Sep 2019 14:48:53 +0200 Subject: [PATCH 03/26] CTR_DRBG: Document the security strength and SP 800-90A compliance Document that a derivation function is used. Document the security strength of the DRBG depending on the compile-time configuration and how it is set up. In particular, document how the nonce specified in SP 800-90A is set. Mention how to link the ctr_drbg module with the entropy module. --- include/mbedtls/ctr_drbg.h | 55 +++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 58b9a65d8..05a2aba2c 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -9,9 +9,22 @@ * Bit Generators. * * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * as the underlying block cipher. + * as the underlying block cipher, with a derivation function. The security + * strength is: + * - 256 bits under the default configuration of the library, with AES-256 + * (`MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` not set) 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 + * - 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 (`MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` set) + * 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`). * - * \warning Using 128-bit keys for CTR_DRBG limits the security of generated + * \warning Using 128-bit keys for CTR_DRBG or using SHA-256 as the entropy + * compression function limits the security of generated * keys and operations that use random values generated to 128-bit security. */ /* @@ -182,8 +195,35 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \brief This function seeds and sets up the CTR_DRBG * entropy source for future reseeds. * - * \note Personalization data can be provided in addition to the more generic - * entropy source, to make this instantiation as unique as possible. + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). + * + * Personalization data can be provided in addition to the more generic + * entropy source, to make this instantiation as unique as possible. + * + * \note The _seed_material_ value passed to the derivation + * function in the CTR_DRBG Instantiate Process + * described in NIST SP 800-90A §10.2.1.3.2 + * is the concatenation of the string obtained from + * 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. + * - 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. * * \param ctx The CTR_DRBG context to seed. * \param f_entropy The entropy callback, taking as arguments the @@ -234,6 +274,13 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, * seed or reseed. The default value is * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * + * \note For compliance with NIST SP 800-90A, the entropy length + * must be at least 1.5 times security strength, since + * the entropy source is used both as the entropy input + * and to provide the initial nonce: + * - 24 bytes if using AES-128; + * - 48 bytes if using AES-256. + * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. From 3c3bf4dfdbc95d43bd6cba4d6948da16516dcb3e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 24 Sep 2019 14:52:32 +0200 Subject: [PATCH 04/26] CTR_DRBG documentation: add changelog entry This is a documentation-only change, but one that users who care about NIST compliance may be interested in, to review if they're using the module in a compliant way. --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3186e580d..30a84f1ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.16.x branch released xxxx-xx-xx + +Changes + * Clarify how the interface of the CTR_DRBG module relates to + NIST SP 800-90A. + = mbed TLS 2.16.3 branch released 2019-09-06 Security From 3354f75bc1dd9897dc367243fe9c7880bd869c78 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 25 Sep 2019 20:22:24 +0200 Subject: [PATCH 05/26] CTR_DRBG: Finish an unfinished paragraph --- include/mbedtls/ctr_drbg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 05a2aba2c..03ce87f72 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -15,6 +15,8 @@ * (`MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` not set) and * with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set + * to 32 or more, and the DRBG is initialized with an explicit + * nonce in the \c custom parameter to see mbedtls_ctr_drbg_seed(). * - 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()). From c85dcb31d9c3ae4d5a2f2457f5e4ff18e944494d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 25 Sep 2019 20:22:40 +0200 Subject: [PATCH 06/26] CTR_DRBG: improve the discussion of entropy length vs strength --- include/mbedtls/ctr_drbg.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 03ce87f72..32d9adf33 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -277,11 +277,30 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * * \note For compliance with NIST SP 800-90A, the entropy length - * must be at least 1.5 times security strength, since - * the entropy source is used both as the entropy input - * and to provide the initial nonce: - * - 24 bytes if using AES-128; - * - 48 bytes if using AES-256. + * (\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. + * Therefore, to provide full security, + * the entropy input must be at least: + * - 24 bytes if using AES-128 and the \p custom + * argument to mbedtls_ctr_drbg_seed() may repeat + * (for example because it is empty, or more generally + * constant); + * - 48 bytes if using AES-256 and the \p custom + * argument to mbedtls_ctr_drbg_seed() may repeat + * (for example because it is empty, or more generally + * constant); + * - 16 bytes if using AES-128 and the \p custom + * argument to mbedtls_ctr_drbg_seed() includes + * a nonce; + * - 32 bytes if using AES-256 and the \p custom + * argument to mbedtls_ctr_drbg_seed() includes + * a nonce. * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. From 761f88818e8dadde3555d45ee5a2e0cfef816fae Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 26 Sep 2019 14:53:44 +0200 Subject: [PATCH 07/26] Remove warning that the previous expanded discussion has obsoleted --- include/mbedtls/ctr_drbg.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 32d9adf33..ae0da45a5 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -24,10 +24,6 @@ * 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`). - * - * \warning Using 128-bit keys for CTR_DRBG or using SHA-256 as the entropy - * compression function limits the security of generated - * keys and operations that use random values generated to 128-bit security. */ /* * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved From 4284becde97bddc85b77aab26262b6876507e826 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 26 Sep 2019 14:54:42 +0200 Subject: [PATCH 08/26] Fix wording --- include/mbedtls/ctr_drbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index ae0da45a5..6098df8cf 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -16,7 +16,7 @@ * with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set * to 32 or more, and the DRBG is initialized with an explicit - * nonce in the \c custom parameter to see mbedtls_ctr_drbg_seed(). + * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). * - 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()). From 0bf49eb85b68a9b5e2273f11c3248dec2234b743 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 30 Sep 2019 15:01:02 +0200 Subject: [PATCH 09/26] More CTR_DRBG documentation improvements and clarifications --- include/mbedtls/ctr_drbg.h | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 6098df8cf..f65606eb4 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -200,6 +200,9 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * with mbedtls_entropy_init() (which registers the platform's default * 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(). + * * Personalization data can be provided in addition to the more generic * entropy source, to make this instantiation as unique as possible. * @@ -227,7 +230,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \param f_entropy The entropy callback, taking as arguments the * \p p_entropy context, the buffer to fill, and the * length of the buffer. - * \param p_entropy The entropy context. + * \param p_entropy The entropy context to pass to \p f_entropy. * \param custom Personalization data, that is device-specific * identifiers. This can be NULL, in which case the * personalization data is empty regardless of the value @@ -257,7 +260,8 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); * The default value is off. * * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_ctr_drbg_random_with_add(). + * every call to mbedtls_ctr_drbg_random_with_add() + * or mbedtls_ctr_drbg_random(). * Only use this if your entropy source has sufficient * throughput. * @@ -269,8 +273,9 @@ 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. The default value is - * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + * seed or 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) @@ -307,7 +312,12 @@ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, /** * \brief This function sets the reseed interval. - * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. + * + * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() + * or mbedtls_ctr_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. * * \param ctx The CTR_DRBG context. * \param interval The reseed interval. @@ -361,7 +371,7 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer. + * \param output_len The length of the buffer in bytes. * \param additional Additional data to update. Can be NULL, in which * case the additional data is empty regardless of * the value of \p add_len. @@ -436,7 +446,7 @@ MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed * failure. */ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); @@ -450,8 +460,10 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. */ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ From db6f41402c5cb3a76ea908be3f5659d8144bce8c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 30 Sep 2019 15:01:15 +0200 Subject: [PATCH 10/26] HMAC_DRBG documentation improvements clarifications Improve the formatting and writing of the documentation based on what had been done for CTR_DRBG. Document the maximum size and nullability of some buffer parameters. --- include/mbedtls/hmac_drbg.h | 258 ++++++++++++++++++++++-------------- 1 file changed, 158 insertions(+), 100 deletions(-) diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index f1289cb30..47a71b80b 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -1,10 +1,14 @@ /** * \file hmac_drbg.h * - * \brief HMAC_DRBG (NIST SP 800-90A) + * \brief The HMAC_DRBG pseudorandom generator. + * + * This module implements the HMAC_DRBG pseudorandom generator described + * in NIST SP 800-90A: Recommendation for Random Number Generation Using + * Deterministic Random Bit Generators. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -104,38 +108,50 @@ typedef struct mbedtls_hmac_drbg_context } mbedtls_hmac_drbg_context; /** - * \brief HMAC_DRBG context initialization - * Makes the context ready for mbedtls_hmac_drbg_seed(), - * mbedtls_hmac_drbg_seed_buf() or - * mbedtls_hmac_drbg_free(). + * \brief HMAC_DRBG context initialization. * - * \param ctx HMAC_DRBG context to be initialized + * This function makes the context ready for mbedtls_hmac_drbg_seed(), + * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). + * + * \param ctx HMAC_DRBG context to be initialized. */ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); /** - * \brief HMAC_DRBG initial seeding - * Seed and setup entropy source for future reseeds. + * \brief HMAC_DRBG initial seeding. * - * \param ctx HMAC_DRBG context to be seeded - * \param md_info MD algorithm to use for HMAC_DRBG - * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer - * length) - * \param p_entropy Entropy context - * \param custom Personalization data (Device specific identifiers) - * (Can be NULL) - * \param len Length of personalization data + * Set the initial seed and set up the entropy source for future reseeds. + * + * \param ctx HMAC_DRBG context to be seeded. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param f_entropy The entropy callback, taking as arguments the + * \p p_entropy context, the buffer to fill, and the + * length of the buffer. + * \param p_entropy The entropy context to pass to \p f_entropy. + * \param custom Personalization data, that is device-specific + * identifiers. This can be NULL, in which case the + * personalization data is empty regardless of the value + * of \p len. + * \param len The length of the personalization data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 + * where \p entropy_len is the entropy length + * (see mbedtls_hmac_drbg_set_entropy_len()). * * \note The "security strength" as defined by NIST is set to: - * 128 bits if md_alg is SHA-1, - * 192 bits if md_alg is SHA-224, - * 256 bits if md_alg is SHA-256 or higher. + * 128 bits if \p md_info is SHA-1, + * 192 bits if \p md_info is SHA-224, + * 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. * Note that SHA-256 is just as efficient as SHA-224. * - * \return 0 if successful, or - * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or - * MBEDTLS_ERR_MD_ALLOC_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED. + * \return 0 if successful. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if the call to \p f_entropy failed. */ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, @@ -146,98 +162,131 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, /** * \brief Initilisation of simpified HMAC_DRBG (never reseeds). - * (For use with deterministic ECDSA.) * - * \param ctx HMAC_DRBG context to be initialised - * \param md_info MD algorithm to use for HMAC_DRBG - * \param data Concatenation of entropy string and additional data - * \param data_len Length of data in bytes + * This function is meant for use in algorithms that need a pseudorandom + * input such as deterministic ECDSA. * - * \return 0 if successful, or - * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or - * MBEDTLS_ERR_MD_ALLOC_FAILED. + * \param ctx HMAC_DRBG context to be initialised. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param data Concatenation of the initial entropy string and + * the additional data. + * \param data_len Length of \p data in bytes. + * + * \return 0 if successful. or + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. */ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, const unsigned char *data, size_t data_len ); /** - * \brief Enable / disable prediction resistance (Default: Off) + * \brief This function turns prediction resistance on or off. + * The default value is off. * - * Note: If enabled, entropy is used for ctx->entropy_len before each call! - * Only use this if you have ample supply of good entropy! + * \note If enabled, entropy is gathered at the beginning of + * every call to mbedtls_hmac_drbg_random_with_add() + * or mbedtls_hmac_drbg_random(). + * Only use this if your entropy source has sufficient + * throughput. * - * \param ctx HMAC_DRBG context - * \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF + * \param ctx The HMAC_DRBG context. + * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. */ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, int resistance ); /** - * \brief Set the amount of entropy grabbed on each reseed - * (Default: given by the security strength, which - * depends on the hash used, see \c mbedtls_hmac_drbg_init() ) + * \brief This function sets the amount of entropy grabbed on each + * seed or reseed. * - * \param ctx HMAC_DRBG context - * \param len Amount of entropy to grab, in bytes + * The default value is given by the security strength, which depends on the + * hash used. See mbedtls_hmac_drbg_init(). + * + * \param ctx The HMAC_DRBG context. + * \param len The amount of entropy to grab, in bytes. */ void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ); /** - * \brief Set the reseed interval - * (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) + * \brief Set the reseed interval. * - * \param ctx HMAC_DRBG context - * \param interval Reseed interval + * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() + * or mbedtls_hmac_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. + * + * \param ctx The HMAC_DRBG context. + * \param interval The reseed interval. */ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ); /** - * \brief HMAC_DRBG update state + * \brief This function updates the state of the HMAC_DRBG context. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to update state with, or NULL - * \param add_len Length of additional data, or 0 + * \param ctx The HMAC_DRBG context. + * \param additional The data to update the state with. + * If this is \p NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is null. * * \return \c 0 on success, or an error from the underlying * hash calculation. - * - * \note Additional data is optional, pass NULL and 0 as second - * third argument if no additional data is being used. */ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ); /** - * \brief HMAC_DRBG reseeding (extracts data from entropy source) + * \brief This function reseeds the HMAC_DRBG context, that is + * extracts data from the entropy source. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to add to state (Can be NULL) - * \param len Length of additional data + * \param ctx The HMAC_DRBG context. + * \param additional Additional data to add to the state. + * If this is \c NULL, there is no additional data + * and \p len should be \c 0. + * \param len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len + * where \p entropy_len is the entropy length + * (see mbedtls_hmac_drbg_set_entropy_len()). * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * \return 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy function failed. */ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t len ); /** - * \brief HMAC_DRBG generate random with additional update input + * \brief This function updates an HMAC_DRBG instance with additional + * data and uses it to generate random data. * - * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * \note The function automatically reseeds if the reseed counter is exceeded. * - * \param p_rng HMAC_DRBG context - * \param output Buffer to fill - * \param output_len Length of the buffer - * \param additional Additional data to update with (can be NULL) - * \param add_len Length of additional data (can be 0) + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \param additional Additional data to update with. + * If this is \p NULL, there is no additional data + * and \p add_len should be \c 0. + * \param add_len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or - * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG. + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if + * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. */ int mbedtls_hmac_drbg_random_with_add( void *p_rng, unsigned char *output, size_t output_len, @@ -245,24 +294,28 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, size_t add_len ); /** - * \brief HMAC_DRBG generate random + * \brief This function uses HMAC_DRBG to generate random data. * - * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * \note The function automatically reseeds if the reseed counter is exceeded. * - * \param p_rng HMAC_DRBG context - * \param output Buffer to fill - * \param out_len Length of the buffer + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param out_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. */ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); /** * \brief Free an HMAC_DRBG context * - * \param ctx HMAC_DRBG context to free. + * \param ctx The HMAC_DRBG context to free. */ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); @@ -273,17 +326,16 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); #define MBEDTLS_DEPRECATED #endif /** - * \brief HMAC_DRBG update state + * \brief This function updates the state of the HMAC_DRBG context. * * \deprecated Superseded by mbedtls_hmac_drbg_update_ret() * in 2.16.0. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to update state with, or NULL - * \param add_len Length of additional data, or 0 - * - * \note Additional data is optional, pass NULL and 0 as second - * third argument if no additional data is being used. + * \param ctx The HMAC_DRBG context. + * \param additional The data to update the state with. + * If this is \p NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is null. */ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, @@ -293,26 +345,31 @@ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( #if defined(MBEDTLS_FS_IO) /** - * \brief Write a seed file + * \brief This function writes a seed file. * - * \param ctx HMAC_DRBG context - * \param path Name of the file + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. * - * \return 0 if successful, 1 on file error, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed + * failure. */ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); /** - * \brief Read and update a seed file. Seed is added to this - * instance + * \brief This function reads and updates a seed file. The seed + * is added to this instance. * - * \param ctx HMAC_DRBG context - * \param path Name of the file + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. * - * \return 0 if successful, 1 on file error, - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or - * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. */ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ @@ -320,9 +377,10 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch #if defined(MBEDTLS_SELF_TEST) /** - * \brief Checkup routine + * \brief The HMAC_DRBG Checkup routine. * - * \return 0 if successful, or 1 if the test failed + * \return \c 0 if successful. + * \return \c 1 if the test failed. */ int mbedtls_hmac_drbg_self_test( int verbose ); #endif From 0b5e804c095789c85cba0503b04d53eb5700a35e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 30 Sep 2019 15:20:52 +0200 Subject: [PATCH 11/26] HMAC_DRBG: improve the documentation of the entropy length --- include/mbedtls/hmac_drbg.h | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 47a71b80b..3b56d45b0 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -122,6 +122,32 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * * Set the initial seed and set up the entropy source for future reseeds. * + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). + * + * \note By default, the security strength as defined by NIST is: + * - 128 bits if \p md_info is SHA-1; + * - 192 bits if \p md_info is SHA-224; + * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. + * Note that SHA-256 is just as efficient as SHA-224. + * The security strength can be reduced if a smaller + * entropy length is set with + * mbedtls_hmac_drbg_set_entropy_len(). + * + * \note The default entropy length is the security strength + * (converted from bits to bytes). You can override + * it mbedtls_hmac_drbg_set_entropy_len(). + * \p f_entropy is always called with a length that is + * less than or equal to the entropy length. + * + * \note During the initial seeding, this function calls + * the entropy source to obtain a nonce + * whose length is half the entropy length. + * * \param ctx HMAC_DRBG context to be seeded. * \param md_info MD algorithm to use for HMAC_DRBG. * \param f_entropy The entropy callback, taking as arguments the @@ -137,13 +163,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * and also at most * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 * where \p entropy_len is the entropy length - * (see mbedtls_hmac_drbg_set_entropy_len()). - * - * \note The "security strength" as defined by NIST is set to: - * 128 bits if \p md_info is SHA-1, - * 192 bits if \p md_info is SHA-224, - * 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. - * Note that SHA-256 is just as efficient as SHA-224. + * described above. * * \return 0 if successful. * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is @@ -203,7 +223,7 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx * seed or reseed. * * The default value is given by the security strength, which depends on the - * hash used. See mbedtls_hmac_drbg_init(). + * hash used. See the documentation of mbedtls_hmac_drbg_seed() for details. * * \param ctx The HMAC_DRBG context. * \param len The amount of entropy to grab, in bytes. From 6735363f809049c70038b8272721d909b9a64772 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 30 Sep 2019 15:25:18 +0200 Subject: [PATCH 12/26] Also mention HMAC_DRBG in the changelog entry There were no tricky compliance issues for HMAC_DBRG, unlike CTR_DRBG, but mention it anyway. For CTR_DRBG, summarize the salient issue. --- ChangeLog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30a84f1ff..18a47c80b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,8 +3,9 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS 2.16.x branch released xxxx-xx-xx Changes - * Clarify how the interface of the CTR_DRBG module relates to - NIST SP 800-90A. + * Clarify how the interface of the CTR_DRBG and HMAC modules relates to + NIST SP 800-90A. In particular CTR_DRBG requires an explicit nonce + to achieve a 256-bit strength if MBEDTLS_ENTROPY_FORCE_SHA256 is set. = mbed TLS 2.16.3 branch released 2019-09-06 From 759c91d66aa39bbcfdc469cbc39f07a1ae5dbcf7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 1 Oct 2019 18:30:02 +0200 Subject: [PATCH 13/26] Consistently use \c NULL and \c 0 --- include/mbedtls/ctr_drbg.h | 10 +++++----- include/mbedtls/hmac_drbg.h | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index f65606eb4..e47b76986 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -232,7 +232,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * length of the buffer. * \param p_entropy The entropy context to pass to \p f_entropy. * \param custom Personalization data, that is device-specific - * identifiers. This can be NULL, in which case the + * identifiers. This can be \c NULL, in which case the * personalization data is empty regardless of the value * of \p len. * \param len The length of the personalization data. @@ -330,7 +330,7 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, * extracts data from the entropy source. * * \param ctx The CTR_DRBG context. - * \param additional Additional data to add to the state. Can be NULL. + * \param additional Additional data to add to the state. Can be \c NULL. * \param len The length of the additional data. * This must be less than * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len @@ -348,7 +348,7 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, * * \param ctx The CTR_DRBG context. * \param additional The data to update the state with. This must not be - * null unless \p add_len is 0. + * \c NULL unless \p add_len is \c 0. * \param add_len Length of \p additional in bytes. This must be at * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * @@ -372,11 +372,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. * \param output_len The length of the buffer in bytes. - * \param additional Additional data to update. Can be NULL, in which + * \param additional Additional data to update. Can be \c NULL, in which * case the additional data is empty regardless of * the value of \p add_len. * \param add_len The length of the additional data - * if \p additional is non-null. + * if \p additional is not \c NULL. * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT * and less than * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 3b56d45b0..e31b3c664 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -155,7 +155,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * length of the buffer. * \param p_entropy The entropy context to pass to \p f_entropy. * \param custom Personalization data, that is device-specific - * identifiers. This can be NULL, in which case the + * identifiers. This can be \c NULL, in which case the * personalization data is empty regardless of the value * of \p len. * \param len The length of the personalization data. @@ -165,7 +165,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * where \p entropy_len is the entropy length * described above. * - * \return 0 if successful. + * \return \c 0 if successful. * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is * invalid. * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough @@ -192,7 +192,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, * the additional data. * \param data_len Length of \p data in bytes. * - * \return 0 if successful. or + * \return \c 0 if successful. or * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is * invalid. * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough @@ -251,9 +251,9 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, * * \param ctx The HMAC_DRBG context. * \param additional The data to update the state with. - * If this is \p NULL, there is no additional data. + * If this is \c NULL, there is no additional data. * \param add_len Length of \p additional in bytes. - * Unused if \p additional is null. + * Unused if \p additional is \c NULL. * * \return \c 0 on success, or an error from the underlying * hash calculation. @@ -276,7 +276,7 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, * where \p entropy_len is the entropy length * (see mbedtls_hmac_drbg_set_entropy_len()). * - * \return 0 if successful. + * \return \c 0 if successful. * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED * if a call to the entropy function failed. */ @@ -295,7 +295,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, * \param output_len The length of the buffer in bytes. * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. * \param additional Additional data to update with. - * If this is \p NULL, there is no additional data + * If this is \c NULL, there is no additional data * and \p add_len should be \c 0. * \param add_len The length of the additional data. * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. @@ -353,9 +353,9 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); * * \param ctx The HMAC_DRBG context. * \param additional The data to update the state with. - * If this is \p NULL, there is no additional data. + * If this is \c NULL, there is no additional data. * \param add_len Length of \p additional in bytes. - * Unused if \p additional is null. + * Unused if \p additional is \c NULL. */ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, From 3f9c97345283120a5b5d244d5d5569e23fd3c4ab Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 1 Oct 2019 18:31:28 +0200 Subject: [PATCH 14/26] Do note that xxx_drbg_random functions reseed with PR enabled --- include/mbedtls/ctr_drbg.h | 7 +++++-- include/mbedtls/hmac_drbg.h | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index e47b76986..3d176288b 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -366,7 +366,8 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * \brief This function updates a CTR_DRBG instance with additional * data and uses it to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. @@ -394,7 +395,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, /** * \brief This function uses CTR_DRBG to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + * * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index e31b3c664..500a9d4b6 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -287,7 +287,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, * \brief This function updates an HMAC_DRBG instance with additional * data and uses it to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * * \param p_rng The HMAC_DRBG context. This must be a pointer to a * #mbedtls_hmac_drbg_context structure. @@ -316,7 +317,8 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, /** * \brief This function uses HMAC_DRBG to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * * \param p_rng The HMAC_DRBG context. This must be a pointer to a * #mbedtls_hmac_drbg_context structure. From 9fb45187282ae314e81f6fa2dbd17d73cedde6f2 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 1 Oct 2019 18:39:45 +0200 Subject: [PATCH 15/26] Use standard terminology to describe the personalization string NIST and many other sources call it a "personalization string", and certainly not "device-specific identifiers" which is actually somewhat misleading since this is just one of many things that might go into a personalization string. --- include/mbedtls/ctr_drbg.h | 11 +++++------ include/mbedtls/hmac_drbg.h | 12 +++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 3d176288b..3599e95d2 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -203,7 +203,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \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(). * - * Personalization data can be provided in addition to the more generic + * You can provide a personalization string in addition to the * entropy source, to make this instantiation as unique as possible. * * \note The _seed_material_ value passed to the derivation @@ -231,11 +231,10 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \p p_entropy context, the buffer to fill, and the * length of the buffer. * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom Personalization data, that is device-specific - * identifiers. This can be \c NULL, in which case the - * personalization data is empty regardless of the value - * of \p len. - * \param len The length of the personalization data. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. * This must be at most * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT / 2. * diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 500a9d4b6..2a97ae9d2 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -129,6 +129,9 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * with mbedtls_entropy_init() (which registers the platform's default * entropy sources). * + * You can provide a personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * * \note By default, the security strength as defined by NIST is: * - 128 bits if \p md_info is SHA-1; * - 192 bits if \p md_info is SHA-224; @@ -154,11 +157,10 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * \p p_entropy context, the buffer to fill, and the * length of the buffer. * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom Personalization data, that is device-specific - * identifiers. This can be \c NULL, in which case the - * personalization data is empty regardless of the value - * of \p len. - * \param len The length of the personalization data. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT * and also at most * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 From 340d6099a097a9bc2d170ae978de7d9cbd44ca64 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 1 Oct 2019 18:41:12 +0200 Subject: [PATCH 16/26] HMAC_DRBG: note that the initial seeding grabs entropy for the nonce --- include/mbedtls/hmac_drbg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 2a97ae9d2..aa93dc91c 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -224,6 +224,9 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx * \brief This function sets the amount of entropy grabbed on each * seed or reseed. * + * During the initial seeding, mbedtls_hmac_drbg_seed() additionally grabs + * half this amount to create the nonce. + * * The default value is given by the security strength, which depends on the * hash used. See the documentation of mbedtls_hmac_drbg_seed() for details. * From 8cec70a8c4549dc962dd0634083294166460c939 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 18:23:38 +0200 Subject: [PATCH 17/26] CTR_DRBG: make it easier to understand the security strength Explain how MBEDTLS_CTR_DRBG_ENTROPY_LEN is set next to the security strength statement, rather than giving a partial explanation (current setting only) in the documentation of MBEDTLS_CTR_DRBG_ENTROPY_LEN. --- include/mbedtls/ctr_drbg.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 3599e95d2..4f8d1315c 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -24,6 +24,13 @@ * 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 #MBEDTLS_SHA512_C is enabled and the symbol + * #MBEDTLS_ENTROPY_FORCE_SHA256 is not enabled at compile time. + * This is the default configuration of the library. + * - \c 32 if the module #MBEDTLS_SHA512_C is disabled at compile time. + * - \c 32 if #MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. */ /* * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved @@ -99,7 +106,7 @@ /** The amount of entropy used per seed by default. * * This is 48 bytes because the entropy module uses SHA-512 - * (`MBEDTLS_ENTROPY_FORCE_SHA256` is not set). + * #MBEDTLS_ENTROPY_FORCE_SHA256 is not set). * * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are * acceptable. @@ -109,7 +116,7 @@ /** The amount of entropy used per seed by default. * * This is 32 bytes because the entropy module uses SHA-256 - * (the SHA-512 module is disabled or `MBEDTLS_ENTROPY_FORCE_SHA256` is set). + * (the SHA512 module is disabled or #MBEDTLS_ENTROPY_FORCE_SHA256 is set). * * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are * acceptable. From 596fdfd6cf122de5c35d1cc526bc05336faa969e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 19:01:31 +0200 Subject: [PATCH 18/26] CTR_DRBG: Improve the explanation of security strength Separate the cases that achieve a 128-bit strength and the cases that achieve a 256-bit strength. --- include/mbedtls/ctr_drbg.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 4f8d1315c..892fd620f 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -292,22 +292,24 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, * 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. - * Therefore, to provide full security, + * + * To achieve 256-bit security, + * you must use AES-256 and * the entropy input must be at least: - * - 24 bytes if using AES-128 and the \p custom - * argument to mbedtls_ctr_drbg_seed() may repeat - * (for example because it is empty, or more generally - * constant); - * - 48 bytes if using AES-256 and the \p custom - * argument to mbedtls_ctr_drbg_seed() may repeat - * (for example because it is empty, or more generally - * constant); - * - 16 bytes if using AES-128 and the \p custom - * argument to mbedtls_ctr_drbg_seed() includes - * a nonce; - * - 32 bytes if using AES-256 and the \p custom - * argument to mbedtls_ctr_drbg_seed() includes - * a nonce. + * - 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. * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. From e3d8cf1966d5da95a192839e8c06305675a0a22d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 19:02:13 +0200 Subject: [PATCH 19/26] CTR_DRBG documentation: further wording improvements --- include/mbedtls/ctr_drbg.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 892fd620f..e62f115c1 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -1,7 +1,8 @@ /** * \file ctr_drbg.h * - * \brief This file contains CTR_DRBG definitions and functions. + * \brief This file contains definitions and functions for the + * CTR_DRBG pseudorandom generator. * * CTR_DRBG is a standardized way of building a PRNG from a block-cipher * in counter mode operation, as defined in NIST SP 800-90A: @@ -410,7 +411,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer. + * \param output_len The length of the buffer in bytes. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or From dd5b67b4f4c0ce60e391f7ccf8a385143f5a4e7c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:20:46 +0200 Subject: [PATCH 20/26] CTR_DRBG: more consistent formatting and wording In particular, don't use #MBEDTLS_xxx on macros that are undefined in some configurations, since this would be typeset with a literal '#'. --- include/mbedtls/ctr_drbg.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index e62f115c1..c06241afa 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -12,26 +12,26 @@ * 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) * - 256 bits under the default configuration of the library, with AES-256 - * (`MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` not set) and - * with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. + * and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set * to 32 or more, and the DRBG is initialized with an explicit * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). * - 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 (`MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` set) + * - 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`). + * in config.h). * * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to: - * - \c 48 if the module #MBEDTLS_SHA512_C is enabled and the symbol - * #MBEDTLS_ENTROPY_FORCE_SHA256 is not enabled at compile time. + * - \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 #MBEDTLS_SHA512_C is disabled at compile time. - * - \c 32 if #MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. + * - \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 @@ -79,14 +79,14 @@ /**< The key size in bytes used by the cipher. * * Compile-time choice: 16 bytes (128 bits) - * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is set. + * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. */ #else #define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size in bytes used by the cipher. * * Compile-time choice: 32 bytes (256 bits) - * because `MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` is not set. + * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. */ #endif @@ -107,10 +107,10 @@ /** The amount of entropy used per seed by default. * * This is 48 bytes because the entropy module uses SHA-512 - * #MBEDTLS_ENTROPY_FORCE_SHA256 is not set). * * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are * acceptable. + * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 #else From 19892184567dd3ae908000220c68f6e29a613dee Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:21:14 +0200 Subject: [PATCH 21/26] Move MBEDTLS_CTR_DRBG_USE_128_BIT_KEY to the correct section It's an on/off feature, so it should be listed in version_features. --- include/mbedtls/config.h | 10 ++++++++-- library/version_features.c | 3 +++ programs/ssl/query_config.c | 16 ++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 5df962ef6..085f40a8f 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -689,6 +689,13 @@ #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN #define MBEDTLS_CIPHER_PADDING_ZEROS +/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + * + * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. + * By default, CTR_DRBG uses a 256-bit key. + */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + /** * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES * @@ -2149,7 +2156,7 @@ * * Enable the CTR_DRBG AES-based random generator. * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. + * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. * * Module: library/ctr_drbg.c * Caller: @@ -3041,7 +3048,6 @@ //#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ //#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ //#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */ /* HMAC_DRBG options */ //#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ diff --git a/library/version_features.c b/library/version_features.c index a99ee808d..3b67b2be8 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -297,6 +297,9 @@ static const char *features[] = { #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) "MBEDTLS_CIPHER_PADDING_ZEROS", #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ +#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) + "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", +#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index bfb92720b..37e4141e9 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -834,6 +834,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ +#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) + if( strcmp( "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_CTR_DRBG_USE_128_BIT_KEY ); + return( 0 ); + } +#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ + #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) if( strcmp( "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", config ) == 0 ) { @@ -2114,14 +2122,6 @@ int query_config( const char *config ) } #endif /* MBEDTLS_CTR_DRBG_MAX_SEED_INPUT */ -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) - if( strcmp( "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", config ) == 0 ) - { - MACRO_EXPANSION_TO_STR( MBEDTLS_CTR_DRBG_USE_128_BIT_KEY ); - return( 0 ); - } -#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ - #if defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) if( strcmp( "MBEDTLS_HMAC_DRBG_RESEED_INTERVAL", config ) == 0 ) { From f6c2061af2a13b1430daf132fe04e1e4af7b5b48 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:21:39 +0200 Subject: [PATCH 22/26] Add a note about CTR_DRBG security strength to config.h --- include/mbedtls/config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 085f40a8f..834cced87 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -2158,6 +2158,10 @@ * The CTR_DRBG generator uses AES-256 by default. * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. * + * \note To achieve a 256-bit security strength with CTR_DRBG, + * you must use AES-256 *and* use sufficient entropy. + * See ctr_drbg.h for more details. + * * Module: library/ctr_drbg.c * Caller: * From e215a4d05ecf874cb3a2f35120b7755742672a7d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 15:13:08 +0200 Subject: [PATCH 23/26] mbedtls_ctr_drbg_seed: correct maximum for len --- include/mbedtls/ctr_drbg.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index c06241afa..f1985d77e 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -244,7 +244,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * string is empty regardless of the value of \p len. * \param len The length of the personalization string. * This must be at most - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT / 2. + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. From cc74872ba9e840d500a883eaf074b06ccd9de4fa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:22:04 +0200 Subject: [PATCH 24/26] 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 f1985d77e..766e64701 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 - * - * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are - * acceptable. +/** This is 48 bytes because the entropy module uses SHA-512 * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). */ #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 set). - * - * \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. From 8b424397b9a47e796bf7230a72527cd4587f37e9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 4 Oct 2019 11:52:22 +0200 Subject: [PATCH 25/26] mbedtls_hmac_drbg_set_entropy_len() only matters when reseeding The documentation of HMAC_DRBG erroneously claimed that mbedtls_hmac_drbg_set_entropy_len() had an impact on the initial seeding. This is in fact not the case: mbedtls_hmac_drbg_seed() forces the entropy length to its chosen value. Fix the documentation. --- include/mbedtls/hmac_drbg.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index aa93dc91c..20b29d981 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -139,13 +139,13 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * Note that SHA-256 is just as efficient as SHA-224. * The security strength can be reduced if a smaller * entropy length is set with - * mbedtls_hmac_drbg_set_entropy_len(). + * mbedtls_hmac_drbg_set_entropy_len() afterwards. * - * \note The default entropy length is the security strength - * (converted from bits to bytes). You can override - * it mbedtls_hmac_drbg_set_entropy_len(). - * \p f_entropy is always called with a length that is - * less than or equal to the entropy length. + * \note The entropy length for the initial seeding is + * the security strength (converted from bits to bytes). + * You can set a different entropy length for subsequent + * seeding by calling mbedtls_hmac_drbg_set_entropy_len() + * after this function. * * \note During the initial seeding, this function calls * the entropy source to obtain a nonce @@ -156,6 +156,8 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); * \param f_entropy The entropy callback, taking as arguments the * \p p_entropy context, the buffer to fill, and the * length of the buffer. + * \p f_entropy is always called with a length that is + * less than or equal to the entropy length. * \param p_entropy The entropy context to pass to \p f_entropy. * \param custom The personalization string. * This can be \c NULL, in which case the personalization @@ -222,13 +224,14 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx /** * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. + * reseed. * - * During the initial seeding, mbedtls_hmac_drbg_seed() additionally grabs - * half this amount to create the nonce. + * The default value is set by mbedtls_hmac_drbg_seed(). * - * The default value is given by the security strength, which depends on the - * hash used. See the documentation of mbedtls_hmac_drbg_seed() for details. + * \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 len The amount of entropy to grab, in bytes. From 16ee3c15a39f11dd20069aba5465a631429a3ab3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 7 Oct 2019 15:57:50 +0200 Subject: [PATCH 26/26] config.pl full: exclude MBEDTLS_CTR_DRBG_USE_128_BIT_KEY This is a variant toggle, not an extra feature, so it should be tested separately. --- scripts/config.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/config.pl b/scripts/config.pl index 7afc89875..c2be0ba56 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -87,6 +87,7 @@ MBEDTLS_TEST_NULL_ENTROPY MBEDTLS_DEPRECATED_REMOVED MBEDTLS_HAVE_SSE2 MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +MBEDTLS_CTR_DRBG_USE_128_BIT_KEY MBEDTLS_ECP_DP_M221_ENABLED MBEDTLS_ECP_DP_M383_ENABLED MBEDTLS_ECP_DP_M511_ENABLED