blob: 6aa8dd343887690e300b2cf4caa3c81888e05fbf [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"
Gilles Peskine1e557b72020-04-14 21:28:42 +02004#include "mbedtls/md.h"
Mohammad Azim Khan67735d52017-04-06 11:55:43 +01005#include "string.h"
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +02006
7/*
8 * Number of calls made to entropy_dummy_source()
9 */
10static size_t entropy_dummy_calls;
11
12/*
13 * Dummy entropy source
14 *
15 * If data is NULL, write exactly the requested length.
16 * Otherwise, write the length indicated by data or error if negative
17 */
18static int entropy_dummy_source( void *data, unsigned char *output,
19 size_t len, size_t *olen )
20{
21 entropy_dummy_calls++;
22
23 if( data == NULL )
24 *olen = len;
25 else
26 {
27 int *d = (int *) data;
28
29 if( *d < 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020031 else
32 *olen = *d;
33 }
34
35 memset( output, 0x2a, *olen );
36
37 return( 0 );
38}
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010039
Paul Bakker4a6c6fc2016-06-01 16:34:25 +010040#if defined(MBEDTLS_ENTROPY_NV_SEED)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010041/*
42 * Ability to clear entropy sources to allow testing with just predefined
43 * entropy sources. This function or tests depending on it might break if there
44 * are internal changes to how entropy sources are registered.
45 *
46 * To be called immediately after mbedtls_entropy_init().
47 *
48 * Just resetting the counter. New sources will overwrite existing ones.
49 * This might break memory checks in the future if sources need 'free-ing' then
50 * as well.
51 */
Jaeden Amerof580d432019-06-21 12:56:05 +010052void entropy_clear_sources( mbedtls_entropy_context *ctx )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010053{
54 ctx->source_count = 0;
55}
56
57/*
58 * NV seed read/write functions that use a buffer instead of a file
59 */
60static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
61
Jaeden Amerof580d432019-06-21 12:56:05 +010062int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010063{
64 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
65 return( -1 );
66
67 memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
68 return( 0 );
69}
70
Jaeden Amerof580d432019-06-21 12:56:05 +010071int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010072{
73 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
74 return( -1 );
75
76 memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
77 return( 0 );
78}
79
80/*
81 * NV seed read/write helpers that fill the base seedfile
82 */
Jaeden Amerof580d432019-06-21 12:56:05 +010083int write_nv_seed( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010084{
85 FILE *f;
86
87 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
88 return( -1 );
89
90 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
91 return( -1 );
92
93 if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
94 MBEDTLS_ENTROPY_BLOCK_SIZE )
95 return( -1 );
96
97 fclose( f );
98
99 return( 0 );
100}
101
Jaeden Amerof580d432019-06-21 12:56:05 +0100102int read_nv_seed( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100103{
104 FILE *f;
105
106 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
107 return( -1 );
108
109 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
110 return( -1 );
111
112 if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
113 MBEDTLS_ENTROPY_BLOCK_SIZE )
114 return( -1 );
115
116 fclose( f );
117
118 return( 0 );
119}
Paul Bakker4a6c6fc2016-06-01 16:34:25 +0100120#endif /* MBEDTLS_ENTROPY_NV_SEED */
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200121/* END_HEADER */
122
123/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 * depends_on:MBEDTLS_ENTROPY_C
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200125 * END_DEPENDENCIES
126 */
127
Gilles Peskine210a0162021-02-22 21:24:02 +0100128/* BEGIN_CASE */
129void entropy_init_free( int reinit )
130{
131 mbedtls_entropy_context ctx;
132
133 /* Double free is not explicitly documented to work, but it is convenient
134 * to call mbedtls_entropy_free() unconditionally on an error path without
135 * checking whether it has already been called in the success path. */
136
137 mbedtls_entropy_init( &ctx );
138 mbedtls_entropy_free( &ctx );
139
140 if( reinit )
141 mbedtls_entropy_init( &ctx );
142 mbedtls_entropy_free( &ctx );
143
144 /* This test case always succeeds, functionally speaking. A plausible
145 * bug might trigger an invalid pointer dereference or a memory leak. */
146 goto exit;
147}
148/* END_CASE */
149
Simon Butcherb7f45c52016-09-15 18:42:26 +0100150/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100151void entropy_seed_file( char * path, int ret )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200152{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path ) == ret );
158 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path ) == ret );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200159
Paul Bakkerbd51b262014-07-10 15:26:12 +0200160exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200162}
163/* END_CASE */
164
Victor Krasnoshchok12b89cb2020-08-27 00:19:55 +0300165/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
166void entropy_write_base_seed_file( int ret )
167{
168 mbedtls_entropy_context ctx;
169
170 mbedtls_entropy_init( &ctx );
171
172 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
173 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
174
175exit:
176 mbedtls_entropy_free( &ctx );
177}
178/* END_CASE */
179
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200180/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100181void entropy_too_many_sources( )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200182{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200184 size_t i;
185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200187
188 /*
189 * It's hard to tell precisely when the error will occur,
190 * since we don't know how many sources were automatically added.
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200193 (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
194 16, MBEDTLS_ENTROPY_SOURCE_WEAK );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200195
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200196 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
197 16, MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198 == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200199
Paul Bakkerbd51b262014-07-10 15:26:12 +0200200exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200202}
203/* END_CASE */
204
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100205/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200206void entropy_func_len( int len, int ret )
207{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_entropy_context ctx;
209 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
210 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200211 size_t i, j;
212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200214
215 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 * See comments in mbedtls_entropy_self_test()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200217 */
218 for( i = 0; i < 8; i++ )
219 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200221 for( j = 0; j < sizeof( buf ); j++ )
222 acc[j] |= buf[j];
223 }
224
225 if( ret == 0 )
226 for( j = 0; j < (size_t) len; j++ )
227 TEST_ASSERT( acc[j] != 0 );
228
229 for( j = len; j < sizeof( buf ); j++ )
230 TEST_ASSERT( acc[j] == 0 );
Gilles Peskine468ef4b2021-01-31 00:07:11 +0100231
232exit:
233 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200234}
235/* END_CASE */
236
237/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100238void entropy_source_fail( char * path )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200239{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200241 int fail = -1;
242 unsigned char buf[16];
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200245
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200246 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
247 &fail, 16,
248 MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200249 == 0 );
250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
252 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
253 TEST_ASSERT( mbedtls_entropy_gather( &ctx )
254 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Simon Butcherb7f45c52016-09-15 18:42:26 +0100255#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
257 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
258 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
259 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200260#else
261 ((void) path);
262#endif
263
Paul Bakkerbd51b262014-07-10 15:26:12 +0200264exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200266}
267/* END_CASE */
268
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100269/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200270void entropy_threshold( int threshold, int chunk_size, int result )
271{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 mbedtls_entropy_context ctx;
273 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200274 int ret;
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200277
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200279 &chunk_size, threshold,
280 MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200281
282 entropy_dummy_calls = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200284
285 if( result >= 0 )
286 {
287 TEST_ASSERT( ret == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100288#if defined(MBEDTLS_ENTROPY_NV_SEED)
289 // Two times as much calls due to the NV seed update
290 result *= 2;
291#endif
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200292 TEST_ASSERT( entropy_dummy_calls == (size_t) result );
293 }
294 else
295 {
296 TEST_ASSERT( ret == result );
297 }
298
Paul Bakkerbd51b262014-07-10 15:26:12 +0200299exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200301}
302/* END_CASE */
303
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100304/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100305void nv_seed_file_create( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100306{
307 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
308
309 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
310
311 TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
312}
313/* END_CASE */
314
Paul Bakkerb598c292016-06-01 16:57:11 +0100315/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khanf1aaec92017-05-30 14:23:15 +0100316void entropy_nv_seed_std_io( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100317{
318 unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
319 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
320
321 memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
322 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
323
324 mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
325 mbedtls_platform_std_nv_seed_write );
326
327 /* Check if platform NV read and write manipulate the same data */
328 TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
329 TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
330 MBEDTLS_ENTROPY_BLOCK_SIZE );
331
332 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
333
334 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
335
336 /* Check if platform NV write and raw read manipulate the same data */
337 TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
338 MBEDTLS_ENTROPY_BLOCK_SIZE );
339 TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
340
341 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
342}
343/* END_CASE */
344
Gilles Peskine756b3f22019-06-12 19:33:42 +0200345/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khan5fcca462018-06-29 11:05:32 +0100346void entropy_nv_seed( data_t * read_seed )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100347{
Gilles Peskine756b3f22019-06-12 19:33:42 +0200348#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
349 const mbedtls_md_info_t *md_info =
350 mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
351#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
352 const mbedtls_md_info_t *md_info =
353 mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
354#else
355#error "Unsupported entropy accumulator"
356#endif
357 mbedtls_md_context_t accumulator;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100358 mbedtls_entropy_context ctx;
Gilles Peskine0450eec2019-06-12 19:31:29 +0200359 int (*original_mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
360 mbedtls_nv_seed_read;
361 int (*original_mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
362 mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100363
364 unsigned char header[2];
365 unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
366 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
367 unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100368 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
369 unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
370
371 memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
372 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100373 memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
374 memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
375 memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
376
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100377 // Make sure we read/write NV seed from our buffers
378 mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
379
Gilles Peskine756b3f22019-06-12 19:33:42 +0200380 mbedtls_md_init( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100381 mbedtls_entropy_init( &ctx );
382 entropy_clear_sources( &ctx );
383
384 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
385 MBEDTLS_ENTROPY_BLOCK_SIZE,
386 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
387
Gilles Peskine756b3f22019-06-12 19:33:42 +0200388 // Set the initial NV seed to read
389 TEST_ASSERT( read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE );
390 memcpy( buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE );
391
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100392 // Do an entropy run
393 TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100394 // Determine what should have happened with manual entropy internal logic
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100395
396 // Init accumulator
397 header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
Gilles Peskine756b3f22019-06-12 19:33:42 +0200398 TEST_ASSERT( mbedtls_md_setup( &accumulator, md_info, 0 ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100399
400 // First run for updating write_seed
401 header[0] = 0;
Gilles Peskine756b3f22019-06-12 19:33:42 +0200402 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
403 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
404 TEST_ASSERT( mbedtls_md_update( &accumulator,
405 read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
406 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100407
Gilles Peskine756b3f22019-06-12 19:33:42 +0200408 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
409 TEST_ASSERT( mbedtls_md_update( &accumulator,
410 buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100411
Gilles Peskine756b3f22019-06-12 19:33:42 +0200412 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
413 check_seed ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100414
415 // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
416 header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
Gilles Peskine756b3f22019-06-12 19:33:42 +0200417 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
418 TEST_ASSERT( mbedtls_md_update( &accumulator,
419 empty, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100420
421 header[0] = 0;
Gilles Peskine756b3f22019-06-12 19:33:42 +0200422 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
423 TEST_ASSERT( mbedtls_md_update( &accumulator,
424 check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
425 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100426
Gilles Peskine756b3f22019-06-12 19:33:42 +0200427 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
428 check_entropy ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100429
430 // Check result of both NV file and entropy received with the manual calculations
431 TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
432 TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
433
Gilles Peskine0450eec2019-06-12 19:31:29 +0200434exit:
Gilles Peskine756b3f22019-06-12 19:33:42 +0200435 mbedtls_md_free( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100436 mbedtls_entropy_free( &ctx );
Gilles Peskine0450eec2019-06-12 19:31:29 +0200437 mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
438 mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100439}
440/* END_CASE */
441
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100442/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
Simon Butcherb7f45c52016-09-15 18:42:26 +0100443void entropy_selftest( int result )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200444{
Andres AG93012e82016-09-09 09:10:28 +0100445 TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200446}
447/* END_CASE */