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