From 25e1945321e4a2f19faa0bdb220c14cef6525024 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 18:54:20 +0200 Subject: [PATCH 01/10] CTR_DRBG documentation improvements * State explicit whether several numbers are in bits or bytes. * Clarify whether buffer pointer parameters can be NULL. * Clarify some terminology. * Minor wording and formatting improvements. --- include/mbedtls/ctr_drbg.h | 106 ++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 36 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 5a3284315..f1b4f7cf0 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -1,13 +1,16 @@ /** * \file ctr_drbg.h * - * \brief CTR_DRBG is based on AES-256, as defined in NIST SP 800-90A: - * Recommendation for Random Number Generation Using Deterministic - * Random Bit Generators. + * \brief 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: + * Recommendation for Random Number Generation Using Deterministic Random + * Bit Generators. * */ /* - * 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 @@ -92,7 +95,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 */ @@ -150,17 +153,21 @@ 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. + * You can provide a personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * * * \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. - * \param p_entropy The entropy context. - * \param custom Personalization data, that is device-specific - identifiers. Can be NULL. - * \param len The length of the personalization data. + * length of the buffer. + * \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 + * 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. * * \return \c 0 on success, or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -183,7 +190,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. * @@ -199,14 +207,20 @@ 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. + * 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 ); /** * \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. @@ -219,8 +233,12 @@ 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 + * where \c entropy_len is the entropy length + * configured for the context. * * \return \c 0 on success, or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -232,7 +250,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 + * \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. * @@ -258,8 +277,10 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * The remaining Bytes are silently discarded. * * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. - * \param add_len Length of \p additional data. + * \param additional The data to update the state with. This must not be + * \c NULL unless \p add_len is \c 0. + * \param add_len Length of \p additional data. This must be at + * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. */ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, @@ -269,17 +290,26 @@ void mbedtls_ctr_drbg_update( 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. * \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 output_len The length of the buffer in bytes. + * \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 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 + * where \c entropy_len is the entropy length + * configured for the context. * - * \return \c 0 on success, or - * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. */ int mbedtls_ctr_drbg_random_with_add( void *p_rng, @@ -289,15 +319,17 @@ 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. * \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, or - * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. */ int mbedtls_ctr_drbg_random( void *p_rng, @@ -310,9 +342,9 @@ int mbedtls_ctr_drbg_random( void *p_rng, * \param ctx The CTR_DRBG context. * \param path The name of the file. * - * \return \c 0 on success, - * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or - * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * \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 reseed * failure. */ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); @@ -324,10 +356,12 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char * \param ctx The CTR_DRBG context. * \param path The name of the file. * - * \return \c 0 on success, - * #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, - * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure. + * \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 + * 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 eb99c1028f0a9a17eacd30c0c0c91bd919dac219 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 18:56:17 +0200 Subject: [PATCH 02/10] CTR_DRBG: explain the security strength and the entropy input length Explain what how entropy input length is determined from the configuration, and how this in turn determines the security strength. Explain how the nonce is obtained during initialization. --- include/mbedtls/ctr_drbg.h | 82 ++++++++++++++++++++++++++++++++----- include/mbedtls/hmac_drbg.h | 8 +++- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index f1b4f7cf0..6626024aa 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -8,6 +8,24 @@ * Recommendation for Random Number Generation Using Deterministic Random * Bit Generators. * + * The Mbed TLS implementation of CTR_DRBG uses AES-256 + * as the underlying block cipher, with a derivation function. The security + * strength is: + * - 256 bits under the default configuration of the library, + * with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. + * - 256 bits if #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 #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()). + * + * 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 @@ -64,17 +82,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 SHA512 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 @@ -156,6 +182,25 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * 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 + * 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 @@ -203,8 +248,25 @@ 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) + * 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. + * See NIST SP 800-57A table 2. + * + * To achieve 256-bit security, + * 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. * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index bd05da33c..f090ac4a3 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 From d89173066cfc1c950dd67bb5522cc4aef8aff108 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 19:00:06 +0200 Subject: [PATCH 03/10] HMAC_DRBG documentation improvements * State explicit whether several numbers are in bits or bytes. * Clarify whether buffer pointer parameters can be NULL. * Minor wording and formatting improvements. --- include/mbedtls/hmac_drbg.h | 259 +++++++++++++++++++++++------------- 1 file changed, 167 insertions(+), 92 deletions(-) diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index f090ac4a3..f253b9afa 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -108,38 +108,65 @@ typedef struct } 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. * - * \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. + * 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; + * - 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(). * - * \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. + * \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 + * \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 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 + * where \p entropy_len is the entropy length + * described above. + * + * \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 + * 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, @@ -150,66 +177,84 @@ 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 \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 + * 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 + * 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. + * + * \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 \c NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is \c 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 ); @@ -232,33 +277,52 @@ void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, 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 \c 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. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * - * \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 \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. * - * \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, @@ -266,49 +330,59 @@ 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. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * - * \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 ); #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 */ @@ -316,9 +390,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 97edf5e1e22e50263010ee98ccb93b5b06d4016d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 19:00:29 +0200 Subject: [PATCH 04/10] Add ChangeLog entry for the DRBG documentation improvements --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index a746a38a3..88b93452a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.7.x branch released xxxx-xx-xx + +Changes + * 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.7.12 branch released 2019-09-06 Security From b9cfe58180e462c4e3b41f499e1fb93470c37bbd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 2 Oct 2019 19:00:57 +0200 Subject: [PATCH 05/10] DRBG documentation: Relate f_entropy arguments to the entropy module --- include/mbedtls/ctr_drbg.h | 10 ++++++++++ include/mbedtls/hmac_drbg.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 6626024aa..59550797c 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -179,6 +179,16 @@ 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. * + * 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). + * + * \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(). + * * You can provide a personalization string in addition to the * entropy source, to make this instantiation as unique as possible. * diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index f253b9afa..bcecba93d 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -122,6 +122,13 @@ 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). + * * You can provide a personalization string in addition to the * entropy source, to make this instantiation as unique as possible. * From f0b3dcb14ba1df2a45e782214bc2913b8fa7be10 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:28:17 +0200 Subject: [PATCH 06/10] 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 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 59550797c..17a5cfc4e 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -21,11 +21,11 @@ * nonce (see mbedtls_ctr_drbg_seed()). * * 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 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. + * - \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 @@ -85,7 +85,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). + * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is not set). * * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are * acceptable. @@ -95,7 +95,8 @@ /** 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). + * (the SHA512 module is disabled or + * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). * * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are * acceptable. From 406d25878c4042fc326fd2dc60f95bb3845e225c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 14:31:22 +0200 Subject: [PATCH 07/10] 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 fa88ebf01..0bc08cca4 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1884,6 +1884,10 @@ * * Enable the CTR_DRBG AES-256-based random generator. * + * \note This module only achieves a 256-bit security strength if + * the generator is seeded with sufficient entropy. + * See ctr_drbg.h for more details. + * * Module: library/ctr_drbg.c * Caller: * From 2abefefec25db5a2d9f656daaaf26a3f9c45efa9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 15:13:08 +0200 Subject: [PATCH 08/10] 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 17a5cfc4e..fbad4a760 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -223,7 +223,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, or * #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. From dff36824773b9de40be3017610d9aaed03e56cde Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Oct 2019 15:10:21 +0200 Subject: [PATCH 09/10] 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 | 78 ++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index fbad4a760..8963c7423 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -9,8 +9,12 @@ * Bit Generators. * * The Mbed TLS implementation of CTR_DRBG uses AES-256 - * as the underlying block cipher, with a derivation function. The security - * strength is: + * 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 #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. * - 256 bits if #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set @@ -80,30 +84,29 @@ * \{ */ +/** \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 not set). - * - * \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 + +#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). * - * \note See mbedtls_ctr_drbg_set_entropy_len() regarding what values are - * acceptable. + * \warning To achieve a 256-bit security strength, you must pass a nonce + * to mbedtls_ctr_drbg_seed(). */ #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 @@ -188,7 +191,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. @@ -200,9 +206,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. @@ -212,7 +215,17 @@ 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 + * 48, to achieve a 256-bit security strength, + * 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 @@ -260,25 +273,18 @@ 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. - * See NIST SP 800-57A table 2. + * \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, - * 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. + * \note The security strength of CTR_DRBG is bounded by the + * entropy length. Thus \p len must be at least + * 32 (in bytes) to achieve a 256-bit strength. * * \param ctx The CTR_DRBG context. * \param len The amount of entropy to grab, in bytes. From 55e120b9b25502b44354aa022e94cda6ee5adca9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 4 Oct 2019 11:52:22 +0200 Subject: [PATCH 10/10] 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 bcecba93d..a46b28726 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.