blob: 7f7d4950de78d3c9ea1ff5d70fe6467dadf6c588 [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 Peskineef0624f2018-08-03 20:23:09 +02006static size_t test_offset_idx;
7static size_t test_max_idx;
Reut Caspie278b362017-10-19 08:49:19 +01008static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +00009{
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010010 const unsigned char *p = (unsigned char *) data;
Gilles Peskineef0624f2018-08-03 20:23:09 +020011 if( test_offset_idx + len > test_max_idx )
12 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Paul Bakker3ddfa662013-11-26 17:45:20 +010013 memcpy( buf, p + test_offset_idx, len );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010014 test_offset_idx += len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +000015 return( 0 );
16}
Paul Bakker33b43f12013-08-20 11:48:36 +020017/* END_HEADER */
Paul Bakker0e04d0e2011-11-27 14:46:59 +000018
Paul Bakker33b43f12013-08-20 11:48:36 +020019/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020020 * depends_on:MBEDTLS_CTR_DRBG_C
Paul Bakker33b43f12013-08-20 11:48:36 +020021 * END_DEPENDENCIES
22 */
Paul Bakker0e04d0e2011-11-27 14:46:59 +000023
Paul Bakker33b43f12013-08-20 11:48:36 +020024/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +010025void ctr_drbg_special_behaviours( )
Paul Bakker185ccf72016-07-14 13:21:10 +010026{
27 mbedtls_ctr_drbg_context ctx;
28 unsigned char output[512];
29 unsigned char additional[512];
30
31 mbedtls_ctr_drbg_init( &ctx );
32 memset( output, 0, sizeof( output ) );
33 memset( additional, 0, sizeof( additional ) );
34
35 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
36 output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1,
37 additional, 16 ) ==
38 MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
39 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
40 output, 16,
41 additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1 ) ==
42 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
43
44 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
45 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
46 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Andres Amaya Garcia6a543362017-01-17 23:04:22 +000047
48 mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
49 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
50 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
51 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Paul Bakker185ccf72016-07-14 13:21:10 +010052exit:
53 mbedtls_ctr_drbg_free( &ctx );
54}
55/* END_CASE */
56
57/* BEGIN_CASE */
Gilles Peskine4c786652018-08-03 20:24:54 +020058
59/* BEGIN_CASE */
60void ctr_drbg_validate_no_reseed( char *add_init_string, char *entropy_string,
61 char *add1_string, char *add2_string,
62 char *result_string )
63{
64 unsigned char entropy[512];
65 unsigned char add_init[512];
66 unsigned char add1[512];
67 unsigned char add2[512];
68 mbedtls_ctr_drbg_context ctx;
69 unsigned char buf[512];
70 unsigned char result[512];
71 size_t entropy_len, add_init_len, add1_len, add2_len, result_len;
72
73 mbedtls_ctr_drbg_init( &ctx );
74
75 entropy_len = unhexify( entropy, entropy_string );
76 add_init_len = unhexify( add_init, add_init_string );
77 add1_len = unhexify( add1, add1_string );
78 add2_len = unhexify( add2, add2_string );
79 result_len = unhexify( result, result_string );
80
81 test_offset_idx = 0;
82 test_max_idx = entropy_len;
83 /* CTR_DRBG_Instantiate(entropy[:entropy_len], nonce, perso, <ignored>)
84 * where nonce||perso = add_init[add_init_len] */
85 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, entropy_len ) == 0 );
86
87 /* CTR_DRBG_Generate(result_len * 8 bits, add1[:add1_len]) -> buf */
88 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add1, add1_len ) == 0 );
89 /* CTR_DRBG_Generate(result_len * 8 bits, add2[:add2_len]) -> buf */
90 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add2, add2_len ) == 0 );
91 TEST_ASSERT( memcmp( buf, result, result_len ) == 0 );
92
93exit:
94 mbedtls_ctr_drbg_free( &ctx );
95}
96/* END_CASE */
Gilles Peskineef0624f2018-08-03 20:23:09 +020097 char *result_string )
Paul Bakker0e04d0e2011-11-27 14:46:59 +000098{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 mbedtls_ctr_drbg_context ctx;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000100 unsigned char buf[512];
Gilles Peskineef0624f2018-08-03 20:23:09 +0200101 unsigned char result[512];
102 size_t entropy_len, add_init_len, add1_len, add2_len, result_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000103
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200104 mbedtls_ctr_drbg_init( &ctx );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000105
Gilles Peskineef0624f2018-08-03 20:23:09 +0200106 entropy_len = unhexify( entropy, entropy_string );
107 result_len = unhexify( result, result_string );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000108
Paul Bakker3ddfa662013-11-26 17:45:20 +0100109 test_offset_idx = 0;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200110 test_max_idx = entropy_len;
Gilles Peskineed7da592018-08-03 20:16:52 +0200111 /* CTR_DRBG_Instantiate(entropy[:entropy_len/3], nonce, perso, <ignored>)
112 * where nonce||perso = add_init[add_init_len] */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200113 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, entropy_len / 3 ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000115
Gilles Peskineed7da592018-08-03 20:16:52 +0200116 /* CTR_DRBG_Generate(result_len * 8 bits, add1[:add1_len]) -> buf */
117 /* Then reseed because of prediction resistance. */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200118 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add1, add1_len ) == 0 );
Gilles Peskineed7da592018-08-03 20:16:52 +0200119 /* CTR_DRBG_Generate(result_len * 8 bits, add2[:add2_len]) -> buf */
120 /* Then reseed because of prediction resistance. */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200121 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add2, add2_len ) == 0 );
122 TEST_ASSERT( memcmp( buf, result, result_len ) == 0 );
Paul Bakkera317a982014-06-18 16:44:11 +0200123
Paul Bakkerbd51b262014-07-10 15:26:12 +0200124exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 mbedtls_ctr_drbg_free( &ctx );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000126}
Paul Bakker33b43f12013-08-20 11:48:36 +0200127/* END_CASE */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000128
Paul Bakker33b43f12013-08-20 11:48:36 +0200129/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100130void ctr_drbg_validate_nopr( data_t * add_init, data_t * entropy,
131 data_t * add1, data_t * add_reseed,
Gilles Peskineef0624f2018-08-03 20:23:09 +0200132 char *add2_string, char *result_string )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000133{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 mbedtls_ctr_drbg_context ctx;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000135 unsigned char buf[512];
Gilles Peskineef0624f2018-08-03 20:23:09 +0200136 unsigned char result[512];
137 size_t entropy_len, add_init_len, add1_len, add_reseed_len, add2_len, result_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000138
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200139 mbedtls_ctr_drbg_init( &ctx );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000140
Gilles Peskineef0624f2018-08-03 20:23:09 +0200141 entropy_len = unhexify( entropy, entropy_string );
142 result_len = unhexify( result, result_string );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000143
Paul Bakker3ddfa662013-11-26 17:45:20 +0100144 test_offset_idx = 0;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200145 test_max_idx = entropy_len;
Gilles Peskineed7da592018-08-03 20:16:52 +0200146 /* CTR_DRBG_Instantiate(entropy[:entropy_len/2], nonce, perso, <ignored>)
147 * where nonce||perso = add_init[add_init_len] */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200148 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_test_entropy_func, entropy, add_init, add_init_len, entropy_len / 2 ) == 0 );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000149
Gilles Peskineed7da592018-08-03 20:16:52 +0200150 /* CTR_DRBG_Generate(16 * 8 bits, add1[:add1_len]) -> buf */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200151 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add1, add1_len ) == 0 );
Gilles Peskineed7da592018-08-03 20:16:52 +0200152 /* CTR_DRBG_Reseed(entropy[entropy_len/2:entropy_len], add_reseed[:add_reseed_len]) */
Azim Khand30ca132017-06-09 04:32:58 +0100153 TEST_ASSERT( hexcmp( buf, result_str->x, 16, result_str->len ) == 0 );
Gilles Peskineed7da592018-08-03 20:16:52 +0200154 /* CTR_DRBG_Generate(16 * 8 bits, add2[:add2_len]) -> buf */
Gilles Peskineef0624f2018-08-03 20:23:09 +0200155 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, result_len, add2, add2_len ) == 0 );
156 TEST_ASSERT( memcmp( buf, result, result_len ) == 0 );
Paul Bakkera317a982014-06-18 16:44:11 +0200157
Paul Bakkerbd51b262014-07-10 15:26:12 +0200158exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 mbedtls_ctr_drbg_free( &ctx );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000160}
Paul Bakker33b43f12013-08-20 11:48:36 +0200161/* END_CASE */
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100162
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100163/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100164void ctr_drbg_entropy_usage( )
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100165{
166 unsigned char out[16];
167 unsigned char add[16];
168 unsigned char entropy[1024];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100170 size_t i, reps = 10;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200171 size_t last_idx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100172
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200173 mbedtls_ctr_drbg_init( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100174 test_offset_idx = 0;
Gilles Peskineef0624f2018-08-03 20:23:09 +0200175 test_max_idx = sizeof( entropy );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100176 memset( entropy, 0, sizeof( entropy ) );
177 memset( out, 0, sizeof( out ) );
178 memset( add, 0, sizeof( add ) );
179
180 /* Init must use entropy */
181 last_idx = test_offset_idx;
Reut Caspie278b362017-10-19 08:49:19 +0100182 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100183 TEST_ASSERT( last_idx < test_offset_idx );
184
185 /* By default, PR is off and reseed_interval is large,
186 * so the next few calls should not use entropy */
187 last_idx = test_offset_idx;
188 for( i = 0; i < reps; i++ )
189 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
191 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100192 add, sizeof( add ) ) == 0 );
193 }
194 TEST_ASSERT( last_idx == test_offset_idx );
195
196 /* While at it, make sure we didn't write past the requested length */
197 TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
198 TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
199 TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
200 TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
201
202 /* Set reseed_interval to the number of calls done,
203 * so the next call should reseed */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
205 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100206 TEST_ASSERT( last_idx < test_offset_idx );
207
208 /* The new few calls should not reseed */
209 last_idx = test_offset_idx;
210 for( i = 0; i < reps / 2; i++ )
211 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
213 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100214 add, sizeof( add ) ) == 0 );
215 }
216 TEST_ASSERT( last_idx == test_offset_idx );
217
Manuel Pégourié-Gonnardf5f25b32014-11-27 14:04:56 +0100218 /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
219 * (just make sure it doesn't cause memory corruption) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220 mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );
Manuel Pégourié-Gonnardf5f25b32014-11-27 14:04:56 +0100221
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100222 /* Now enable PR, so the next few calls should all reseed */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
224 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100225 TEST_ASSERT( last_idx < test_offset_idx );
226
227 /* Finally, check setting entropy_len */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228 mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100229 last_idx = test_offset_idx;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100231 TEST_ASSERT( test_offset_idx - last_idx == 42 );
232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233 mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100234 last_idx = test_offset_idx;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100236 TEST_ASSERT( test_offset_idx - last_idx == 13 );
Paul Bakkera317a982014-06-18 16:44:11 +0200237
Paul Bakkerbd51b262014-07-10 15:26:12 +0200238exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 mbedtls_ctr_drbg_free( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100240}
241/* END_CASE */
242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100244void ctr_drbg_seed_file( char * path, int ret )
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100245{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100247
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200248 mbedtls_ctr_drbg_init( &ctx );
249
250 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 TEST_ASSERT( mbedtls_ctr_drbg_write_seed_file( &ctx, path ) == ret );
252 TEST_ASSERT( mbedtls_ctr_drbg_update_seed_file( &ctx, path ) == ret );
Paul Bakkera317a982014-06-18 16:44:11 +0200253
Paul Bakkerbd51b262014-07-10 15:26:12 +0200254exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255 mbedtls_ctr_drbg_free( &ctx );
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100256}
257/* END_CASE */
258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +0100260void ctr_drbg_selftest( )
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100261{
Andres AG93012e82016-09-09 09:10:28 +0100262 TEST_ASSERT( mbedtls_ctr_drbg_self_test( 1 ) == 0 );
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100263}
264/* END_CASE */