Skip to content

Commit 6997166

Browse files
CTR_DRBG: define a constant for the default entropy nonce length
The default entropy nonce length is either zero or nonzero depending on the desired security strength and the entropy length. The implementation calculates the actual entropy nonce length from the actual entropy length, and therefore it doesn't need a constant that indicates the default entropy nonce length. A portable application may be interested in this constant, however. And our test code could definitely use it. Define a constant MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN and use it in test code. Previously, test_suite_ctr_drbg had knowledge about the default entropy nonce length built in and test_suite_psa_crypto_init failed. Now both use MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN. This change means that the test ctr_drbg_entropy_usage no longer validates that the default entropy nonce length is sensible. So add a new test that checks that the default entropy length and the default entropy nonce length are sufficient to ensure the expected security strength.
1 parent e9a3454 commit 6997166

File tree

5 files changed

+78
-34
lines changed

5 files changed

+78
-34
lines changed

include/mbedtls/ctr_drbg.h

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,24 @@
147147
extern "C" {
148148
#endif
149149

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+
150168
/**
151169
* \brief The CTR_DRBG context structure.
152170
*/
@@ -216,20 +234,9 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
216234
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
217235
* - Half the entropy length otherwise.
218236
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
219-
*/
220-
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
221-
/** With the default entropy length, the entropy nonce length is \c 0.
222-
*/
223-
#elif MBEDTLS_CTR_DRBG_ENTROPY_LEN & 1
224-
/** With the default entropy length, the entropy nonce length is
225-
* (#MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2.
226-
*/
227-
#else
228-
/** With the default entropy length, the entropy nonce length is
229-
* #MBEDTLS_CTR_DRBG_ENTROPY_LEN / 2.
230-
*/
231-
#endif
232-
/**
237+
* With the default entropy length, the entropy nonce length is
238+
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
239+
*
233240
* You can provide a nonce and personalization string in addition to the
234241
* entropy source, to make this instantiation as unique as possible.
235242
* See SP 800-90A §8.6.7 for more details about nonces.
@@ -240,7 +247,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
240247
* - A string obtained by calling \p f_entropy function for the entropy
241248
* length.
242249
*/
243-
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
250+
#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
244251
/**
245252
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
246253
* obtained by calling \p f_entropy function for the specified length.

tests/suites/test_suite_ctr_drbg.data

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,12 +1070,7 @@ CTR_DRBG CAVS 14.3 (AES-128 use df,True,128,64,0,0) #0
10701070
depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
10711071
ctr_drbg_validate_pr:"d4f1f4ae08bcb3e1":"5d4041942bcf68864a4997d8171f1f9fef55a769b7eaf03fe082029bb32a2b9d8239e865c0a42e14b964b9c09de85a20":"":"":"4155320287eedcf7d484c2c2a1e2eb64b9c9ce77c87202a1ae1616c7a5cfd1c687c7a0bfcc85bda48fdd4629fd330c22d0a76076f88fc7cd04037ee06b7af602"
10721072

1073-
CTR_DRBG entropy usage (entropy_nonce_len=0 by default)
1074-
depends_on:!DEFAULT_ENTROPY_NONCE
1075-
ctr_drbg_entropy_usage:-1
1076-
1077-
CTR_DRBG entropy usage (entropy_nonce_len=entropy_len/2 by default)
1078-
depends_on:DEFAULT_ENTROPY_NONCE
1073+
CTR_DRBG entropy usage (default entropy_nonce_len)
10791074
ctr_drbg_entropy_usage:-1
10801075

10811076
CTR_DRBG entropy usage (entropy_nonce_len=0)
@@ -1084,6 +1079,14 @@ ctr_drbg_entropy_usage:0
10841079
CTR_DRBG entropy usage (entropy_nonce_len=7)
10851080
ctr_drbg_entropy_usage:7
10861081

1082+
CTR_DRBG entropy strength: 128 bits
1083+
depends_on:MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
1084+
ctr_drbg_entropy_strength:128
1085+
1086+
CTR_DRBG entropy strength: 256 bits
1087+
depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
1088+
ctr_drbg_entropy_strength:256
1089+
10871090
CTR_DRBG write/update seed file [#1]
10881091
ctr_drbg_seed_file:"data_files/ctr_drbg_seed":0
10891092

tests/suites/test_suite_ctr_drbg.function

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,6 @@
33
#include "mbedtls/ctr_drbg.h"
44
#include "string.h"
55

6-
/* mbedtls_ctr_drbg_seed() grabs a nonce by default if the entropy
7-
* length is smaller than 3/2 times the maximum security strength. */
8-
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
9-
#undef DEFAULT_ENTROPY_NONCE
10-
#else
11-
#define DEFAULT_ENTROPY_NONCE
12-
#endif
13-
146
/* Modes for ctr_drbg_validate */
157
enum reseed_mode
168
{
@@ -196,7 +188,37 @@ void ctr_drbg_validate_reseed_first( data_t * add_init, data_t * entropy,
196188
}
197189
/* END_CASE */
198190

191+
/* BEGIN_CASE */
192+
void ctr_drbg_entropy_strength( int expected_bit_strength )
193+
{
194+
unsigned char entropy[/*initial entropy*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN +
195+
/*nonce*/ MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN +
196+
/*reseed*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN];
197+
mbedtls_ctr_drbg_context ctx;
198+
size_t last_idx;
199+
size_t byte_strength = expected_bit_strength / 8;
200+
201+
mbedtls_ctr_drbg_init( &ctx );
202+
test_offset_idx = 0;
203+
test_max_idx = sizeof( entropy );
204+
memset( entropy, 0, sizeof( entropy ) );
199205

206+
/* The initial seeding must grab at least byte_strength bytes of entropy
207+
* for the entropy input and byte_strength/2 bytes for a nonce. */
208+
TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx,
209+
mbedtls_test_entropy_func, entropy,
210+
NULL, 0 ) == 0 );
211+
TEST_ASSERT( test_offset_idx >= ( byte_strength * 3 + 1 ) / 2 );
212+
last_idx = test_offset_idx;
213+
214+
/* A reseed must grab at least byte_strength bytes of entropy. */
215+
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) == 0 );
216+
TEST_ASSERT( test_offset_idx - last_idx >= byte_strength );
217+
218+
exit:
219+
mbedtls_ctr_drbg_free( &ctx );
220+
}
221+
/* END_CASE */
200222

