Merge pull request #2747 from Eltrick/stylise-dormakaba
[RRG-proxmark3.git] / common / mbedtls / hmac_drbg.c
bloba6fabb619c999a454856346295c7a50de809410e
1 /*
2 * HMAC_DRBG implementation (NIST SP 800-90)
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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).
26 #include "common.h"
28 #if defined(MBEDTLS_HMAC_DRBG_C)
30 #include "mbedtls/hmac_drbg.h"
31 #include "mbedtls/platform_util.h"
32 #include "mbedtls/error.h"
34 #include <string.h>
36 #if defined(MBEDTLS_FS_IO)
37 #include <stdio.h>
38 #endif
40 #if defined(MBEDTLS_SELF_TEST)
41 #if defined(MBEDTLS_PLATFORM_C)
42 #include "mbedtls/platform.h"
43 #else
44 #include <stdio.h>
45 #define mbedtls_printf printf
46 #endif /* MBEDTLS_SELF_TEST */
47 #endif /* MBEDTLS_PLATFORM_C */
50 * HMAC_DRBG context initialization
52 void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx) {
53 memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context));
55 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
59 * HMAC_DRBG update, using optional additional data (10.1.2.2)
61 int mbedtls_hmac_drbg_update_ret(mbedtls_hmac_drbg_context *ctx,
62 const unsigned char *additional,
63 size_t add_len) {
64 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
65 unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1;
66 unsigned char sep[1];
67 unsigned char K[MBEDTLS_MD_MAX_SIZE];
68 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
70 for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
71 /* Step 1 or 4 */
72 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0)
73 goto exit;
74 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
75 ctx->V, md_len)) != 0)
76 goto exit;
77 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
78 sep, 1)) != 0)
79 goto exit;
80 if (rounds == 2) {
81 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
82 additional, add_len)) != 0)
83 goto exit;
85 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0)
86 goto exit;
88 /* Step 2 or 5 */
89 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0)
90 goto exit;
91 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
92 ctx->V, md_len)) != 0)
93 goto exit;
94 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0)
95 goto exit;
98 exit:
99 mbedtls_platform_zeroize(K, sizeof(K));
100 return (ret);
103 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
104 void mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
105 const unsigned char *additional,
106 size_t add_len) {
107 (void) mbedtls_hmac_drbg_update_ret(ctx, additional, add_len);
109 #endif /* MBEDTLS_DEPRECATED_REMOVED */
112 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
114 int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
115 const mbedtls_md_info_t *md_info,
116 const unsigned char *data, size_t data_len) {
117 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
119 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0)
120 return (ret);
122 #if defined(MBEDTLS_THREADING_C)
123 mbedtls_mutex_init(&ctx->mutex);
124 #endif
127 * Set initial working state.
128 * Use the V memory location, which is currently all 0, to initialize the
129 * MD context with an all-zero key. Then set V to its initial value.
131 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
132 mbedtls_md_get_size(md_info))) != 0)
133 return (ret);
134 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
136 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, data, data_len)) != 0)
137 return (ret);
139 return (0);
143 * Internal function used both for seeding and reseeding the DRBG.
144 * Comments starting with arabic numbers refer to section 10.1.2.4
145 * of SP800-90A, while roman numbers refer to section 9.2.
147 static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
148 const unsigned char *additional, size_t len,
149 int use_nonce) {
150 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
151 size_t seedlen = 0;
152 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
155 size_t total_entropy_len;
157 if (use_nonce == 0)
158 total_entropy_len = ctx->entropy_len;
159 else
160 total_entropy_len = ctx->entropy_len * 3 / 2;
162 /* III. Check input length */
163 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
164 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
165 return (MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG);
169 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
171 /* IV. Gather entropy_len bytes of entropy for the seed */
172 if ((ret = ctx->f_entropy(ctx->p_entropy,
173 seed, ctx->entropy_len)) != 0) {
174 return (MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED);
176 seedlen += ctx->entropy_len;
178 /* For initial seeding, allow adding of nonce generated
179 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
180 if (use_nonce) {
181 /* Note: We don't merge the two calls to f_entropy() in order
182 * to avoid requesting too much entropy from f_entropy()
183 * at once. Specifically, if the underlying digest is not
184 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
185 * is larger than the maximum of 32 Bytes that our own
186 * entropy source implementation can emit in a single
187 * call in configurations disabling SHA-512. */
188 if ((ret = ctx->f_entropy(ctx->p_entropy,
189 seed + seedlen,
190 ctx->entropy_len / 2)) != 0) {
191 return (MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED);
194 seedlen += ctx->entropy_len / 2;
198 /* 1. Concatenate entropy and additional data if any */
199 if (additional != NULL && len != 0) {
200 memcpy(seed + seedlen, additional, len);
201 seedlen += len;
204 /* 2. Update state */
205 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, seed, seedlen)) != 0)
206 goto exit;
208 /* 3. Reset reseed_counter */
209 ctx->reseed_counter = 1;
211 exit:
212 /* 4. Done */
213 mbedtls_platform_zeroize(seed, seedlen);
214 return (ret);
218 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
220 int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
221 const unsigned char *additional, size_t len) {
222 return (hmac_drbg_reseed_core(ctx, additional, len, 0));
226 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
228 * The nonce is not passed as a separate parameter but extracted
229 * from the entropy source as suggested in 8.6.7.
231 int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
232 const mbedtls_md_info_t *md_info,
233 int (*f_entropy)(void *, unsigned char *, size_t),
234 void *p_entropy,
235 const unsigned char *custom,
236 size_t len) {
237 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
238 size_t md_size;
240 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0)
241 return (ret);
243 /* The mutex is initialized iff the md context is set up. */
244 #if defined(MBEDTLS_THREADING_C)
245 mbedtls_mutex_init(&ctx->mutex);
246 #endif
248 md_size = mbedtls_md_get_size(md_info);
251 * Set initial working state.
252 * Use the V memory location, which is currently all 0, to initialize the
253 * MD context with an all-zero key. Then set V to its initial value.
255 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0)
256 return (ret);
257 memset(ctx->V, 0x01, md_size);
259 ctx->f_entropy = f_entropy;
260 ctx->p_entropy = p_entropy;
262 if (ctx->entropy_len == 0) {
264 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
265 * each hash function, then according to SP800-90A rev1 10.1 table 2,
266 * min_entropy_len (in bits) is security_strength.
268 * (This also matches the sizes used in the NIST test vectors.)
270 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
271 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
272 32; /* better (256+) -> 256 bits */
275 if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
276 1 /* add nonce */)) != 0) {
277 return (ret);
280 return (0);
284 * Set prediction resistance
286 void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
287 int resistance) {
288 ctx->prediction_resistance = resistance;
292 * Set entropy length grabbed for seeding
294 void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len) {
295 ctx->entropy_len = len;
299 * Set reseed interval
301 void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval) {
302 ctx->reseed_interval = interval;
306 * HMAC_DRBG random function with optional additional data:
307 * 10.1.2.5 (arabic) + 9.3 (Roman)
309 int mbedtls_hmac_drbg_random_with_add(void *p_rng,
310 unsigned char *output, size_t out_len,
311 const unsigned char *additional, size_t add_len) {
312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
313 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
314 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
315 size_t left = out_len;
316 unsigned char *out = output;
318 /* II. Check request length */
319 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST)
320 return (MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG);
322 /* III. Check input length */
323 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT)
324 return (MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG);
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);
333 add_len = 0; /* VII.4 */
336 /* 2. Use additional data if any */
337 if (additional != NULL && add_len != 0) {
338 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
339 additional, add_len)) != 0)
340 goto exit;
343 /* 3, 4, 5. Generate bytes */
344 while (left != 0) {
345 size_t use_len = left > md_len ? md_len : left;
347 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0)
348 goto exit;
349 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
350 ctx->V, md_len)) != 0)
351 goto exit;
352 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0)
353 goto exit;
355 memcpy(out, ctx->V, use_len);
356 out += use_len;
357 left -= use_len;
360 /* 6. Update */
361 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
362 additional, add_len)) != 0)
363 goto exit;
365 /* 7. Update reseed counter */
366 ctx->reseed_counter++;
368 exit:
369 /* 8. Done */
370 return (ret);
374 * HMAC_DRBG random function
376 int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len) {
377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
378 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
380 #if defined(MBEDTLS_THREADING_C)
381 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
382 return (ret);
383 #endif
385 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
387 #if defined(MBEDTLS_THREADING_C)
388 if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
389 return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
390 #endif
392 return (ret);
396 * This function resets HMAC_DRBG context to the state immediately
397 * after initial call of mbedtls_hmac_drbg_init().
399 void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx) {
400 if (ctx == NULL)
401 return;
403 #if defined(MBEDTLS_THREADING_C)
404 /* The mutex is initialized iff the md context is set up. */
405 if (ctx->md_ctx.md_info != NULL)
406 mbedtls_mutex_free(&ctx->mutex);
407 #endif
408 mbedtls_md_free(&ctx->md_ctx);
409 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
410 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
413 #if defined(MBEDTLS_FS_IO)
414 int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path) {
415 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
416 FILE *f;
417 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
419 if ((f = fopen(path, "wb")) == NULL)
420 return (MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR);
422 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0)
423 goto exit;
425 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
426 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
427 goto exit;
430 ret = 0;
432 exit:
433 fclose(f);
434 mbedtls_platform_zeroize(buf, sizeof(buf));
436 return (ret);
439 int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path) {
440 int ret = 0;
441 FILE *f = NULL;
442 size_t n;
443 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
444 unsigned char c;
446 if ((f = fopen(path, "rb")) == NULL)
447 return (MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR);
449 n = fread(buf, 1, sizeof(buf), f);
450 if (fread(&c, 1, 1, f) != 0) {
451 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
452 goto exit;
454 if (n == 0 || ferror(f)) {
455 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
456 goto exit;
458 fclose(f);
459 f = NULL;
461 ret = mbedtls_hmac_drbg_update_ret(ctx, buf, n);
463 exit:
464 mbedtls_platform_zeroize(buf, sizeof(buf));
465 if (f != NULL)
466 fclose(f);
467 if (ret != 0)
468 return (ret);
469 return (mbedtls_hmac_drbg_write_seed_file(ctx, path));
471 #endif /* MBEDTLS_FS_IO */
474 #if defined(MBEDTLS_SELF_TEST)
476 #if !defined(MBEDTLS_SHA1_C)
477 /* Dummy checkup routine */
478 int mbedtls_hmac_drbg_self_test(int verbose) {
479 (void) verbose;
480 return (0);
482 #else
484 #define OUTPUT_LEN 80
486 /* From a NIST PR=true test vector */
487 static const unsigned char entropy_pr[] = {
488 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
489 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
490 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
491 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
492 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
494 static const unsigned char result_pr[OUTPUT_LEN] = {
495 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
496 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
497 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
498 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
499 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
500 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
501 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
504 /* From a NIST PR=false test vector */
505 static const unsigned char entropy_nopr[] = {
506 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
507 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
508 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
509 0xe9, 0x9d, 0xfe, 0xdf
511 static const unsigned char result_nopr[OUTPUT_LEN] = {
512 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
513 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
514 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
515 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
516 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
517 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
518 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
521 /* "Entropy" from buffer */
522 static size_t test_offset;
523 static int hmac_drbg_self_test_entropy(void *data,
524 unsigned char *buf, size_t len) {
525 const unsigned char *p = data;
526 memcpy(buf, p + test_offset, len);
527 test_offset += len;
528 return (0);
531 #define CHK( c ) if( (c) != 0 ) \
533 if( verbose != 0 ) \
534 mbedtls_printf( "failed\n" ); \
535 return( 1 ); \
539 * Checkup routine for HMAC_DRBG with SHA-1
541 int mbedtls_hmac_drbg_self_test(int verbose) {
542 mbedtls_hmac_drbg_context ctx;
543 unsigned char buf[OUTPUT_LEN];
544 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
546 mbedtls_hmac_drbg_init(&ctx);
549 * PR = True
551 if (verbose != 0)
552 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
554 test_offset = 0;
555 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
556 hmac_drbg_self_test_entropy, (void *) entropy_pr,
557 NULL, 0));
558 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
559 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
560 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
561 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
562 mbedtls_hmac_drbg_free(&ctx);
564 mbedtls_hmac_drbg_free(&ctx);
566 if (verbose != 0)
567 mbedtls_printf("passed\n");
570 * PR = False
572 if (verbose != 0)
573 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
575 mbedtls_hmac_drbg_init(&ctx);
577 test_offset = 0;
578 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
579 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
580 NULL, 0));
581 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
582 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
583 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
584 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
585 mbedtls_hmac_drbg_free(&ctx);
587 mbedtls_hmac_drbg_free(&ctx);
589 if (verbose != 0)
590 mbedtls_printf("passed\n");
592 if (verbose != 0)
593 mbedtls_printf("\n");
595 return (0);
597 #endif /* MBEDTLS_SHA1_C */
598 #endif /* MBEDTLS_SELF_TEST */
600 #endif /* MBEDTLS_HMAC_DRBG_C */