xref: /third_party/mbedtls/library/hmac_drbg.c (revision a8e1175b)
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