blob: ad9b5a45a132e2beed0d502dce5c0cd160a9b4b9 [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 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
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200174/* BEGIN_CASE */
Gilles Peskine7f246512019-10-08 14:51:49 +0200175void entropy_no_sources( )
176{
177 mbedtls_entropy_context ctx;
178 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
179
180 mbedtls_entropy_init( &ctx );
181 entropy_clear_sources( &ctx );
182 TEST_EQUAL( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ),
183 MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
184
185exit:
186 mbedtls_entropy_free( &ctx );
187}
188/* END_CASE */
189
190/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100191void entropy_too_many_sources( )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200192{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200194 size_t i;
Gilles Peskineed04a672019-10-08 14:37:27 +0200195 entropy_dummy_context dummy = {DUMMY_REQUESTED_LENGTH, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200196
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200198
199 /*
200 * It's hard to tell precisely when the error will occur,
201 * since we don't know how many sources were automatically added.
202 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
Gilles Peskineed04a672019-10-08 14:37:27 +0200204 (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200205 16, MBEDTLS_ENTROPY_SOURCE_WEAK );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200206
Gilles Peskineed04a672019-10-08 14:37:27 +0200207 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, &dummy,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200208 16, MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200210
Paul Bakkerbd51b262014-07-10 15:26:12 +0200211exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200213}
214/* END_CASE */
215
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100216/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200217void entropy_func_len( int len, int ret )
218{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219 mbedtls_entropy_context ctx;
220 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
221 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200222 size_t i, j;
223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200225
226 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 * See comments in mbedtls_entropy_self_test()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200228 */
229 for( i = 0; i < 8; i++ )
230 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200232 for( j = 0; j < sizeof( buf ); j++ )
233 acc[j] |= buf[j];
234 }
235
236 if( ret == 0 )
237 for( j = 0; j < (size_t) len; j++ )
238 TEST_ASSERT( acc[j] != 0 );
239
240 for( j = len; j < sizeof( buf ); j++ )
241 TEST_ASSERT( acc[j] == 0 );
Gilles Peskine7aba0362021-01-31 00:07:11 +0100242
243exit:
244 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200245}
246/* END_CASE */
247
248/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100249void entropy_source_fail( char * path )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200250{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200252 unsigned char buf[16];
Gilles Peskineed04a672019-10-08 14:37:27 +0200253 entropy_dummy_context dummy = {DUMMY_FAIL, 0, 0};
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255 mbedtls_entropy_init( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200256
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200257 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskineed04a672019-10-08 14:37:27 +0200258 &dummy, 16,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200259 MBEDTLS_ENTROPY_SOURCE_WEAK )
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200260 == 0 );
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
263 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
264 TEST_ASSERT( mbedtls_entropy_gather( &ctx )
265 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Simon Butcherb7f45c52016-09-15 18:42:26 +0100266#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
268 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
269 TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
270 == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200271#else
272 ((void) path);
273#endif
274
Paul Bakkerbd51b262014-07-10 15:26:12 +0200275exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200277}
278/* END_CASE */
279
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100280/* BEGIN_CASE */
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200281void entropy_threshold( int threshold, int chunk_size, int result )
282{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 mbedtls_entropy_context ctx;
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100284 entropy_dummy_context strong =
285 {DUMMY_CONSTANT_LENGTH, MBEDTLS_ENTROPY_BLOCK_SIZE, 0};
286 entropy_dummy_context weak = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200288 int ret;
289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290 mbedtls_entropy_init( &ctx );
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100291 entropy_clear_sources( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200292
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100293 /* Set strong source that reaches its threshold immediately and
294 * a weak source whose threshold is a test parameter. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100296 &strong, 1,
297 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
298 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
299 &weak, threshold,
Manuel Pégourié-Gonnard7580ba42015-06-19 10:26:32 +0200300 MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200303
304 if( result >= 0 )
305 {
306 TEST_ASSERT( ret == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100307#if defined(MBEDTLS_ENTROPY_NV_SEED)
Gilles Peskineae679392019-11-25 18:26:23 +0100308 /* If the NV seed functionality is enabled, there are two entropy
309 * updates: before and after updating the NV seed. */
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100310 result *= 2;
311#endif
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100312 TEST_ASSERT( weak.calls == (size_t) result );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200313 }
314 else
315 {
316 TEST_ASSERT( ret == result );
317 }
318
Paul Bakkerbd51b262014-07-10 15:26:12 +0200319exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 mbedtls_entropy_free( &ctx );
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200321}
322/* END_CASE */
323
Gilles Peskine65fc0682019-10-08 15:01:34 +0200324/* BEGIN_CASE */
325void entropy_calls( int strength1, int strength2,
326 int threshold, int chunk_size,
327 int result )
328{
329 /*
330 * if result >= 0: result = expected number of calls to source 1
331 * if result < 0: result = expected return code from mbedtls_entropy_func()
332 */
333
334 mbedtls_entropy_context ctx;
335 entropy_dummy_context dummy1 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
336 entropy_dummy_context dummy2 = {DUMMY_CONSTANT_LENGTH, chunk_size, 0};
337 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
338 int ret;
339
340 mbedtls_entropy_init( &ctx );
341 entropy_clear_sources( &ctx );
342
343 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
344 &dummy1, threshold,
345 strength1 ) == 0 );
346 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
347 &dummy2, threshold,
348 strength2 ) == 0 );
349
350 ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
351
352 if( result >= 0 )
353 {
354 TEST_ASSERT( ret == 0 );
Gilles Peskineae679392019-11-25 18:26:23 +0100355#if defined(MBEDTLS_ENTROPY_NV_SEED)
356 /* If the NV seed functionality is enabled, there are two entropy
357 * updates: before and after updating the NV seed. */
358 result *= 2;
359#endif
Gilles Peskine65fc0682019-10-08 15:01:34 +0200360 TEST_ASSERT( dummy1.calls == (size_t) result );
361 }
362 else
363 {
364 TEST_ASSERT( ret == result );
365 }
366
367exit:
368 mbedtls_entropy_free( &ctx );
369}
370/* END_CASE */
371
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100372/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100373void nv_seed_file_create( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100374{
375 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
376
377 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
378
379 TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
380}
381/* END_CASE */
382
Paul Bakkerb598c292016-06-01 16:57:11 +0100383/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khanf1aaec92017-05-30 14:23:15 +0100384void entropy_nv_seed_std_io( )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100385{
386 unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
387 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
388
389 memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
390 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
391
392 mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
393 mbedtls_platform_std_nv_seed_write );
394
395 /* Check if platform NV read and write manipulate the same data */
396 TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
397 TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
398 MBEDTLS_ENTROPY_BLOCK_SIZE );
399
400 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
401
402 memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
403
404 /* Check if platform NV write and raw read manipulate the same data */
405 TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
406 MBEDTLS_ENTROPY_BLOCK_SIZE );
407 TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
408
409 TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
410}
411/* END_CASE */
412
Gilles Peskine66afcca2019-06-12 19:33:42 +0200413/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
Azim Khan5fcca462018-06-29 11:05:32 +0100414void entropy_nv_seed( data_t * read_seed )
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100415{
Gilles Peskine66afcca2019-06-12 19:33:42 +0200416#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
417 const mbedtls_md_info_t *md_info =
418 mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
419#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
420 const mbedtls_md_info_t *md_info =
421 mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
422#else
423#error "Unsupported entropy accumulator"
424#endif
425 mbedtls_md_context_t accumulator;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100426 mbedtls_entropy_context ctx;
Gilles Peskinee39b9032019-06-12 19:31:29 +0200427 int (*original_mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
428 mbedtls_nv_seed_read;
429 int (*original_mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
430 mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100431
432 unsigned char header[2];
433 unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
434 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
435 unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100436 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
437 unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
438
439 memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
440 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100441 memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
442 memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
443 memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
444
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100445 // Make sure we read/write NV seed from our buffers
446 mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
447
Gilles Peskine66afcca2019-06-12 19:33:42 +0200448 mbedtls_md_init( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100449 mbedtls_entropy_init( &ctx );
450 entropy_clear_sources( &ctx );
451
452 TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
453 MBEDTLS_ENTROPY_BLOCK_SIZE,
454 MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
455
Gilles Peskine66afcca2019-06-12 19:33:42 +0200456 // Set the initial NV seed to read
457 TEST_ASSERT( read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE );
458 memcpy( buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE );
459
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100460 // Do an entropy run
461 TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100462 // Determine what should have happened with manual entropy internal logic
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100463
464 // Init accumulator
465 header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200466 TEST_ASSERT( mbedtls_md_setup( &accumulator, md_info, 0 ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100467
468 // First run for updating write_seed
469 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200470 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
471 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
472 TEST_ASSERT( mbedtls_md_update( &accumulator,
473 read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
474 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100475
Gilles Peskine66afcca2019-06-12 19:33:42 +0200476 TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
477 TEST_ASSERT( mbedtls_md_update( &accumulator,
478 buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100479
Gilles Peskine66afcca2019-06-12 19:33:42 +0200480 TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
481 check_seed ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100482
483 // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
484 header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200485 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
486 TEST_ASSERT( mbedtls_md_update( &accumulator,
487 empty, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100488
489 header[0] = 0;
Gilles Peskine66afcca2019-06-12 19:33:42 +0200490 TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
491 TEST_ASSERT( mbedtls_md_update( &accumulator,
492 check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
493 TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 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_entropy ) == 0 );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100497
498 // Check result of both NV file and entropy received with the manual calculations
499 TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
500 TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
501
Gilles Peskinee39b9032019-06-12 19:31:29 +0200502exit:
Gilles Peskine66afcca2019-06-12 19:33:42 +0200503 mbedtls_md_free( &accumulator );
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100504 mbedtls_entropy_free( &ctx );
Gilles Peskinee39b9032019-06-12 19:31:29 +0200505 mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
506 mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100507}
508/* END_CASE */
509
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100510/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
Simon Butcherb7f45c52016-09-15 18:42:26 +0100511void entropy_selftest( int result )
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200512{
Andres AG93012e82016-09-09 09:10:28 +0100513 TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200514}
515/* END_CASE */