blob: 714af5598bfcf23ed9cc713a89608d4597a99cd2 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Gilles Peskineef0624f2018-08-03 20:23:09 +02002#include "mbedtls/entropy.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00003#include "mbedtls/ctr_drbg.h"
Mohammad Azim Khan67735d52017-04-06 11:55:43 +01004#include "string.h"
Rich Evans00ab4702015-02-06 13:43:58 +00005
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +02006/* Modes for ctr_drbg_validate */
7enum reseed_mode
8{
9 RESEED_NEVER, /* never reseed */
10 RESEED_FIRST, /* instantiate, reseed, generate, generate */
11 RESEED_SECOND, /* instantiate, generate, reseed, generate */
12 RESEED_ALWAYS /* prediction resistance, no explicit reseed */
13};
14
Gilles Peskineef0624f2018-08-03 20:23:09 +020015static size_t test_offset_idx;
16static size_t test_max_idx;
Reut Caspie278b362017-10-19 08:49:19 +010017static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +000018{
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010019 const unsigned char *p = (unsigned char *) data;
Gilles Peskineef0624f2018-08-03 20:23:09 +020020 if( test_offset_idx + len > test_max_idx )
21 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Paul Bakker3ddfa662013-11-26 17:45:20 +010022 memcpy( buf, p + test_offset_idx, len );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010023 test_offset_idx += len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +000024 return( 0 );
25}
Paul Bakker33b43f12013-08-20 11:48:36 +020026/* END_HEADER */
Paul Bakker0e04d0e2011-11-27 14:46:59 +000027
Paul Bakker33b43f12013-08-20 11:48:36 +020028/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029 * depends_on:MBEDTLS_CTR_DRBG_C
Paul Bakker33b43f12013-08-20 11:48:36 +020030 * END_DEPENDENCIES
31 */
Paul Bakker0e04d0e2011-11-27 14:46:59 +000032
Paul Bakker33b43f12013-08-20 11:48:36 +020033/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +010034void ctr_drbg_special_behaviours( )
Paul Bakker185ccf72016-07-14 13:21:10 +010035{
36 mbedtls_ctr_drbg_context ctx;
37 unsigned char output[512];
38 unsigned char additional[512];
39
40 mbedtls_ctr_drbg_init( &ctx );
41 memset( output, 0, sizeof( output ) );
42 memset( additional, 0, sizeof( additional ) );
43
44 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
45 output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1,
46 additional, 16 ) ==
47 MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
48 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
49 output, 16,
50 additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1 ) ==
51 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
52
53 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
54 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
55 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Andres Amaya Garcia6a543362017-01-17 23:04:22 +000056
57 mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
58 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
59 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
60 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Paul Bakker185ccf72016-07-14 13:21:10 +010061exit:
62 mbedtls_ctr_drbg_free( &ctx );
63}
64/* END_CASE */
65
66/* BEGIN_CASE */
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020067void ctr_drbg_validate( int reseed_mode, char *nonce_string,
68 int entropy_len_arg, char *entropy_string,
69 char *reseed_string,
70 char *add1_string, char *add2_string,
71 char *result_string )
Gilles Peskine4c786652018-08-03 20:24:54 +020072{
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020073 unsigned char entropy[144];
74 unsigned char nonce[64];
75 unsigned char reseed[32];
76 unsigned char add1[48];
77 unsigned char add2[48];
Gilles Peskine4c786652018-08-03 20:24:54 +020078 mbedtls_ctr_drbg_context ctx;
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020079 unsigned char buf[64];
80 unsigned char result[64];
81 size_t entropy_chunk_len = (size_t) entropy_len_arg;
82 size_t nonce_len, reseed_len, add1_len, add2_len, result_len;
Gilles Peskine4c786652018-08-03 20:24:54 +020083
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020084 test_offset_idx = 0;
Gilles Peskine4c786652018-08-03 20:24:54 +020085 mbedtls_ctr_drbg_init( &ctx );
86
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020087 test_max_idx = unhexify( entropy, entropy_string );
88 nonce_len = unhexify( nonce, nonce_string );
89 reseed_len = unhexify( reseed, reseed_string );
Gilles Peskine4c786652018-08-03 20:24:54 +020090 add1_len = unhexify( add1, add1_string );
91 add2_len = unhexify( add2, add2_string );
92 result_len = unhexify( result, result_string );
93
Gilles Peskine4c786652018-08-03 20:24:54 +020094 /* CTR_DRBG_Instantiate(entropy[:entropy_len], nonce, perso, <ignored>)
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +020095 * where nonce||perso = nonce[nonce_len] */
96 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len(
97 &ctx,
98 mbedtls_test_entropy_func, entropy,
99 nonce, nonce_len,
100 entropy_chunk_len ) == 0 );
101 if( reseed_mode == RESEED_ALWAYS )
102 mbedtls_ctr_drbg_set_prediction_resistance(
103 &ctx,
104 MBEDTLS_CTR_DRBG_PR_ON );
105
106 if( reseed_mode == RESEED_FIRST )
107 {
108 /* CTR_DRBG_Reseed(entropy[idx:idx+entropy_len],
109 * reseed[:reseed_len]) */
110 TEST_ASSERT( mbedtls_ctr_drbg_reseed(
111 &ctx,
112 reseed, reseed_len ) == 0 );
113 }
Gilles Peskine4c786652018-08-03 20:24:54 +0200114
115 /* CTR_DRBG_Generate(result_len * 8 bits, add1[:add1_len]) -> buf */
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200116 /* Then reseed if prediction resistance is enabled. */
117 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
118 &ctx,
119 buf, result_len,
120 add1, add1_len ) == 0 );
121
122
123 if( reseed_mode == RESEED_SECOND )
124 {
125 /* CTR_DRBG_Reseed(entropy[idx:idx+entropy_len],
126 * reseed[:reseed_len]) */
127 TEST_ASSERT( mbedtls_ctr_drbg_reseed(
128 &ctx,
129 reseed, reseed_len ) == 0 );
130 }
131
Gilles Peskine4c786652018-08-03 20:24:54 +0200132 /* CTR_DRBG_Generate(result_len * 8 bits, add2[:add2_len]) -> buf */
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200133 /* Then reseed if prediction resistance is enabled. */
134 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
135 &ctx,
136 buf, result_len,
137 add2, add2_len ) == 0 );
Gilles Peskine4c786652018-08-03 20:24:54 +0200138 TEST_ASSERT( memcmp( buf, result, result_len ) == 0 );
139
140exit:
141 mbedtls_ctr_drbg_free( &ctx );
142}
143/* END_CASE */
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200144
145/* BEGIN_CASE */
146void ctr_drbg_validate_no_reseed( char *add_init_string, char *entropy_string,
147 char *add1_string, char *add2_string,
148 char *result_string )
149{
150 test_suite_ctr_drbg_validate( RESEED_NEVER, add_init_string,
151 strlen( entropy_string ) / 2, entropy_string,
152 "", add1_string, add2_string,
153 result_string );
154 goto exit;
155}
156/* END_CASE */
157
158/* BEGIN_CASE */
159void ctr_drbg_validate_pr( char *add_init_string, char *entropy_string,
160 char *add1_string, char *add2_string,
Gilles Peskineef0624f2018-08-03 20:23:09 +0200161 char *result_string )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000162{
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200163 test_suite_ctr_drbg_validate( RESEED_ALWAYS, add_init_string,
164 strlen( entropy_string ) / 6, entropy_string,
165 "", add1_string, add2_string,
166 result_string );
167 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000168}
Paul Bakker33b43f12013-08-20 11:48:36 +0200169/* END_CASE */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000170
Paul Bakker33b43f12013-08-20 11:48:36 +0200171/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100172void ctr_drbg_validate_nopr( data_t * add_init, data_t * entropy,
173 data_t * add1, data_t * add_reseed,
Gilles Peskineef0624f2018-08-03 20:23:09 +0200174 char *add2_string, char *result_string )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000175{
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200176 test_suite_ctr_drbg_validate( RESEED_SECOND, add_init_string,
177 strlen( entropy_string ) / 4, entropy_string,
178 add_reseed_string, add1_string, add2_string,
179 result_string );
180 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000181}
Paul Bakker33b43f12013-08-20 11:48:36 +0200182/* END_CASE */
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100183
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100184/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100185void ctr_drbg_entropy_usage( )
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100186{
187 unsigned char out[16];
188 unsigned char add[16];
189 unsigned char entropy[1024];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100191 size_t i, reps = 10;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200192 size_t last_idx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100193
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200194 mbedtls_ctr_drbg_init( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100195 test_offset_idx = 0;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200196 test_max_idx = sizeof( entropy );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100197 memset( entropy, 0, sizeof( entropy ) );
198 memset( out, 0, sizeof( out ) );
199 memset( add, 0, sizeof( add ) );
200
201 /* Init must use entropy */
202 last_idx = test_offset_idx;
Reut Caspie278b362017-10-19 08:49:19 +0100203 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100204 TEST_ASSERT( last_idx < test_offset_idx );
205
206 /* By default, PR is off and reseed_interval is large,
207 * so the next few calls should not use entropy */
208 last_idx = test_offset_idx;
209 for( i = 0; i < reps; i++ )
210 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
212 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100213 add, sizeof( add ) ) == 0 );
214 }
215 TEST_ASSERT( last_idx == test_offset_idx );
216
217 /* While at it, make sure we didn't write past the requested length */
218 TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
219 TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
220 TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
221 TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
222
223 /* Set reseed_interval to the number of calls done,
224 * so the next call should reseed */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
226 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100227 TEST_ASSERT( last_idx < test_offset_idx );
228
229 /* The new few calls should not reseed */
230 last_idx = test_offset_idx;
231 for( i = 0; i < reps / 2; i++ )
232 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
234 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100235 add, sizeof( add ) ) == 0 );
236 }
237 TEST_ASSERT( last_idx == test_offset_idx );
238
Manuel Pégourié-Gonnardf5f25b32014-11-27 14:04:56 +0100239 /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
240 * (just make sure it doesn't cause memory corruption) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );
Manuel Pégourié-Gonnardf5f25b32014-11-27 14:04:56 +0100242
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100243 /* Now enable PR, so the next few calls should all reseed */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
245 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100246 TEST_ASSERT( last_idx < test_offset_idx );
247
248 /* Finally, check setting entropy_len */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100250 last_idx = test_offset_idx;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100252 TEST_ASSERT( test_offset_idx - last_idx == 42 );
253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100255 last_idx = test_offset_idx;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100257 TEST_ASSERT( test_offset_idx - last_idx == 13 );
Paul Bakkera317a982014-06-18 16:44:11 +0200258
Paul Bakkerbd51b262014-07-10 15:26:12 +0200259exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 mbedtls_ctr_drbg_free( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100261}
262/* END_CASE */
263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100265void ctr_drbg_seed_file( char * path, int ret )
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100266{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100268
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200269 mbedtls_ctr_drbg_init( &ctx );
270
271 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 TEST_ASSERT( mbedtls_ctr_drbg_write_seed_file( &ctx, path ) == ret );
273 TEST_ASSERT( mbedtls_ctr_drbg_update_seed_file( &ctx, path ) == ret );
Paul Bakkera317a982014-06-18 16:44:11 +0200274
Paul Bakkerbd51b262014-07-10 15:26:12 +0200275exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 mbedtls_ctr_drbg_free( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100277}
278/* END_CASE */
279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +0100281void ctr_drbg_selftest( )
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100282{
Andres AG93012e82016-09-09 09:10:28 +0100283 TEST_ASSERT( mbedtls_ctr_drbg_self_test( 1 ) == 0 );
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100284}
285/* END_CASE */