201223
/* BEGIN_CASE */
202224
void ctr_drbg_entropy_usage( int entropy_nonce_len )
@@ -224,11 +246,7 @@ void ctr_drbg_entropy_usage( int entropy_nonce_len )
224246
if( entropy_nonce_len >= 0 )
225247
expected_idx += entropy_nonce_len;
226248
else
227-
{
228-
#if defined(DEFAULT_ENTROPY_NONCE)
229-
expected_idx += ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2;
230-
#endif
231-
}
249+
expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN;
232250
TEST_EQUAL( test_offset_idx, expected_idx );
233251

234252
/* By default, PR is off and reseed_interval is large,

tests/suites/test_suite_psa_crypto_init.data

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,25 @@ fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:0:PSA_ERROR_INSUFFICIENT_EN
3434
Fake entropy: less than the block size
3535
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY
3636

37+
Fake entropy: not enough for a nonce
38+
depends_on:ENTROPY_NONCE_LEN != 0
39+
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:ENTROPY_NONCE_LEN - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY
40+
3741
Fake entropy: one block eventually
42+
depends_on:ENTROPY_NONCE_LEN == 0
3843
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS
3944

4045
Fake entropy: one block in two steps
46+
depends_on:ENTROPY_NONCE_LEN == 0
4147
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:1:-1:-1:PSA_SUCCESS
4248

4349
Fake entropy: more than one block in two steps
50+
depends_on:ENTROPY_NONCE_LEN == 0
4451
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:PSA_SUCCESS
4552

53+
Fake entropy: two blocks eventually
54+
fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS
55+
4656
NV seed only: less than minimum
4757
entropy_from_nv_seed:MBEDTLS_ENTROPY_MIN_PLATFORM - 1:PSA_ERROR_INSUFFICIENT_ENTROPY
4858

tests/suites/test_suite_psa_crypto_init.function

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
#define ENTROPY_MIN_NV_SEED_SIZE \
1212
MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
1313

14+
/* PSA crypto uses the CTR_DRBG module. In some configurations, it needs
15+
* to read from the entropy source twice: once for the initial entropy
16+
* and once for a nonce. */
17+
#include "mbedtls/ctr_drbg.h"
18+
#define ENTROPY_NONCE_LEN MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN
19+
1420
typedef struct
1521
{
1622
size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */

0 commit comments

Comments
 (0)