Update mbedTLS sources
[platform/upstream/iotivity.git] / extlibs / mbedtls / mbedtls / tests / suites / test_suite_ctr_drbg.function
1 /* BEGIN_HEADER */
2 #include "mbedtls/entropy.h"
3 #include "mbedtls/ctr_drbg.h"
4 #include "string.h"
5
6 /* Modes for ctr_drbg_validate */
7 enum reseed_mode
8 {
9     RESEED_NEVER, /* never reseed */
10     RESEED_FIRST, /* instantiate, reseed, generate, generate */
11     RESEED_SECOND, /* instantiate, generate, reseed, generate */
12     RESEED_ALWAYS /* prediction resistance, no explicit reseed */
13 };
14
15 static size_t test_offset_idx = 0;
16 static size_t test_max_idx  = 0;
17 static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
18 {
19     const unsigned char *p = (unsigned char *) data;
20     if( test_offset_idx + len > test_max_idx )
21         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
22     memcpy( buf, p + test_offset_idx, len );
23     test_offset_idx += len;
24     return( 0 );
25 }
26
27 static void ctr_drbg_validate_internal( int reseed_mode, data_t * nonce,
28                         int entropy_len_arg, data_t * entropy,
29                         data_t * reseed,
30                         data_t * add1, data_t * add2,
31                         data_t * result )
32 {
33     mbedtls_ctr_drbg_context ctx;
34     unsigned char buf[64];
35
36     size_t entropy_chunk_len = (size_t) entropy_len_arg;
37
38     TEST_ASSERT( entropy_chunk_len <= sizeof( buf ) );
39
40     test_offset_idx = 0;
41     mbedtls_ctr_drbg_init( &ctx );
42
43     test_max_idx = entropy->len;
44
45     /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
46      * where nonce||perso = nonce[nonce->len] */
47     TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len(
48                      &ctx,
49                      mbedtls_test_entropy_func, entropy->x,
50                      nonce->x, nonce->len,
51                      entropy_chunk_len ) == 0 );
52     if( reseed_mode == RESEED_ALWAYS )
53         mbedtls_ctr_drbg_set_prediction_resistance(
54             &ctx,
55             MBEDTLS_CTR_DRBG_PR_ON );
56
57     if( reseed_mode == RESEED_FIRST )
58     {
59         /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
60          *                 reseed[:reseed->len]) */
61         TEST_ASSERT( mbedtls_ctr_drbg_reseed(
62                          &ctx,
63                          reseed->x, reseed->len ) == 0 );
64     }
65
66     /* CTR_DRBG_Generate(result->len * 8 bits, add1[:add1->len]) -> buf */
67     /* Then reseed if prediction resistance is enabled. */
68     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
69                      &ctx,
70                      buf, result->len,
71                      add1->x, add1->len ) == 0 );
72
73
74     if( reseed_mode == RESEED_SECOND )
75     {
76         /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
77          *                 reseed[:reseed->len]) */
78         TEST_ASSERT( mbedtls_ctr_drbg_reseed(
79                          &ctx,
80                          reseed->x, reseed->len ) == 0 );
81     }
82
83     /* CTR_DRBG_Generate(result->len * 8 bits, add2->x[:add2->len]) -> buf */
84     /* Then reseed if prediction resistance is enabled. */
85     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
86                      &ctx,
87                      buf, result->len,
88                      add2->x, add2->len ) == 0 );
89     TEST_ASSERT( memcmp( buf, result->x, result->len ) == 0 );
90
91 exit:
92     mbedtls_ctr_drbg_free( &ctx );
93 }
94
95 /* END_HEADER */
96
97 /* BEGIN_DEPENDENCIES
98  * depends_on:MBEDTLS_CTR_DRBG_C
99  * END_DEPENDENCIES
100  */
101
102 /* BEGIN_CASE */
103 void ctr_drbg_special_behaviours( )
104 {
105     mbedtls_ctr_drbg_context ctx;
106     unsigned char output[512];
107     unsigned char additional[512];
108
109     mbedtls_ctr_drbg_init( &ctx );
110     memset( output, 0, sizeof( output ) );
111     memset( additional, 0, sizeof( additional ) );
112
113     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
114                         output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1,
115                         additional, 16 ) ==
116                         MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
117     TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
118                         output, 16,
119                         additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1 ) ==
120                         MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
121
122     TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
123                         MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
124                         MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
125
126     mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
127     TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
128                         MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
129                         MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
130 exit:
131     mbedtls_ctr_drbg_free( &ctx );
132 }
133 /* END_CASE */
134
135
136 /* BEGIN_CASE */
137 void ctr_drbg_validate_no_reseed( data_t * add_init, data_t * entropy,
138                                   data_t * add1, data_t * add2,
139                                   data_t * result_string )
140 {
141     data_t empty = { 0, 0 };
142     ctr_drbg_validate_internal( RESEED_NEVER, add_init,
143                                 entropy->len, entropy,
144                                 &empty, add1, add2,
145                                 result_string );
146     goto exit; // goto is needed to avoid warning ( no test assertions in func)
147 }
148 /* END_CASE */
149
150 /* BEGIN_CASE */
151 void ctr_drbg_validate_pr( data_t * add_init, data_t * entropy,
152                            data_t * add1, data_t * add2,
153                            data_t * result_string )
154 {
155     data_t empty = { 0, 0 };
156     ctr_drbg_validate_internal( RESEED_ALWAYS, add_init,
157                                 entropy->len / 3, entropy,
158                                 &empty, add1, add2,
159                                 result_string );
160     goto exit; // goto is needed to avoid warning ( no test assertions in func)
161 }
162 /* END_CASE */
163
164 /* BEGIN_CASE */
165 void ctr_drbg_validate_reseed_between( data_t * add_init, data_t * entropy,
166                              data_t * add1, data_t * add_reseed,
167                              data_t * add2, data_t * result_string )
168 {
169     ctr_drbg_validate_internal( RESEED_SECOND, add_init,
170                                 entropy->len / 2, entropy,
171                                 add_reseed, add1, add2,
172                                 result_string );
173     goto exit; // goto is needed to avoid warning ( no test assertions in func)
174 }
175 /* END_CASE */
176
177 /* BEGIN_CASE */
178 void ctr_drbg_validate_reseed_first( data_t * add_init, data_t * entropy,
179                              data_t * add1, data_t * add_reseed,
180                              data_t * add2, data_t * result_string )
181 {
182     ctr_drbg_validate_internal( RESEED_FIRST, add_init,
183                                 entropy->len / 2, entropy,
184                                 add_reseed, add1, add2,
185                                 result_string );
186     goto exit; // goto is needed to avoid warning ( no test assertions in func)
187 }
188 /* END_CASE */
189
190
191
192 /* BEGIN_CASE */
193 void ctr_drbg_entropy_usage(  )
194 {
195     unsigned char out[16];
196     unsigned char add[16];
197     unsigned char entropy[1024];
198     mbedtls_ctr_drbg_context ctx;
199     size_t i, reps = 10;
200     size_t last_idx;
201
202     mbedtls_ctr_drbg_init( &ctx );
203     test_offset_idx = 0;
204     test_max_idx = sizeof( entropy );
205     memset( entropy, 0, sizeof( entropy ) );
206     memset( out, 0, sizeof( out ) );
207     memset( add, 0, sizeof( add ) );
208
209     /* Init must use entropy */
210     last_idx = test_offset_idx;
211     TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
212     TEST_ASSERT( last_idx < test_offset_idx );
213
214     /* By default, PR is off and reseed_interval is large,
215      * so the next few calls should not use entropy */
216     last_idx = test_offset_idx;
217     for( i = 0; i < reps; i++ )
218     {
219         TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
220         TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
221                                                 add, sizeof( add ) ) == 0 );
222     }
223     TEST_ASSERT( last_idx == test_offset_idx );
224
225     /* While at it, make sure we didn't write past the requested length */
226     TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
227     TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
228     TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
229     TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
230
231     /* Set reseed_interval to the number of calls done,
232      * so the next call should reseed */
233     mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
234     TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
235     TEST_ASSERT( last_idx < test_offset_idx );
236
237     /* The new few calls should not reseed */
238     last_idx = test_offset_idx;
239     for( i = 0; i < reps / 2; i++ )
240     {
241         TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
242         TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
243                                                 add, sizeof( add ) ) == 0 );
244     }
245     TEST_ASSERT( last_idx == test_offset_idx );
246
247     /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
248      * Make sure it's detected as an error and doesn't cause memory
249      * corruption. */
250     TEST_ASSERT( mbedtls_ctr_drbg_update_ret(
251                      &ctx, entropy, sizeof( entropy ) ) != 0 );
252
253     /* Now enable PR, so the next few calls should all reseed */
254     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
255     TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
256     TEST_ASSERT( last_idx < test_offset_idx );
257
258     /* Finally, check setting entropy_len */
259     mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 );
260     last_idx = test_offset_idx;
261     TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
262     TEST_ASSERT( test_offset_idx - last_idx == 42 );
263
264     mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 );
265     last_idx = test_offset_idx;
266     TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
267     TEST_ASSERT( test_offset_idx - last_idx == 13 );
268
269 exit:
270     mbedtls_ctr_drbg_free( &ctx );
271 }
272 /* END_CASE */
273
274 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
275 void ctr_drbg_seed_file( char * path, int ret )
276 {
277     mbedtls_ctr_drbg_context ctx;
278
279     mbedtls_ctr_drbg_init( &ctx );
280
281     TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 );
282     TEST_ASSERT( mbedtls_ctr_drbg_write_seed_file( &ctx, path ) == ret );
283     TEST_ASSERT( mbedtls_ctr_drbg_update_seed_file( &ctx, path ) == ret );
284
285 exit:
286     mbedtls_ctr_drbg_free( &ctx );
287 }
288 /* END_CASE */
289
290 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
291 void ctr_drbg_selftest(  )
292 {
293     TEST_ASSERT( mbedtls_ctr_drbg_self_test( 1 ) == 0 );
294 }
295 /* END_CASE */