1 /*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22 /*
23 * The NIST SP 800-90A DRBGs are described in the following publication.
24 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
25 * References below are based on rev. 1 (January 2012).
26 */
27
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
30 #else
31 #include MBEDTLS_CONFIG_FILE
32 #endif
33
34 #if defined(MBEDTLS_HMAC_DRBG_C)
35
36 #include "mbedtls/hmac_drbg.h"
37 #include "mbedtls/platform_util.h"
38
39 #include <string.h>
40
41 #if defined(MBEDTLS_FS_IO)
42 #include <stdio.h>
43 #endif
44
45 #if defined(MBEDTLS_SELF_TEST)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
48 #else
49 #include <stdio.h>
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_SELF_TEST */
52 #endif /* MBEDTLS_PLATFORM_C */
53
54 /*
55 * HMAC_DRBG context initialization
56 */
mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context * ctx)57 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
58 {
59 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
60
61 #if defined(MBEDTLS_THREADING_C)
62 mbedtls_mutex_init( &ctx->mutex );
63 #endif
64 }
65
66 /*
67 * HMAC_DRBG update, using optional additional data (10.1.2.2)
68 */
mbedtls_hmac_drbg_update_ret(mbedtls_hmac_drbg_context * ctx,const unsigned char * additional,size_t add_len)69 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
70 const unsigned char *additional,
71 size_t add_len )
72 {
73 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
74 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
75 unsigned char sep[1];
76 unsigned char K[MBEDTLS_MD_MAX_SIZE];
77 int ret = 0;
78
79 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
80 {
81 /* Step 1 or 4 */
82 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
83 goto exit;
84 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
85 ctx->V, md_len ) ) != 0 )
86 goto exit;
87 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
88 sep, 1 ) ) != 0 )
89 goto exit;
90 if( rounds == 2 )
91 {
92 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
93 additional, add_len ) ) != 0 )
94 goto exit;
95 }
96 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
97 goto exit;
98
99 /* Step 2 or 5 */
100 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
101 goto exit;
102 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
103 ctx->V, md_len ) ) != 0 )
104 goto exit;
105 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
106 goto exit;
107 }
108
109 exit:
110 mbedtls_platform_zeroize( K, sizeof( K ) );
111 return( ret );
112 }
113
114 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context * ctx,const unsigned char * additional,size_t add_len)115 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
116 const unsigned char *additional,
117 size_t add_len )
118 {
119 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
120 }
121 #endif /* MBEDTLS_DEPRECATED_REMOVED */
122
123 /*
124 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
125 */
mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context * ctx,const mbedtls_md_info_t * md_info,const unsigned char * data,size_t data_len)126 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
127 const mbedtls_md_info_t * md_info,
128 const unsigned char *data, size_t data_len )
129 {
130 int ret;
131
132 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
133 return( ret );
134
135 /*
136 * Set initial working state.
137 * Use the V memory location, which is currently all 0, to initialize the
138 * MD context with an all-zero key. Then set V to its initial value.
139 */
140 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
141 mbedtls_md_get_size( md_info ) ) ) != 0 )
142 return( ret );
143 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
144
145 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
146 return( ret );
147
148 return( 0 );
149 }
150
151 /*
152 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
153 */
mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context * ctx,const unsigned char * additional,size_t len)154 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
155 const unsigned char *additional, size_t len )
156 {
157 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
158 size_t seedlen;
159 int ret;
160
161 /* III. Check input length */
162 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
163 ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
164 {
165 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
166 }
167
168 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
169
170 /* IV. Gather entropy_len bytes of entropy for the seed */
171 if( ( ret = ctx->f_entropy( ctx->p_entropy,
172 seed, ctx->entropy_len ) ) != 0 )
173 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
174
175 seedlen = ctx->entropy_len;
176
177 /* 1. Concatenate entropy and additional data if any */
178 if( additional != NULL && len != 0 )
179 {
180 memcpy( seed + seedlen, additional, len );
181 seedlen += len;
182 }
183
184 /* 2. Update state */
185 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
186 goto exit;
187
188 /* 3. Reset reseed_counter */
189 ctx->reseed_counter = 1;
190
191 exit:
192 /* 4. Done */
193 mbedtls_platform_zeroize( seed, seedlen );
194 return( ret );
195 }
196
197 /*
198 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
199 */
mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context * ctx,const mbedtls_md_info_t * md_info,int (* f_entropy)(void *,unsigned char *,size_t),void * p_entropy,const unsigned char * custom,size_t len)200 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
201 const mbedtls_md_info_t * md_info,
202 int (*f_entropy)(void *, unsigned char *, size_t),
203 void *p_entropy,
204 const unsigned char *custom,
205 size_t len )
206 {
207 int ret;
208 size_t entropy_len, md_size;
209
210 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
211 return( ret );
212
213 md_size = mbedtls_md_get_size( md_info );
214
215 /*
216 * Set initial working state.
217 * Use the V memory location, which is currently all 0, to initialize the
218 * MD context with an all-zero key. Then set V to its initial value.
219 */
220 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
221 return( ret );
222 memset( ctx->V, 0x01, md_size );
223
224 ctx->f_entropy = f_entropy;
225 ctx->p_entropy = p_entropy;
226
227 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
228
229 /*
230 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
231 * each hash function, then according to SP800-90A rev1 10.1 table 2,
232 * min_entropy_len (in bits) is security_strength.
233 *
234 * (This also matches the sizes used in the NIST test vectors.)
235 */
236 entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
237 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
238 32; /* better (256+) -> 256 bits */
239
240 /*
241 * For initialisation, use more entropy to emulate a nonce
242 * (Again, matches test vectors.)
243 */
244 ctx->entropy_len = entropy_len * 3 / 2;
245
246 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
247 return( ret );
248
249 ctx->entropy_len = entropy_len;
250
251 return( 0 );
252 }
253
254 /*
255 * Set prediction resistance
256 */
mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context * ctx,int resistance)257 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
258 int resistance )
259 {
260 ctx->prediction_resistance = resistance;
261 }
262
263 /*
264 * Set entropy length grabbed for reseeds
265 */
mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context * ctx,size_t len)266 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
267 {
268 ctx->entropy_len = len;
269 }
270
271 /*
272 * Set reseed interval
273 */
mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context * ctx,int interval)274 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
275 {
276 ctx->reseed_interval = interval;
277 }
278
279 /*
280 * HMAC_DRBG random function with optional additional data:
281 * 10.1.2.5 (arabic) + 9.3 (Roman)
282 */
mbedtls_hmac_drbg_random_with_add(void * p_rng,unsigned char * output,size_t out_len,const unsigned char * additional,size_t add_len)283 int mbedtls_hmac_drbg_random_with_add( void *p_rng,
284 unsigned char *output, size_t out_len,
285 const unsigned char *additional, size_t add_len )
286 {
287 int ret;
288 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
289 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
290 size_t left = out_len;
291 unsigned char *out = output;
292
293 /* II. Check request length */
294 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
295 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
296
297 /* III. Check input length */
298 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
299 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
300
301 /* 1. (aka VII and IX) Check reseed counter and PR */
302 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
303 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
304 ctx->reseed_counter > ctx->reseed_interval ) )
305 {
306 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
307 return( ret );
308
309 add_len = 0; /* VII.4 */
310 }
311
312 /* 2. Use additional data if any */
313 if( additional != NULL && add_len != 0 )
314 {
315 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
316 additional, add_len ) ) != 0 )
317 goto exit;
318 }
319
320 /* 3, 4, 5. Generate bytes */
321 while( left != 0 )
322 {
323 size_t use_len = left > md_len ? md_len : left;
324
325 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
326 goto exit;
327 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
328 ctx->V, md_len ) ) != 0 )
329 goto exit;
330 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
331 goto exit;
332
333 use_len = (use_len < MBEDTLS_MD_MAX_SIZE) ? use_len : MBEDTLS_MD_MAX_SIZE;
334 memcpy( out, ctx->V, use_len );
335 out += use_len;
336 left -= use_len;
337 }
338
339 /* 6. Update */
340 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
341 additional, add_len ) ) != 0 )
342 goto exit;
343
344 /* 7. Update reseed counter */
345 ctx->reseed_counter++;
346
347 exit:
348 /* 8. Done */
349 return( ret );
350 }
351
352 /*
353 * HMAC_DRBG random function
354 */
mbedtls_hmac_drbg_random(void * p_rng,unsigned char * output,size_t out_len)355 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
356 {
357 int ret;
358 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
359
360 #if defined(MBEDTLS_THREADING_C)
361 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
362 return( ret );
363 #endif
364
365 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
366
367 #if defined(MBEDTLS_THREADING_C)
368 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
369 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
370 #endif
371
372 return( ret );
373 }
374
375 /*
376 * Free an HMAC_DRBG context
377 */
mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context * ctx)378 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
379 {
380 if( ctx == NULL )
381 return;
382
383 #if defined(MBEDTLS_THREADING_C)
384 mbedtls_mutex_free( &ctx->mutex );
385 #endif
386 mbedtls_md_free( &ctx->md_ctx );
387 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
388 }
389
390 #if defined(MBEDTLS_FS_IO)
mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context * ctx,const char * path)391 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
392 {
393 int ret;
394 FILE *f;
395 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
396
397 if( ( f = fopen( path, "wb" ) ) == NULL )
398 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
399
400 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
401 goto exit;
402
403 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
404 {
405 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
406 goto exit;
407 }
408
409 ret = 0;
410
411 exit:
412 fclose( f );
413 mbedtls_platform_zeroize( buf, sizeof( buf ) );
414
415 return( ret );
416 }
417
mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context * ctx,const char * path)418 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
419 {
420 int ret = 0;
421 FILE *f = NULL;
422 size_t n;
423 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
424 unsigned char c;
425
426 if( ( f = fopen( path, "rb" ) ) == NULL )
427 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
428
429 n = fread( buf, 1, sizeof( buf ), f );
430 if( fread( &c, 1, 1, f ) != 0 )
431 {
432 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
433 goto exit;
434 }
435 if( n == 0 || ferror( f ) )
436 {
437 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
438 goto exit;
439 }
440 fclose( f );
441 f = NULL;
442
443 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
444
445 exit:
446 mbedtls_platform_zeroize( buf, sizeof( buf ) );
447 if( f != NULL )
448 fclose( f );
449 if( ret != 0 )
450 return( ret );
451 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
452 }
453 #endif /* MBEDTLS_FS_IO */
454
455
456 #if defined(MBEDTLS_SELF_TEST)
457
458 #if !defined(MBEDTLS_SHA1_C)
459 /* Dummy checkup routine */
mbedtls_hmac_drbg_self_test(int verbose)460 int mbedtls_hmac_drbg_self_test( int verbose )
461 {
462 (void) verbose;
463 return( 0 );
464 }
465 #else
466
467 #define OUTPUT_LEN 80
468
469 /* From a NIST PR=true test vector */
470 static const unsigned char entropy_pr[] = {
471 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
472 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
473 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
474 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
475 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
476 static const unsigned char result_pr[OUTPUT_LEN] = {
477 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
478 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
479 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
480 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
481 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
482 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
483 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
484
485 /* From a NIST PR=false test vector */
486 static const unsigned char entropy_nopr[] = {
487 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
488 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
489 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
490 0xe9, 0x9d, 0xfe, 0xdf };
491 static const unsigned char result_nopr[OUTPUT_LEN] = {
492 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
493 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
494 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
495 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
496 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
497 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
498 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
499
500 /* "Entropy" from buffer */
501 static size_t test_offset;
hmac_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)502 static int hmac_drbg_self_test_entropy( void *data,
503 unsigned char *buf, size_t len )
504 {
505 const unsigned char *p = data;
506 memcpy( buf, p + test_offset, len );
507 test_offset += len;
508 return( 0 );
509 }
510
511 #define CHK( c ) if( (c) != 0 ) \
512 { \
513 if( verbose != 0 ) \
514 mbedtls_printf( "failed\n" ); \
515 return( 1 ); \
516 }
517
518 /*
519 * Checkup routine for HMAC_DRBG with SHA-1
520 */
mbedtls_hmac_drbg_self_test(int verbose)521 int mbedtls_hmac_drbg_self_test( int verbose )
522 {
523 mbedtls_hmac_drbg_context ctx;
524 unsigned char buf[OUTPUT_LEN];
525 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
526
527 mbedtls_hmac_drbg_init( &ctx );
528
529 /*
530 * PR = True
531 */
532 if( verbose != 0 )
533 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
534
535 test_offset = 0;
536 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
537 hmac_drbg_self_test_entropy, (void *) entropy_pr,
538 NULL, 0 ) );
539 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
540 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
541 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
542 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
543 mbedtls_hmac_drbg_free( &ctx );
544
545 mbedtls_hmac_drbg_free( &ctx );
546
547 if( verbose != 0 )
548 mbedtls_printf( "passed\n" );
549
550 /*
551 * PR = False
552 */
553 if( verbose != 0 )
554 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
555
556 mbedtls_hmac_drbg_init( &ctx );
557
558 test_offset = 0;
559 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
560 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
561 NULL, 0 ) );
562 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
563 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
564 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
565 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
566 mbedtls_hmac_drbg_free( &ctx );
567
568 mbedtls_hmac_drbg_free( &ctx );
569
570 if( verbose != 0 )
571 mbedtls_printf( "passed\n" );
572
573 if( verbose != 0 )
574 mbedtls_printf( "\n" );
575
576 return( 0 );
577 }
578 #endif /* MBEDTLS_SHA1_C */
579 #endif /* MBEDTLS_SELF_TEST */
580
581 #endif /* MBEDTLS_HMAC_DRBG_C */
582