Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / mbedtls / repo / tests / suites / test_suite_entropy.function
1 /* BEGIN_HEADER */
2 #include "mbedtls/entropy.h"
3 #include "mbedtls/entropy_poll.h"
4 #include "string.h"
5
6 /*
7  * Number of calls made to entropy_dummy_source()
8  */
9 static size_t entropy_dummy_calls;
10
11 /*
12  * Dummy entropy source
13  *
14  * If data is NULL, write exactly the requested length.
15  * Otherwise, write the length indicated by data or error if negative
16  */
17 static int entropy_dummy_source( void *data, unsigned char *output,
18                                  size_t len, size_t *olen )
19 {
20     entropy_dummy_calls++;
21
22     if( data == NULL )
23         *olen = len;
24     else
25     {
26         int *d = (int *) data;
27
28         if( *d < 0 )
29             return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
30         else
31             *olen = *d;
32     }
33
34     memset( output, 0x2a, *olen );
35
36     return( 0 );
37 }
38
39 #if defined(MBEDTLS_ENTROPY_NV_SEED)
40 /*
41  * Ability to clear entropy sources to allow testing with just predefined
42  * entropy sources. This function or tests depending on it might break if there
43  * are internal changes to how entropy sources are registered.
44  *
45  * To be called immediately after mbedtls_entropy_init().
46  *
47  * Just resetting the counter. New sources will overwrite existing ones.
48  * This might break memory checks in the future if sources need 'free-ing' then
49  * as well.
50  */
51 static void entropy_clear_sources( mbedtls_entropy_context *ctx )
52 {
53     ctx->source_count = 0;
54 }
55
56 /*
57  * NV seed read/write functions that use a buffer instead of a file
58  */
59 static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
60
61 static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
62 {
63     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
64         return( -1 );
65
66     memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
67     return( 0 );
68 }
69
70 static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
71 {
72     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
73         return( -1 );
74
75     memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
76     return( 0 );
77 }
78
79 /*
80  * NV seed read/write helpers that fill the base seedfile
81  */
82 static int write_nv_seed( unsigned char *buf, size_t buf_len )
83 {
84     FILE *f;
85
86     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
87         return( -1 );
88
89     if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
90         return( -1 );
91
92     if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
93                     MBEDTLS_ENTROPY_BLOCK_SIZE )
94         return( -1 );
95
96     fclose( f );
97
98     return( 0 );
99 }
100
101 static int read_nv_seed( unsigned char *buf, size_t buf_len )
102 {
103     FILE *f;
104
105     if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
106         return( -1 );
107
108     if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
109         return( -1 );
110
111     if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
112                     MBEDTLS_ENTROPY_BLOCK_SIZE )
113         return( -1 );
114
115     fclose( f );
116
117     return( 0 );
118 }
119 #endif /* MBEDTLS_ENTROPY_NV_SEED */
120 /* END_HEADER */
121
122 /* BEGIN_DEPENDENCIES
123  * depends_on:MBEDTLS_ENTROPY_C
124  * END_DEPENDENCIES
125  */
126
127 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
128 void entropy_seed_file( char * path, int ret )
129 {
130     mbedtls_entropy_context ctx;
131
132     mbedtls_entropy_init( &ctx );
133
134     TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path ) == ret );
135     TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path ) == ret );
136
137 exit:
138     mbedtls_entropy_free( &ctx );
139 }
140 /* END_CASE */
141
142 /* BEGIN_CASE */
143 void entropy_too_many_sources(  )
144 {
145     mbedtls_entropy_context ctx;
146     size_t i;
147
148     mbedtls_entropy_init( &ctx );
149
150     /*
151      * It's hard to tell precisely when the error will occur,
152      * since we don't know how many sources were automatically added.
153      */
154     for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
155         (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
156                                            16, MBEDTLS_ENTROPY_SOURCE_WEAK );
157
158     TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
159                                              16, MBEDTLS_ENTROPY_SOURCE_WEAK )
160                  == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
161
162 exit:
163     mbedtls_entropy_free( &ctx );
164 }
165 /* END_CASE */
166
167 /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
168 void entropy_func_len( int len, int ret )
169 {
170     mbedtls_entropy_context ctx;
171     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
172     unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
173     size_t i, j;
174
175     mbedtls_entropy_init( &ctx );
176
177     /*
178      * See comments in mbedtls_entropy_self_test()
179      */
180     for( i = 0; i < 8; i++ )
181     {
182         TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
183         for( j = 0; j < sizeof( buf ); j++ )
184             acc[j] |= buf[j];
185     }
186
187     if( ret == 0 )
188         for( j = 0; j < (size_t) len; j++ )
189             TEST_ASSERT( acc[j] != 0 );
190
191     for( j = len; j < sizeof( buf ); j++ )
192         TEST_ASSERT( acc[j] == 0 );
193 }
194 /* END_CASE */
195
196 /* BEGIN_CASE */
197 void entropy_source_fail( char * path )
198 {
199     mbedtls_entropy_context ctx;
200     int fail = -1;
201     unsigned char buf[16];
202
203     mbedtls_entropy_init( &ctx );
204
205     TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
206                                              &fail, 16,
207                                              MBEDTLS_ENTROPY_SOURCE_WEAK )
208                  == 0 );
209
210     TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
211                  == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
212     TEST_ASSERT( mbedtls_entropy_gather( &ctx )
213                  == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
214 #if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
215     TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
216                  == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
217     TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
218                  == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
219 #else
220     ((void) path);
221 #endif
222
223 exit:
224     mbedtls_entropy_free( &ctx );
225 }
226 /* END_CASE */
227
228 /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
229 void entropy_threshold( int threshold, int chunk_size, int result )
230 {
231     mbedtls_entropy_context ctx;
232     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
233     int ret;
234
235     mbedtls_entropy_init( &ctx );
236
237     TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
238                                      &chunk_size, threshold,
239                                      MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
240
241     entropy_dummy_calls = 0;
242     ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
243
244     if( result >= 0 )
245     {
246         TEST_ASSERT( ret == 0 );
247 #if defined(MBEDTLS_ENTROPY_NV_SEED)
248         // Two times as much calls due to the NV seed update
249         result *= 2;
250 #endif
251         TEST_ASSERT( entropy_dummy_calls == (size_t) result );
252     }
253     else
254     {
255         TEST_ASSERT( ret == result );
256     }
257
258 exit:
259     mbedtls_entropy_free( &ctx );
260 }
261 /* END_CASE */
262
263 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
264 void nv_seed_file_create(  )
265 {
266     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
267
268     memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
269
270     TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
271 }
272 /* END_CASE */
273
274 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
275 void entropy_nv_seed_std_io(  )
276 {
277     unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
278     unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
279
280     memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
281     memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
282
283     mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
284                                   mbedtls_platform_std_nv_seed_write );
285
286     /* Check if platform NV read and write manipulate the same data */
287     TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
288     TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
289                     MBEDTLS_ENTROPY_BLOCK_SIZE );
290
291     TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
292
293     memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
294
295     /* Check if platform NV write and raw read manipulate the same data */
296     TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
297                     MBEDTLS_ENTROPY_BLOCK_SIZE );
298     TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
299
300     TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
301 }
302 /* END_CASE */
303
304 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT:MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
305 void entropy_nv_seed( data_t * read_seed )
306 {
307     mbedtls_sha512_context accumulator;
308     mbedtls_entropy_context ctx;
309
310     unsigned char header[2];
311     unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
312     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
313     unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
314     unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
315     unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
316
317     memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
318     memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
319     memset( buffer_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
320     memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
321     memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
322     memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
323
324     // Set the initial NV seed to read
325     memcpy( buffer_seed, read_seed->x, read_seed->len );
326
327     // Make sure we read/write NV seed from our buffers
328     mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
329
330     mbedtls_entropy_init( &ctx );
331     entropy_clear_sources( &ctx );
332
333     TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
334                                              MBEDTLS_ENTROPY_BLOCK_SIZE,
335                                              MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
336
337     // Do an entropy run
338     TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
339
340     // Determine what should have happened with manual entropy internal logic
341     // Only use the SHA-512 version to check
342
343     // Init accumulator
344     header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
345     mbedtls_sha512_starts( &accumulator, 0 );
346
347     // First run for updating write_seed
348     header[0] = 0;
349     mbedtls_sha512_update( &accumulator, header, 2 );
350     mbedtls_sha512_update( &accumulator, read_seed->x, read_seed->len );
351     mbedtls_sha512_finish( &accumulator, buf );
352
353     memset( &accumulator, 0, sizeof( mbedtls_sha512_context ) );
354     mbedtls_sha512_starts( &accumulator, 0 );
355     mbedtls_sha512_update( &accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
356
357     mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_seed, 0 );
358
359     // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
360     header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
361     mbedtls_sha512_update( &accumulator, header, 2 );
362     mbedtls_sha512_update( &accumulator, empty, MBEDTLS_ENTROPY_BLOCK_SIZE );
363
364     header[0] = 0;
365     mbedtls_sha512_update( &accumulator, header, 2 );
366     mbedtls_sha512_update( &accumulator, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
367     mbedtls_sha512_finish( &accumulator, buf );
368
369     mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_entropy, 0 );
370
371     // Check result of both NV file and entropy received with the manual calculations
372     TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
373     TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
374
375     mbedtls_entropy_free( &ctx );
376 }
377 /* END_CASE */
378
379 /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
380 void entropy_selftest( int result )
381 {
382     TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
383 }
384 /* END_CASE */