• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/hmac_drbg.h"
3#include "string.h"
4
5typedef struct
6{
7    unsigned char *p;
8    size_t len;
9} entropy_ctx;
10
11static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
12{
13    entropy_ctx *ctx = (entropy_ctx *) data;
14
15    if( len > ctx->len )
16        return( -1 );
17
18    memcpy( buf, ctx->p, len );
19
20    ctx->p += len;
21    ctx->len -= len;
22
23    return( 0 );
24}
25/* END_HEADER */
26
27/* BEGIN_DEPENDENCIES
28 * depends_on:MBEDTLS_HMAC_DRBG_C
29 * END_DEPENDENCIES
30 */
31
32/* BEGIN_CASE */
33void hmac_drbg_entropy_usage( int md_alg )
34{
35    unsigned char out[16];
36    unsigned char buf[1024];
37    const mbedtls_md_info_t *md_info;
38    mbedtls_hmac_drbg_context ctx;
39    entropy_ctx entropy;
40    size_t last_len, i, reps = 10;
41
42    mbedtls_hmac_drbg_init( &ctx );
43    memset( buf, 0, sizeof( buf ) );
44    memset( out, 0, sizeof( out ) );
45
46    entropy.len = sizeof( buf );
47    entropy.p = buf;
48
49    md_info = mbedtls_md_info_from_type( md_alg );
50    TEST_ASSERT( md_info != NULL );
51
52    /* Set reseed interval before seed */
53    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
54
55    /* Init must use entropy */
56    last_len = entropy.len;
57    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy,
58                                 NULL, 0 ) == 0 );
59    TEST_ASSERT( entropy.len < last_len );
60
61    /* By default, PR is off, and reseed interval was set to
62     * 2 * reps so the next few calls should not use entropy */
63    last_len = entropy.len;
64    for( i = 0; i < reps; i++ )
65    {
66        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
67        TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
68                                                buf, 16 ) == 0 );
69    }
70    TEST_ASSERT( entropy.len == last_len );
71
72    /* While at it, make sure we didn't write past the requested length */
73    TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
74    TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
75    TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
76    TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
77
78    /* There have been 2 * reps calls to random. The next call should reseed */
79    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
80    TEST_ASSERT( entropy.len < last_len );
81
82    /* Set reseed interval after seed */
83    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 4 * reps + 1);
84
85    /* The new few calls should not reseed */
86    last_len = entropy.len;
87    for( i = 0; i < (2 * reps); i++ )
88    {
89        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
90        TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) ,
91                                                buf, 16 ) == 0 );
92    }
93    TEST_ASSERT( entropy.len == last_len );
94
95    /* Now enable PR, so the next few calls should all reseed */
96    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
97    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
98    TEST_ASSERT( entropy.len < last_len );
99
100    /* Finally, check setting entropy_len */
101    mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 );
102    last_len = entropy.len;
103    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
104    TEST_ASSERT( (int) last_len - entropy.len == 42 );
105
106    mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 );
107    last_len = entropy.len;
108    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
109    TEST_ASSERT( (int) last_len - entropy.len == 13 );
110
111exit:
112    mbedtls_hmac_drbg_free( &ctx );
113}
114/* END_CASE */
115
116/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
117void hmac_drbg_seed_file( int md_alg, char * path, int ret )
118{
119    const mbedtls_md_info_t *md_info;
120    mbedtls_hmac_drbg_context ctx;
121
122    mbedtls_hmac_drbg_init( &ctx );
123
124    md_info = mbedtls_md_info_from_type( md_alg );
125    TEST_ASSERT( md_info != NULL );
126
127    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, rnd_std_rand, NULL,
128                                 NULL, 0 ) == 0 );
129
130    TEST_ASSERT( mbedtls_hmac_drbg_write_seed_file( &ctx, path ) == ret );
131    TEST_ASSERT( mbedtls_hmac_drbg_update_seed_file( &ctx, path ) == ret );
132
133exit:
134    mbedtls_hmac_drbg_free( &ctx );
135}
136/* END_CASE */
137
138/* BEGIN_CASE */
139void hmac_drbg_buf( int md_alg )
140{
141    unsigned char out[16];
142    unsigned char buf[100];
143    const mbedtls_md_info_t *md_info;
144    mbedtls_hmac_drbg_context ctx;
145    size_t i;
146
147    mbedtls_hmac_drbg_init( &ctx );
148    memset( buf, 0, sizeof( buf ) );
149    memset( out, 0, sizeof( out ) );
150
151    md_info = mbedtls_md_info_from_type( md_alg );
152    TEST_ASSERT( md_info != NULL );
153    TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info, buf, sizeof( buf ) ) == 0 );
154
155    /* Make sure it never tries to reseed (would segfault otherwise) */
156    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 3 );
157    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
158
159    for( i = 0; i < 30; i++ )
160        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
161
162exit:
163    mbedtls_hmac_drbg_free( &ctx );
164}
165/* END_CASE */
166
167/* BEGIN_CASE */
168void hmac_drbg_no_reseed( int md_alg, data_t * entropy,
169                          data_t * custom, data_t * add1,
170                          data_t * add2, data_t * output )
171{
172    unsigned char data[1024];
173    unsigned char my_output[512];
174    entropy_ctx p_entropy;
175    const mbedtls_md_info_t *md_info;
176    mbedtls_hmac_drbg_context ctx;
177
178    mbedtls_hmac_drbg_init( &ctx );
179
180    p_entropy.p = entropy->x;
181    p_entropy.len = entropy->len;
182
183    md_info = mbedtls_md_info_from_type( md_alg );
184    TEST_ASSERT( md_info != NULL );
185
186    /* Test the simplified buffer-based variant */
187    memcpy( data, entropy->x, p_entropy.len );
188    memcpy( data + p_entropy.len, custom->x, custom->len );
189    TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info,
190                                     data, p_entropy.len + custom->len ) == 0 );
191    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
192                                            add1->x, add1->len ) == 0 );
193    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
194                                            add2->x, add2->len ) == 0 );
195
196    /* Reset context for second run */
197    mbedtls_hmac_drbg_free( &ctx );
198
199    TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
200
201    /* And now the normal entropy-based variant */
202    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
203                                 custom->x, custom->len ) == 0 );
204    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
205                                            add1->x, add1->len ) == 0 );
206    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
207                                            add2->x, add2->len ) == 0 );
208    TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
209
210exit:
211    mbedtls_hmac_drbg_free( &ctx );
212}
213/* END_CASE */
214
215/* BEGIN_CASE */
216void hmac_drbg_nopr( int md_alg, data_t * entropy, data_t * custom,
217                     data_t * add1, data_t * add2, data_t * add3,
218                     data_t * output )
219{
220    unsigned char my_output[512];
221    entropy_ctx p_entropy;
222    const mbedtls_md_info_t *md_info;
223    mbedtls_hmac_drbg_context ctx;
224
225    mbedtls_hmac_drbg_init( &ctx );
226
227    p_entropy.p = entropy->x;
228    p_entropy.len = entropy->len;
229
230    md_info = mbedtls_md_info_from_type( md_alg );
231    TEST_ASSERT( md_info != NULL );
232
233    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
234                                 custom->x, custom->len ) == 0 );
235    TEST_ASSERT( mbedtls_hmac_drbg_reseed( &ctx, add1->x, add1->len ) == 0 );
236    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
237                                            add2->x, add2->len ) == 0 );
238    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
239                                            add3->x, add3->len ) == 0 );
240
241    TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
242
243exit:
244    mbedtls_hmac_drbg_free( &ctx );
245}
246/* END_CASE */
247
248/* BEGIN_CASE */
249void hmac_drbg_pr( int md_alg, data_t * entropy, data_t * custom,
250                   data_t * add1, data_t * add2, data_t * output )
251{
252    unsigned char my_output[512];
253    entropy_ctx p_entropy;
254    const mbedtls_md_info_t *md_info;
255    mbedtls_hmac_drbg_context ctx;
256
257    mbedtls_hmac_drbg_init( &ctx );
258
259    p_entropy.p = entropy->x;
260    p_entropy.len = entropy->len;
261
262    md_info = mbedtls_md_info_from_type( md_alg );
263    TEST_ASSERT( md_info != NULL );
264
265    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &p_entropy,
266                                 custom->x, custom->len ) == 0 );
267    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
268    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
269                                            add1->x, add1->len ) == 0 );
270    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
271                                            add2->x, add2->len ) == 0 );
272
273    TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
274
275exit:
276    mbedtls_hmac_drbg_free( &ctx );
277}
278/* END_CASE */
279
280/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
281void hmac_drbg_selftest(  )
282{
283    TEST_ASSERT( mbedtls_hmac_drbg_self_test( 1 ) == 0 );
284}
285/* END_CASE */
286