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