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