Skip to content

Commit 22589f0

Browse files
Merge pull request #305 from gilles-peskine-arm/ctr_drbg-grab_nonce_from_entropy-set_nonce_length
CTR_DRBG: grab a nonce from the entropy source if needed
2 parents 08c674d + bd326f9 commit 22589f0

File tree

9 files changed

+317
-125
lines changed

9 files changed

+317
-125
lines changed

include/mbedtls/ctr_drbg.h

Lines changed: 114 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,14 @@
1212
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
1313
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
1414
* as the underlying block cipher, with a derivation function.
15-
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
16-
* See the documentation of mbedtls_ctr_drbg_seed() for more details.
17-
*
18-
* Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
19-
* here are the security strengths achieved in typical configuration:
20-
* - 256 bits under the default configuration of the library, with AES-256
21-
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
22-
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
23-
* to 32 or more, and the DRBG is initialized with an explicit
24-
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
25-
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
26-
* between 24 and 47 and the DRBG is not initialized with an explicit
27-
* nonce (see mbedtls_ctr_drbg_seed()).
28-
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
29-
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
30-
* always the case unless it is explicitly set to a different value
31-
* in config.h).
32-
*
33-
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
34-
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
35-
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
36-
* This is the default configuration of the library.
37-
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
38-
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
15+
*
16+
* The security strength as defined in NIST SP 800-90A is
17+
* 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
18+
* and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
19+
* kept at its default value (and not overridden in config.h) and that the
20+
* DRBG instance is set up with default parameters.
21+
* See the documentation of mbedtls_ctr_drbg_seed() for more
22+
* information.
3923
*/
4024
/*
4125
* Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
@@ -163,20 +147,47 @@
163147
extern "C" {
164148
#endif
165149

150+
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
151+
/** The default length of the nonce read from the entropy source.
152+
*
153+
* This is \c 0 because a single read from the entropy source is sufficient
154+
* to include a nonce.
155+
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
156+
*/
157+
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
158+
#else
159+
/** The default length of the nonce read from the entropy source.
160+
*
161+
* This is half of the default entropy length because a single read from
162+
* the entropy source does not provide enough material to form a nonce.
163+
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
164+
*/
165+
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2
166+
#endif
167+
166168
/**
167169
* \brief The CTR_DRBG context structure.
168170
*/
169171
typedef struct mbedtls_ctr_drbg_context
170172
{
171173
unsigned char counter[16]; /*!< The counter (V). */
172-
int reseed_counter; /*!< The reseed counter. */
174+
int reseed_counter; /*!< The reseed counter.
175+
* This is the number of requests that have
176+
* been made since the last (re)seeding,
177+
* minus one.
178+
* Before the initial seeding, this field
179+
* contains the amount of entropy in bytes
180+
* to use as a nonce for the initial seeding.
181+
*/
173182
int prediction_resistance; /*!< This determines whether prediction
174183
resistance is enabled, that is
175184
whether to systematically reseed before
176185
each random generation. */
177186
size_t entropy_len; /*!< The amount of entropy grabbed on each
178-
seed or reseed operation. */
179-
int reseed_interval; /*!< The reseed interval. */
187+
seed or reseed operation, in bytes. */
188+
int reseed_interval; /*!< The reseed interval.
189+
* This is the maximum number of requests
190+
* that can be made between reseedings. */
180191

181192
mbedtls_aes_context aes_ctx; /*!< The AES context. */
182193

@@ -217,43 +228,68 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
217228
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
218229
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
219230
*
220-
* You can provide a personalization string in addition to the
231+
* The entropy nonce length is:
232+
* - \c 0 if the entropy length is at least 3/2 times the entropy length,
233+
* which guarantees that the security strength is the maximum permitted
234+
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
235+
* - Half the entropy length otherwise.
236+
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
237+
* With the default entropy length, the entropy nonce length is
238+
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
239+
*
240+
* You can provide a nonce and personalization string in addition to the
221241
* entropy source, to make this instantiation as unique as possible.
242+
* See SP 800-90A §8.6.7 for more details about nonces.
222243
*
223-
* \note The _seed_material_ value passed to the derivation
224-
* function in the CTR_DRBG Instantiate Process
225-
* described in NIST SP 800-90A §10.2.1.3.2
226-
* is the concatenation of the string obtained from
227-
* calling \p f_entropy and the \p custom string.
228-
* The origin of the nonce depends on the value of
229-
* the entropy length relative to the security strength.
230-
* - If the entropy length is at least 1.5 times the
231-
* security strength then the nonce is taken from the
232-
* string obtained with \p f_entropy.
233-
* - If the entropy length is less than the security
234-
* strength, then the nonce is taken from \p custom.
235-
* In this case, for compliance with SP 800-90A,
236-
* you must pass a unique value of \p custom at
237-
* each invocation. See SP 800-90A §8.6.7 for more
238-
* details.
244+
* The _seed_material_ value passed to the derivation function in
245+
* the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2
246+
* is the concatenation of the following strings:
247+
* - A string obtained by calling \p f_entropy function for the entropy
248+
* length.
239249
*/
240-
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
241-
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
242-
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
243-
* maximum security strength permitted by CTR_DRBG,
244-
* you must pass a value of \p custom that is a nonce:
245-
* this value must never be repeated in subsequent
246-
* runs of the same application or on a different
247-
* device.
250+
#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
251+
/**
252+
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
253+
* obtained by calling \p f_entropy function for the specified length.
254+
*/
255+
#else
256+
/**
257+
* - A string obtained by calling \p f_entropy function for the entropy nonce
258+
* length. If the entropy nonce length is \c 0, this function does not
259+
* make a second call to \p f_entropy.
248260
*/
249261
#endif
250262
/**
263+
* - The \p custom string.
264+
*
265+
* \note To achieve the nominal security strength permitted
266+
* by CTR_DRBG, the entropy length must be:
267+
* - at least 16 bytes for a 128-bit strength
268+
* (maximum achievable strength when using AES-128);
269+
* - at least 32 bytes for a 256-bit strength
270+
* (maximum achievable strength when using AES-256).
271+
*
272+
* In addition, if you do not pass a nonce in \p custom,
273+
* the sum of the entropy length
274+
* and the entropy nonce length must be:
275+
* - at least 24 bytes for a 128-bit strength
276+
* (maximum achievable strength when using AES-128);
277+
* - at least 48 bytes for a 256-bit strength
278+
* (maximum achievable strength when using AES-256).
279+
*
251280
* \param ctx The CTR_DRBG context to seed.
281+
* It must have been initialized with
282+
* mbedtls_ctr_drbg_init().
283+
* After a successful call to mbedtls_ctr_drbg_seed(),
284+
* you may not call mbedtls_ctr_drbg_seed() again on
285+
* the same context unless you call
286+
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
287+
* again first.
252288
* \param f_entropy The entropy callback, taking as arguments the
253289
* \p p_entropy context, the buffer to fill, and the
254290
* length of the buffer.
255291
* \p f_entropy is always called with a buffer size
256-
* equal to the entropy length.
292+
* less than or equal to the entropy length.
257293
* \param p_entropy The entropy context to pass to \p f_entropy.
258294
* \param custom The personalization string.
259295
* This can be \c NULL, in which case the personalization
@@ -301,11 +337,6 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
301337
*
302338
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
303339
*
304-
* \note mbedtls_ctr_drbg_seed() always sets the entropy length
305-
* to #MBEDTLS_CTR_DRBG_ENTROPY_LEN, so this function
306-
* only has an effect when it is called after
307-
* mbedtls_ctr_drbg_seed().
308-
*
309340
* \note The security strength of CTR_DRBG is bounded by the
310341
* entropy length. Thus:
311342
* - When using AES-256
@@ -320,11 +351,35 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
320351
*
321352
* \param ctx The CTR_DRBG context.
322353
* \param len The amount of entropy to grab, in bytes.
323-
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
354+
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
355+
* and at most the maximum length accepted by the
356+
* entropy function that is set in the context.
324357
*/
325358
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
326359
size_t len );
327360

