blob: c26f4f86651c98e96a4d68b0f5764cc3f9c2fbf8 [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"
Chris Jonesea0a8652021-03-09 19:11:19 +00003#include "entropy_poll.h"
Gilles Peskine72d40fc2020-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
Gilles Peskineed04a672019-10-08 14:37:27 +02007typedef enum
8{
9 DUMMY_CONSTANT_LENGTH, /* Output context->length bytes */
10 DUMMY_REQUESTED_LENGTH, /* Output whatever length was requested */
11 DUMMY_FAIL, /* Return an error code */
12} entropy_dummy_instruction;
13
14typedef struct
15{
16 entropy_dummy_instruction instruction;
17 size_t length; /* Length to return for DUMMY_CONSTANT_LENGTH */
18 size_t calls; /* Incremented at each call */
19} entropy_dummy_context;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020020
21/*
22 * Dummy entropy source
23 *
24 * If data is NULL, write exactly the requested length.
25 * Otherwise, write the length indicated by data or error if negative
26 */
Gilles Peskineed04a672019-10-08 14:37:27 +020027static int entropy_dummy_source( void *arg, unsigned char *output,
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020028 size_t len, size_t *olen )
29{
Gilles Peskineed04a672019-10-08 14:37:27 +020030 entropy_dummy_context *context = arg;
31 ++context->calls;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020032
Gilles Peskineed04a672019-10-08 14:37:27 +020033 switch( context->instruction )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020034 {
Gilles Peskineed04a672019-10-08 14:37:27 +020035 case DUMMY_CONSTANT_LENGTH:
36 *olen = context->length;
37 break;
38 case DUMMY_REQUESTED_LENGTH:
39 *olen = len;
40 break;
41 case DUMMY_FAIL:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020043 }
44
45 memset( output, 0x2a, *olen );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020046 return( 0 );
47}
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010048
49/*
50 * Ability to clear entropy sources to allow testing with just predefined
51 * entropy sources. This function or tests depending on it might break if there
52 * are internal changes to how entropy sources are registered.
53 *
54 * To be called immediately after mbedtls_entropy_init().
55 *
56 * Just resetting the counter. New sources will overwrite existing ones.
57 * This might break memory checks in the future if sources need 'free-ing' then
58 * as well.
59 */
Gilles Peskine7f246512019-10-08 14:51:49 +020060static void entropy_clear_sources( mbedtls_entropy_context *ctx )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010061{
62 ctx->source_count = 0;
63}
64
Gilles Peskine7f246512019-10-08 14:51:49 +020065#if defined(MBEDTLS_ENTROPY_NV_SEED)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010066/*
67 * NV seed read/write functions that use a buffer instead of a file
68 */
69static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
70
Jaeden Amerof7dca862019-06-27 17:31:33 +010071int buffer_nv_seed_read( 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( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
77 return( 0 );
78}
79
Jaeden Amerof7dca862019-06-27 17:31:33 +010080int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010081{
82 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
83 return( -1 );
84
85 memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
86 return( 0 );
87}
88
89/*
90 * NV seed read/write helpers that fill the base seedfile
91 */
92static int write_nv_seed( unsigned char *buf, size_t buf_len )
93{
94 FILE *f;
95
96 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
97 return( -1 );
98
99 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
100 return( -1 );
101
102 if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
103 MBEDTLS_ENTROPY_BLOCK_SIZE )
104 return( -1 );
105
106 fclose( f );
107
108 return( 0 );
109}
110
Jaeden Amerof7dca862019-06-27 17:31:33 +0100111int read_nv_seed( unsigned char *buf, size_t buf_len )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100112{
113 FILE *f;
114
115 if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
116 return( -1 );
117
118 if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
119 return( -1 );
120
121 if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
122 MBEDTLS_ENTROPY_BLOCK_SIZE )
123 return( -1 );
124
125 fclose( f );
126
127 return( 0 );
128}
Paul Bakker4a6c6fc2016-06-01 16:34:25 +0100129#endif /* MBEDTLS_ENTROPY_NV_SEED */
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200130/* END_HEADER */
131
132/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 * depends_on:MBEDTLS_ENTROPY_C
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200134 * END_DEPENDENCIES
135 */
136
Gilles Peskine3d979f72021-02-22 21:24:02 +0100137/* BEGIN_CASE */
138void entropy_init_free( int reinit )
139{
140 mbedtls_entropy_context ctx;
141
142 /* Double free is not explicitly documented to work, but it is convenient
143 * to call mbedtls_entropy_free() unconditionally on an error path without
144 * checking whether it has already been called in the success path. */
145
146 mbedtls_entropy_init( &ctx );
147 mbedtls_entropy_free( &ctx );
148
149 if( reinit )
150 mbedtls_entropy_init( &ctx );
151 mbedtls_entropy_free( &ctx );
152
153 /* This test case always succeeds, functionally speaking. A plausible
154 * bug might trigger an invalid pointer dereference or a memory leak. */
155 goto exit;
156}
157/* END_CASE */
158
Simon Butcherb7f45c52016-09-15 18:42:26 +0100159/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100160void entropy_seed_file( char * path, int ret )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path ) == ret );
167 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path ) == ret );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200168
Paul Bakkerbd51b262014-07-10 15:26:12 +0200169exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200171}
172/* END_CASE */
173
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300174/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
175void entropy_write_base_seed_file( int ret )
176{
177 mbedtls_entropy_context ctx;
178
179 mbedtls_entropy_init( &ctx );
180
181 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
182 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
183
184exit:
185 mbedtls_entropy_free( &ctx );
186}
187/* END_CASE */
188
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200189/* BEGIN_CASE */
Gilles Peskine7f246512019-10-08 14:51:49 +0200190void entropy_no_sources( )
191{
192 mbedtls_entropy_context ctx;
193 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
194
195 mbedtls_entropy_init( &ctx );
196 entropy_clear_sources( &ctx );
197 TEST_EQUAL( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ),
198 MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
199
200exit:
201 mbedtls_entropy_free( &ctx );
202}
203/* END_CASE */
204
205/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100206void entropy_too_many_sources( )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200207{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200209 size_t i;
Gilles Peskineed04a672019-10-08 14:37:27 +0200210 entropy_dummy_context dummy = {DUMMY_REQUESTED_LENGTH, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200213
214 /*
215 * It's hard to tell precisely when the error will occur,
216 * since we don't know how many sources were automatically added.
217 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218 for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
Gilles Peskineed04a672019-10-08 14:37:27 +0200219 (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200220 16, MBEDTLS_ENTROPY_SOURCE_WEAK );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200221
Gilles Peskineed04a672019-10-08 14:37:27 +0200222 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200223 16, MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200225
Paul Bakkerbd51b262014-07-10 15:26:12 +0200226exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200228}
229/* END_CASE */
230
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100231/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200232void entropy_func_len( int len, int ret )
233{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 mbedtls_entropy_context ctx;
235 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
236 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200237 size_t i, j;
238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200240
241 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242 * See comments in mbedtls_entropy_self_test()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200243 */
244 for( i = 0; i < 8; i++ )
245 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200247 for( j = 0; j < sizeof( buf ); j++ )
248 acc[j] |= buf[j];
249 }
250
251 if( ret == 0 )
252 for( j = 0; j < (size_t) len; j++ )
253 TEST_ASSERT( acc[j] != 0 );
254
255 for( j = len; j < sizeof( buf ); j++ )
256 TEST_ASSERT( acc[j] == 0 );
Gilles Peskine7aba0362021-01-31 00:07:11 +0100257
258exit:
259 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200260}
261/* END_CASE */
262
263/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100264void entropy_source_fail( char * path )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200265{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200267 unsigned char buf[16];
Gilles Peskineed04a672019-10-08 14:37:27 +0200268 entropy_dummy_context dummy = {DUMMY_FAIL, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200271
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200272 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskineed04a672019-10-08 14:37:27 +0200273 &dummy, 16,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200274 MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200275 == 0 );
276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
278 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
279 TEST_ASSERT( mbedtls_entropy_gather( &ctx )
280 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Simon Butcherb7f45c52016-09-15 18:42:26 +0100281#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
283 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
284 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
285 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200286#else
287 ((void) path);
288#endif
289
Paul Bakkerbd51b262014-07-10 15:26:12 +0200290exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200292}
293/* END_CASE */
294
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100295/* BEGIN_CASE */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200296void entropy_threshold( int threshold, int chunk_size, int result )
297{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298 mbedtls_entropy_context ctx;
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100299 entropy_dummy_context strong =
300 {DUMMY_CONSTANT_LENGTH, MBEDTLS_ENTROPY_BLOCK_SIZE, 0};
301 entropy_dummy_context weak = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200303 int ret;
304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 mbedtls_entropy_init( &ctx );
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100306 entropy_clear_sources( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200307
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100308 /* Set strong source that reaches its threshold immediately and
309 * a weak source whose threshold is a test parameter. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100311 &strong, 1,
312 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
313 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
314 &weak, threshold,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200315 MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200318
319 if( result >= 0 )
320 {
321 TEST_ASSERT( ret == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100322#if defined(MBEDTLS_ENTROPY_NV_SEED)
Gilles Peskineae679392019-11-25 18:26:23 +0100323 /* If the NV seed functionality is enabled, there are two entropy
324 * updates: before and after updating the NV seed. */
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100325 result *= 2;
326#endif
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100327 TEST_ASSERT( weak.calls == (size_t) result );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200328 }
329 else
330 {
331 TEST_ASSERT( ret == result );
332 }
333
Paul Bakkerbd51b262014-07-10 15:26:12 +0200334exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200336}
337/* END_CASE */
338
Gilles Peskine65fc0682019-10-08 15:01:34 +0200339/* BEGIN_CASE */
340void entropy_calls( int strength1, int strength2,
341 int threshold, int chunk_size,
342 int result )
343{
344 /*
345 * if result >= 0: result = expected number of calls to source 1
346 * if result < 0: result = expected return code from mbedtls_entropy_func()
347 */
348
349 mbedtls_entropy_context ctx;
350 entropy_dummy_context dummy1 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
351 entropy_dummy_context dummy2 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
352 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
353 int ret;
354
355 mbedtls_entropy_init( &ctx );
356 entropy_clear_sources( &ctx );
357
358 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
359 &dummy1, threshold,
360 strength1 ) == 0 );
361 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
362 &dummy2, threshold,
363 strength2 ) == 0 );
364
365 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
366
367 if( result >= 0 )
368 {
369 TEST_ASSERT( ret == 0 );
Gilles Peskineae679392019-11-25 18:26:23 +0100370#if defined(MBEDTLS_ENTROPY_NV_SEED)
371 /* If the NV seed functionality is enabled, there are two entropy
372 * updates: before and after updating the NV seed. */
373 result *= 2;
374#endif
Gilles Peskine65fc0682019-10-08 15:01:34 +0200375 TEST_ASSERT( dummy1.calls == (size_t) result );
376 }
377 else
378 {
379 TEST_ASSERT( ret == result );
380 }
381
382exit:
383 mbedtls_entropy_free( &ctx );
384}
385/* END_CASE */
386
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100387/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100388void nv_seed_file_create( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100389{
390 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
391
392 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
393
394 TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
395}
396/* END_CASE */
397
Paul Bakkerb598c292016-06-01 16:57:11 +0100398/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khanf1aaec92017-05-30 14:23:15 +0100399void entropy_nv_seed_std_io( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100400{
401 unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
402 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
403
404 memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
405 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
406
407 mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
408 mbedtls_platform_std_nv_seed_write );
409
410 /* Check if platform NV read and write manipulate the same data */
411 TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
412 TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
413 MBEDTLS_ENTROPY_BLOCK_SIZE );
414
415 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
416
417 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
418
419 /* Check if platform NV write and raw read manipulate the same data */
420 TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
421 MBEDTLS_ENTROPY_BLOCK_SIZE );
422 TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
423
424 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
425}
426/* END_CASE */
427
Gilles Peskine66afcca2019-06-12 19:33:42 +0200428/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khan5fcca462018-06-29 11:05:32 +0100429void entropy_nv_seed( data_t * read_seed )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100430{
Gilles Peskine66afcca2019-06-12 19:33:42 +0200431#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
432 const mbedtls_md_info_t *md_info =
433 mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
434#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
435 const mbedtls_md_info_t *md_info =
436 mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
437#else
438#error "Unsupported entropy accumulator"
439#endif
440 mbedtls_md_context_t accumulator;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100441 mbedtls_entropy_context ctx;
Gilles Peskinee39b9032019-06-12 19:31:29 +0200442 int (*original_mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
443 mbedtls_nv_seed_read;
444 int (*original_mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
445 mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100446
447 unsigned char header[2];
448 unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
449 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
450 unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100451 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
452 unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
453
454 memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
455 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100456 memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
457 memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
458 memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
459
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100460 // Make sure we read/write NV seed from our buffers
461 mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
462
Gilles Peskine66afcca2019-06-12 19:33:42 +0200463 mbedtls_md_init( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100464 mbedtls_entropy_init( &ctx );
465 entropy_clear_sources( &ctx );
466
467 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
468 MBEDTLS_ENTROPY_BLOCK_SIZE,
469 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
470
Gilles Peskine66afcca2019-06-12 19:33:42 +0200471 // Set the initial NV seed to read
472 TEST_ASSERT( read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE );
473 memcpy( buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE );
474
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100475 // Do an entropy run
476 TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100477 // Determine what should have happened with manual entropy internal logic
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100478
479 // Init accumulator
480 header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200481 TEST_ASSERT( mbedtls_md_setup( &accumulator, md_info, 0 ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100482
483 // First run for updating write_seed
484 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200485 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
486 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
487 TEST_ASSERT( mbedtls_md_update( &accumulator,
488 read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
489 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100490
Gilles Peskine66afcca2019-06-12 19:33:42 +0200491 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
492 TEST_ASSERT( mbedtls_md_update( &accumulator,
493 buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100494
Gilles Peskine66afcca2019-06-12 19:33:42 +0200495 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
496 check_seed ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100497
498 // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
499 header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200500 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
501 TEST_ASSERT( mbedtls_md_update( &accumulator,
502 empty, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100503
504 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200505 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
506 TEST_ASSERT( mbedtls_md_update( &accumulator,
507 check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
508 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100509
Gilles Peskine66afcca2019-06-12 19:33:42 +0200510 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
511 check_entropy ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100512
513 // Check result of both NV file and entropy received with the manual calculations
514 TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
515 TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
516
Gilles Peskinee39b9032019-06-12 19:31:29 +0200517exit:
Gilles Peskine66afcca2019-06-12 19:33:42 +0200518 mbedtls_md_free( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100519 mbedtls_entropy_free( &ctx );
Gilles Peskinee39b9032019-06-12 19:31:29 +0200520 mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
521 mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100522}
523/* END_CASE */
524
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100525/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
Simon Butcherb7f45c52016-09-15 18:42:26 +0100526void entropy_selftest( int result )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200527{
Andres AG93012e82016-09-09 09:10:28 +0100528 TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200529}
530/* END_CASE */