blob: 1a4fefde3a91a77b843834ab8327cfe2e2b30106 [file] [log] [blame]
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/entropy.h"
Paul Bakkerffbfb4c2016-06-01 15:36:18 +01003#include "mbedtls/entropy_poll.h"
Mohammad Azim Khan67735d52017-04-06 11:55:43 +01004#include "string.h"
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +02005
Gilles Peskineed04a672019-10-08 14:37:27 +02006typedef enum
7{
8 DUMMY_CONSTANT_LENGTH, /* Output context->length bytes */
9 DUMMY_REQUESTED_LENGTH, /* Output whatever length was requested */
10 DUMMY_FAIL, /* Return an error code */
11} entropy_dummy_instruction;
12
13typedef struct
14{
15 entropy_dummy_instruction instruction;
16 size_t length; /* Length to return for DUMMY_CONSTANT_LENGTH */
17 size_t calls; /* Incremented at each call */
18} entropy_dummy_context;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020019
20/*
21 * Dummy entropy source
22 *
23 * If data is NULL, write exactly the requested length.
24 * Otherwise, write the length indicated by data or error if negative
25 */
Gilles Peskineed04a672019-10-08 14:37:27 +020026static int entropy_dummy_source( void *arg, unsigned char *output,
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020027 size_t len, size_t *olen )
28{
Gilles Peskineed04a672019-10-08 14:37:27 +020029 entropy_dummy_context *context = arg;
30 ++context->calls;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020031
Gilles Peskineed04a672019-10-08 14:37:27 +020032 switch( context->instruction )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020033 {
Gilles Peskineed04a672019-10-08 14:37:27 +020034 case DUMMY_CONSTANT_LENGTH:
35 *olen = context->length;
36 break;
37 case DUMMY_REQUESTED_LENGTH:
38 *olen = len;
39 break;
40 case DUMMY_FAIL:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020042 }
43
44 memset( output, 0x2a, *olen );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020045 return( 0 );
46}
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010047
48/*
49 * Ability to clear entropy sources to allow testing with just predefined
50 * entropy sources. This function or tests depending on it might break if there
51 * are internal changes to how entropy sources are registered.
52 *
53 * To be called immediately after mbedtls_entropy_init().
54 *
55 * Just resetting the counter. New sources will overwrite existing ones.
56 * This might break memory checks in the future if sources need 'free-ing' then
57 * as well.
58 */
Gilles Peskine7f246512019-10-08 14:51:49 +020059static void entropy_clear_sources( mbedtls_entropy_context *ctx )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010060{
61 ctx->source_count = 0;
62}
63
Gilles Peskine7f246512019-10-08 14:51:49 +020064#if defined(MBEDTLS_ENTROPY_NV_SEED)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010065/*
66 * NV seed read/write functions that use a buffer instead of a file
67 */
68static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
69
Jaeden Amerof7dca862019-06-27 17:31:33 +010070int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010071{
72 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
73 return( -1 );
74
75 memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
76 return( 0 );
77}
78
Jaeden Amerof7dca862019-06-27 17:31:33 +010079int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010080{
81 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
82 return( -1 );
83
84 memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
85 return( 0 );
86}
87
88/*
89 * NV seed read/write helpers that fill the base seedfile
90 */
91static int write_nv_seed( unsigned char *buf, size_t buf_len )
92{
93 FILE *f;
94
95 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
96 return( -1 );
97
98 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
99 return( -1 );
100
101 if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
102 MBEDTLS_ENTROPY_BLOCK_SIZE )
103 return( -1 );
104
105 fclose( f );
106
107 return( 0 );
108}
109
Jaeden Amerof7dca862019-06-27 17:31:33 +0100110int read_nv_seed( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100111{
112 FILE *f;
113
114 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
115 return( -1 );
116
117 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
118 return( -1 );
119
120 if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
121 MBEDTLS_ENTROPY_BLOCK_SIZE )
122 return( -1 );
123
124 fclose( f );
125
126 return( 0 );
127}
Paul Bakker4a6c6fc2016-06-01 16:34:25 +0100128#endif /* MBEDTLS_ENTROPY_NV_SEED */
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200129/* END_HEADER */
130
131/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 * depends_on:MBEDTLS_ENTROPY_C
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200133 * END_DEPENDENCIES
134 */
135
Simon Butcherb7f45c52016-09-15 18:42:26 +0100136/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100137void entropy_seed_file( char * path, int ret )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200138{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path ) == ret );
144 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path ) == ret );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200145
Paul Bakkerbd51b262014-07-10 15:26:12 +0200146exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200148}
149/* END_CASE */
150
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200151/* BEGIN_CASE */
Gilles Peskine7f246512019-10-08 14:51:49 +0200152void entropy_no_sources( )
153{
154 mbedtls_entropy_context ctx;
155 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
156
157 mbedtls_entropy_init( &ctx );
158 entropy_clear_sources( &ctx );
159 TEST_EQUAL( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ),
160 MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
161
162exit:
163 mbedtls_entropy_free( &ctx );
164}
165/* END_CASE */
166
167/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100168void entropy_too_many_sources( )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200169{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200171 size_t i;
Gilles Peskineed04a672019-10-08 14:37:27 +0200172 entropy_dummy_context dummy = {DUMMY_REQUESTED_LENGTH, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200175
176 /*
177 * It's hard to tell precisely when the error will occur,
178 * since we don't know how many sources were automatically added.
179 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
Gilles Peskineed04a672019-10-08 14:37:27 +0200181 (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200182 16, MBEDTLS_ENTROPY_SOURCE_WEAK );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200183
Gilles Peskineed04a672019-10-08 14:37:27 +0200184 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200185 16, MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200187
Paul Bakkerbd51b262014-07-10 15:26:12 +0200188exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200190}
191/* END_CASE */
192
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100193/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200194void entropy_func_len( int len, int ret )
195{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 mbedtls_entropy_context ctx;
197 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
198 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200199 size_t i, j;
200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200202
203 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 * See comments in mbedtls_entropy_self_test()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200205 */
206 for( i = 0; i < 8; i++ )
207 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200209 for( j = 0; j < sizeof( buf ); j++ )
210 acc[j] |= buf[j];
211 }
212
213 if( ret == 0 )
214 for( j = 0; j < (size_t) len; j++ )
215 TEST_ASSERT( acc[j] != 0 );
216
217 for( j = len; j < sizeof( buf ); j++ )
218 TEST_ASSERT( acc[j] == 0 );
219}
220/* END_CASE */
221
222/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100223void entropy_source_fail( char * path )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200224{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200226 unsigned char buf[16];
Gilles Peskineed04a672019-10-08 14:37:27 +0200227 entropy_dummy_context dummy = {DUMMY_FAIL, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200228
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200230
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200231 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskineed04a672019-10-08 14:37:27 +0200232 &dummy, 16,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200233 MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200234 == 0 );
235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
237 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
238 TEST_ASSERT( mbedtls_entropy_gather( &ctx )
239 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Simon Butcherb7f45c52016-09-15 18:42:26 +0100240#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
242 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
243 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
244 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200245#else
246 ((void) path);
247#endif
248
Paul Bakkerbd51b262014-07-10 15:26:12 +0200249exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200251}
252/* END_CASE */
253
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100254/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200255void entropy_threshold( int threshold, int chunk_size, int result )
256{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 mbedtls_entropy_context ctx;
Gilles Peskineed04a672019-10-08 14:37:27 +0200258 entropy_dummy_context dummy = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200260 int ret;
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskineed04a672019-10-08 14:37:27 +0200265 &dummy, threshold,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200266 MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200267
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200269
270 if( result >= 0 )
271 {
272 TEST_ASSERT( ret == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100273#if defined(MBEDTLS_ENTROPY_NV_SEED)
Gilles Peskineae679392019-11-25 18:26:23 +0100274 /* If the NV seed functionality is enabled, there are two entropy
275 * updates: before and after updating the NV seed. */
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100276 result *= 2;
277#endif
Gilles Peskineed04a672019-10-08 14:37:27 +0200278 TEST_ASSERT( dummy.calls == (size_t) result );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200279 }
280 else
281 {
282 TEST_ASSERT( ret == result );
283 }
284
Paul Bakkerbd51b262014-07-10 15:26:12 +0200285exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200287}
288/* END_CASE */
289
Gilles Peskine65fc0682019-10-08 15:01:34 +0200290/* BEGIN_CASE */
291void entropy_calls( int strength1, int strength2,
292 int threshold, int chunk_size,
293 int result )
294{
295 /*
296 * if result >= 0: result = expected number of calls to source 1
297 * if result < 0: result = expected return code from mbedtls_entropy_func()
298 */
299
300 mbedtls_entropy_context ctx;
301 entropy_dummy_context dummy1 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
302 entropy_dummy_context dummy2 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
303 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
304 int ret;
305
306 mbedtls_entropy_init( &ctx );
307 entropy_clear_sources( &ctx );
308
309 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
310 &dummy1, threshold,
311 strength1 ) == 0 );
312 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
313 &dummy2, threshold,
314 strength2 ) == 0 );
315
316 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
317
318 if( result >= 0 )
319 {
320 TEST_ASSERT( ret == 0 );
Gilles Peskineae679392019-11-25 18:26:23 +0100321#if defined(MBEDTLS_ENTROPY_NV_SEED)
322 /* If the NV seed functionality is enabled, there are two entropy
323 * updates: before and after updating the NV seed. */
324 result *= 2;
325#endif
Gilles Peskine65fc0682019-10-08 15:01:34 +0200326 TEST_ASSERT( dummy1.calls == (size_t) result );
327 }
328 else
329 {
330 TEST_ASSERT( ret == result );
331 }
332
333exit:
334 mbedtls_entropy_free( &ctx );
335}
336/* END_CASE */
337
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100338/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100339void nv_seed_file_create( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100340{
341 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
342
343 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
344
345 TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
346}
347/* END_CASE */
348
Paul Bakkerb598c292016-06-01 16:57:11 +0100349/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khanf1aaec92017-05-30 14:23:15 +0100350void entropy_nv_seed_std_io( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100351{
352 unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
353 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
354
355 memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
356 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
357
358 mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
359 mbedtls_platform_std_nv_seed_write );
360
361 /* Check if platform NV read and write manipulate the same data */
362 TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
363 TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
364 MBEDTLS_ENTROPY_BLOCK_SIZE );
365
366 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
367
368 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
369
370 /* Check if platform NV write and raw read manipulate the same data */
371 TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
372 MBEDTLS_ENTROPY_BLOCK_SIZE );
373 TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
374
375 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
376}
377/* END_CASE */
378
Gilles Peskine66afcca2019-06-12 19:33:42 +0200379/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khan5fcca462018-06-29 11:05:32 +0100380void entropy_nv_seed( data_t * read_seed )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100381{
Gilles Peskine66afcca2019-06-12 19:33:42 +0200382#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
383 const mbedtls_md_info_t *md_info =
384 mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
385#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
386 const mbedtls_md_info_t *md_info =
387 mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
388#else
389#error "Unsupported entropy accumulator"
390#endif
391 mbedtls_md_context_t accumulator;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100392 mbedtls_entropy_context ctx;
Gilles Peskinee39b9032019-06-12 19:31:29 +0200393 int (*original_mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
394 mbedtls_nv_seed_read;
395 int (*original_mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
396 mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100397
398 unsigned char header[2];
399 unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
400 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
401 unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100402 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
403 unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
404
405 memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
406 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100407 memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
408 memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
409 memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
410
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100411 // Make sure we read/write NV seed from our buffers
412 mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
413
Gilles Peskine66afcca2019-06-12 19:33:42 +0200414 mbedtls_md_init( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100415 mbedtls_entropy_init( &ctx );
416 entropy_clear_sources( &ctx );
417
418 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
419 MBEDTLS_ENTROPY_BLOCK_SIZE,
420 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
421
Gilles Peskine66afcca2019-06-12 19:33:42 +0200422 // Set the initial NV seed to read
423 TEST_ASSERT( read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE );
424 memcpy( buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE );
425
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100426 // Do an entropy run
427 TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100428 // Determine what should have happened with manual entropy internal logic
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100429
430 // Init accumulator
431 header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200432 TEST_ASSERT( mbedtls_md_setup( &accumulator, md_info, 0 ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100433
434 // First run for updating write_seed
435 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200436 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
437 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
438 TEST_ASSERT( mbedtls_md_update( &accumulator,
439 read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
440 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100441
Gilles Peskine66afcca2019-06-12 19:33:42 +0200442 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
443 TEST_ASSERT( mbedtls_md_update( &accumulator,
444 buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100445
Gilles Peskine66afcca2019-06-12 19:33:42 +0200446 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
447 check_seed ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100448
449 // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
450 header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200451 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
452 TEST_ASSERT( mbedtls_md_update( &accumulator,
453 empty, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100454
455 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200456 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
457 TEST_ASSERT( mbedtls_md_update( &accumulator,
458 check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
459 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100460
Gilles Peskine66afcca2019-06-12 19:33:42 +0200461 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
462 check_entropy ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100463
464 // Check result of both NV file and entropy received with the manual calculations
465 TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
466 TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
467
Gilles Peskinee39b9032019-06-12 19:31:29 +0200468exit:
Gilles Peskine66afcca2019-06-12 19:33:42 +0200469 mbedtls_md_free( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100470 mbedtls_entropy_free( &ctx );
Gilles Peskinee39b9032019-06-12 19:31:29 +0200471 mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
472 mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100473}
474/* END_CASE */
475
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100476/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
Simon Butcherb7f45c52016-09-15 18:42:26 +0100477void entropy_selftest( int result )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200478{
Andres AG93012e82016-09-09 09:10:28 +0100479 TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200480}
481/* END_CASE */