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