361+
/**
362+
* \brief This function sets the amount of entropy grabbed
363+
* as a nonce for the initial seeding.
364+
*
365+
* Call this function before calling mbedtls_ctr_drbg_seed() to read
366+
* a nonce from the entropy source during the initial seeding.
367+
*
368+
* \param ctx The CTR_DRBG context.
369+
* \param len The amount of entropy to grab for the nonce, in bytes.
370+
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
371+
* and at most the maximum length accepted by the
372+
* entropy function that is set in the context.
373+
*
374+
* \return \c 0 on success.
375+
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
376+
* more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
377+
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
378+
* if the initial seeding has already taken place.
379+
*/
380+
int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
381+
size_t len );
382+
328383
/**
329384
* \brief This function sets the reseed interval.
330385
*

include/mbedtls/hmac_drbg.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
139139
* Note that SHA-256 is just as efficient as SHA-224.
140140
* The security strength can be reduced if a smaller
141141
* entropy length is set with
142-
* mbedtls_hmac_drbg_set_entropy_len() afterwards.
142+
* mbedtls_hmac_drbg_set_entropy_len().
143143
*
144144
* \note The default entropy length is the security strength
145145
* (converted from bits to bytes). You can override
@@ -222,14 +222,9 @@ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx
222222

223223
/**
224224
* \brief This function sets the amount of entropy grabbed on each
225-
* reseed.
225+
* seed or reseed.
226226
*
227-
* The default value is set by mbedtls_hmac_drbg_seed().
228-
*
229-
* \note mbedtls_hmac_drbg_seed() always sets the entropy length
230-
* to the default value based on the chosen MD algorithm,
231-
* so this function only has an effect if it is called
232-
* after mbedtls_hmac_drbg_seed().
227+
* See the documentation of mbedtls_hmac_drbg_seed() for the default value.
233228
*
234229
* \param ctx The HMAC_DRBG context.
235230
* \param len The amount of entropy to grab, in bytes.

0 commit comments

Comments
 (0)