Coverage Report

Created: 2025-03-01 06:26

/src/mbedtls/library/ctr_drbg.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  CTR_DRBG implementation based on AES-256 (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
 *  The NIST SP 800-90 DRBGs are described in the following publication.
9
 *
10
 *  https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf
11
 */
12
13
#include "common.h"
14
15
#if defined(MBEDTLS_CTR_DRBG_C)
16
17
#include "ctr.h"
18
#include "mbedtls/ctr_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
/* Using error translation functions from PSA to MbedTLS */
29
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
30
#include "psa_util_internal.h"
31
#endif
32
33
#include "mbedtls/platform.h"
34
35
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
36
static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
37
                                               unsigned char *key, size_t key_len)
38
{
39
    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
40
    psa_status_t status;
41
42
    psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
43
    psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
44
    psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
45
    status = psa_import_key(&key_attr, key, key_len, &psa_ctx->key_id);
46
    if (status != PSA_SUCCESS) {
47
        goto exit;
48
    }
49
50
    status = psa_cipher_encrypt_setup(&psa_ctx->operation, psa_ctx->key_id, PSA_ALG_ECB_NO_PADDING);
51
    if (status != PSA_SUCCESS) {
52
        goto exit;
53
    }
54
55
exit:
56
    psa_reset_key_attributes(&key_attr);
57
    return status;
58
}
59
60
static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx)
61
{
62
    psa_cipher_abort(&psa_ctx->operation);
63
    psa_destroy_key(psa_ctx->key_id);
64
65
    psa_ctx->operation = psa_cipher_operation_init();
66
    psa_ctx->key_id = MBEDTLS_SVC_KEY_ID_INIT;
67
}
68
#endif
69
70
/*
71
 * CTR_DRBG context initialization
72
 */
73
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
74
2
{
75
2
    memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
76
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
77
    ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
78
    ctx->psa_ctx.operation = psa_cipher_operation_init();
79
#else
80
2
    mbedtls_aes_init(&ctx->aes_ctx);
81
2
#endif
82
    /* Indicate that the entropy nonce length is not set explicitly.
83
     * See mbedtls_ctr_drbg_set_nonce_len(). */
84
2
    ctx->reseed_counter = -1;
85
86
2
    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
87
2
}
88
89
/*
90
 *  This function resets CTR_DRBG context to the state immediately
91
 *  after initial call of mbedtls_ctr_drbg_init().
92
 */
93
void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
94
2
{
95
2
    if (ctx == NULL) {
96
0
        return;
97
0
    }
98
99
2
#if defined(MBEDTLS_THREADING_C)
100
    /* The mutex is initialized iff f_entropy is set. */
101
2
    if (ctx->f_entropy != NULL) {
102
2
        mbedtls_mutex_free(&ctx->mutex);
103
2
    }
104
2
#endif
105
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
106
    ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
107
#else
108
2
    mbedtls_aes_free(&ctx->aes_ctx);
109
2
#endif
110
2
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
111
2
    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
112
2
    ctx->reseed_counter = -1;
113
2
}
114
115
void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
116
                                                int resistance)
117
0
{
118
0
    ctx->prediction_resistance = resistance;
119
0
}
120
121
void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
122
                                      size_t len)
123
0
{
124
0
    ctx->entropy_len = len;
125
0
}
126
127
int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
128
                                   size_t len)
129
0
{
130
    /* If mbedtls_ctr_drbg_seed() has already been called, it's
131
     * too late. Return the error code that's closest to making sense. */
132
0
    if (ctx->f_entropy != NULL) {
133
0
        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
134
0
    }
135
136
0
    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
137
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
138
0
    }
139
140
    /* This shouldn't be an issue because
141
     * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
142
     * configuration, but make sure anyway. */
143
0
    if (len > INT_MAX) {
144
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
145
0
    }
146
147
    /* For backward compatibility with Mbed TLS <= 2.19, store the
148
     * entropy nonce length in a field that already exists, but isn't
149
     * used until after the initial seeding. */
150
    /* Due to the capping of len above, the value fits in an int. */
151
0
    ctx->reseed_counter = (int) len;
152
0
    return 0;
153
0
}
154
155
void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
156
                                          int interval)
157
0
{
158
0
    ctx->reseed_interval = interval;
159
0
}
160
161
static int block_cipher_df(unsigned char *output,
162
                           const unsigned char *data, size_t data_len)
163
0
{
164
0
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
165
0
                      MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
166
0
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
167
0
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
168
0
    unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
169
0
    unsigned char *p, *iv;
170
0
    int ret = 0;
171
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
172
    psa_status_t status;
173
    size_t tmp_len;
174
    mbedtls_ctr_drbg_psa_context psa_ctx;
175
176
    psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
177
    psa_ctx.operation = psa_cipher_operation_init();
178
#else
179
0
    mbedtls_aes_context aes_ctx;
180
0
#endif
181
182
0
    int i, j;
183
0
    size_t buf_len, use_len;
184
185
0
    if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
186
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
187
0
    }
188
189
0
    memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
190
0
           MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
191
192
    /*
193
     * Construct IV (16 bytes) and S in buffer
194
     * IV = Counter (in 32-bits) padded to 16 with zeroes
195
     * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
196
     *     data || 0x80
197
     *     (Total is padded to a multiple of 16-bytes with zeroes)
198
     */
199
0
    p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
200
0
    MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
201
0
    p += 4 + 3;
202
0
    *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
203
0
    memcpy(p, data, data_len);
204
0
    p[data_len] = 0x80;
205
206
0
    buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
207
208
0
    for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
209
0
        key[i] = i;
210
0
    }
211
212
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
213
    status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
214
    if (status != PSA_SUCCESS) {
215
        ret = psa_generic_status_to_mbedtls(status);
216
        goto exit;
217
    }
218
#else
219
0
    mbedtls_aes_init(&aes_ctx);
220
221
0
    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
222
0
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
223
0
        goto exit;
224
0
    }
225
0
#endif
226
227
    /*
228
     * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
229
     */
230
0
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
231
0
        p = buf;
232
0
        memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
233
0
        use_len = buf_len;
234
235
0
        while (use_len > 0) {
236
0
            mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE);
237
0
            p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
238
0
            use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
239
0
                       MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
240
241
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
242
            status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
243
                                       chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
244
            if (status != PSA_SUCCESS) {
245
                ret = psa_generic_status_to_mbedtls(status);
246
                goto exit;
247
            }
248
#else
249
0
            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
250
0
                                             chain, chain)) != 0) {
251
0
                goto exit;
252
0
            }
253
0
#endif
254
0
        }
255
256
0
        memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
257
258
        /*
259
         * Update IV
260
         */
261
0
        buf[3]++;
262
0
    }
263
264
    /*
265
     * Do final encryption with reduced data
266
     */
267
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
268
    ctr_drbg_destroy_psa_contex(&psa_ctx);
269
270
    status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
271
    if (status != PSA_SUCCESS) {
272
        ret = psa_generic_status_to_mbedtls(status);
273
        goto exit;
274
    }
275
#else
276
0
    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
277
0
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
278
0
        goto exit;
279
0
    }
280
0
#endif
281
0
    iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
282
0
    p = output;
283
284
0
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
285
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
286
        status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
287
                                   iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
288
        if (status != PSA_SUCCESS) {
289
            ret = psa_generic_status_to_mbedtls(status);
290
            goto exit;
291
        }
292
#else
293
0
        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
294
0
                                         iv, iv)) != 0) {
295
0
            goto exit;
296
0
        }
297
0
#endif
298
0
        memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
299
0
        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
300
0
    }
301
0
exit:
302
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
303
    ctr_drbg_destroy_psa_contex(&psa_ctx);
304
#else
305
0
    mbedtls_aes_free(&aes_ctx);
306
0
#endif
307
    /*
308
     * tidy up the stack
309
     */
310
0
    mbedtls_platform_zeroize(buf, sizeof(buf));
311
0
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
312
0
    mbedtls_platform_zeroize(key, sizeof(key));
313
0
    mbedtls_platform_zeroize(chain, sizeof(chain));
314
0
    if (0 != ret) {
315
        /*
316
         * wipe partial seed from memory
317
         */
318
0
        mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
319
0
    }
320
321
0
    return ret;
322
0
}
323
324
/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
325
 * ctr_drbg_update_internal(ctx, provided_data)
326
 * implements
327
 * CTR_DRBG_Update(provided_data, Key, V)
328
 * with inputs and outputs
329
 *   ctx->aes_ctx = Key
330
 *   ctx->counter = V
331
 */
332
static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
333
                                    const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
334
0
{
335
0
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
336
0
    unsigned char *p = tmp;
337
0
    int j;
338
0
    int ret = 0;
339
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
340
    psa_status_t status;
341
    size_t tmp_len;
342
#endif
343
344
0
    memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
345
346
0
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
347
        /*
348
         * Increase counter
349
         */
350
0
        mbedtls_ctr_increment_counter(ctx->counter);
351
352
        /*
353
         * Crypt counter block
354
         */
355
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
356
        status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
357
                                   p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
358
        if (status != PSA_SUCCESS) {
359
            ret = psa_generic_status_to_mbedtls(status);
360
            goto exit;
361
        }
362
#else
363
0
        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
364
0
                                         ctx->counter, p)) != 0) {
365
0
            goto exit;
366
0
        }
367
0
#endif
368
369
0
        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
370
0
    }
371
372
0
    mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN);
373
374
    /*
375
     * Update key and counter
376
     */
377
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
378
    ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
379
380
    status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
381
    if (status != PSA_SUCCESS) {
382
        ret = psa_generic_status_to_mbedtls(status);
383
        goto exit;
384
    }
385
#else
386
0
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
387
0
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
388
0
        goto exit;
389
0
    }
390
0
#endif
391
0
    memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
392
0
           MBEDTLS_CTR_DRBG_BLOCKSIZE);
393
394
0
exit:
395
0
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
396
0
    return ret;
397
0
}
398
399
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
400
 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
401
 * implements
402
 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
403
 *                      security_strength) -> initial_working_state
404
 * with inputs
405
 *   ctx->counter = all-bits-0
406
 *   ctx->aes_ctx = context from all-bits-0 key
407
 *   additional[:add_len] = entropy_input || nonce || personalization_string
408
 * and with outputs
409
 *   ctx = initial_working_state
410
 */
411
int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
412
                            const unsigned char *additional,
413
                            size_t add_len)
414
0
{
415
0
    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
416
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
417
418
0
    if (add_len == 0) {
419
0
        return 0;
420
0
    }
421
422
0
    if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
423
0
        goto exit;
424
0
    }
425
0
    if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
426
0
        goto exit;
427
0
    }
428
429
0
exit:
430
0
    mbedtls_platform_zeroize(add_input, sizeof(add_input));
431
0
    return ret;
432
0
}
433
434
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
435
 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
436
 * implements
437
 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
438
 *                -> new_working_state
439
 * with inputs
440
 *   ctx contains working_state
441
 *   additional[:len] = additional_input
442
 * and entropy_input comes from calling ctx->f_entropy
443
 *                              for (ctx->entropy_len + nonce_len) bytes
444
 * and with output
445
 *   ctx contains new_working_state
446
 */
447
static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx,
448
                                            const unsigned char *additional,
449
                                            size_t len,
450
                                            size_t nonce_len)
451
2
{
452
2
    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
453
2
    size_t seedlen = 0;
454
2
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
455
456
2
    if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
457
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
458
0
    }
459
2
    if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
460
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
461
0
    }
462
2
    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
463
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
464
0
    }
465
466
2
    memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
467
468
    /* Gather entropy_len bytes of entropy to seed state. */
469
2
    if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
470
2
        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
471
2
    }
472
0
    seedlen += ctx->entropy_len;
473
474
    /* Gather entropy for a nonce if requested. */
475
0
    if (nonce_len != 0) {
476
0
        if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
477
0
            return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
478
0
        }
479
0
        seedlen += nonce_len;
480
0
    }
481
482
    /* Add additional data if provided. */
483
0
    if (additional != NULL && len != 0) {
484
0
        memcpy(seed + seedlen, additional, len);
485
0
        seedlen += len;
486
0
    }
487
488
    /* Reduce to 384 bits. */
489
0
    if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
490
0
        goto exit;
491
0
    }
492
493
    /* Update state. */
494
0
    if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
495
0
        goto exit;
496
0
    }
497
0
    ctx->reseed_counter = 1;
498
499
0
exit:
500
0
    mbedtls_platform_zeroize(seed, sizeof(seed));
501
0
    return ret;
502
0
}
503
504
int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
505
                            const unsigned char *additional, size_t len)
506
0
{
507
0
    return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
508
0
}
509
510
/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
511
 * is sufficient to achieve the maximum security strength given the key
512
 * size and entropy length. If there is enough entropy in the initial
513
 * call to the entropy function to serve as both the entropy input and
514
 * the nonce, don't make a second call to get a nonce. */
515
static size_t good_nonce_len(size_t entropy_len)
516
2
{
517
2
    if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
518
2
        return 0;
519
2
    } else {
520
0
        return (entropy_len + 1) / 2;
521
0
    }
522
2
}
523
524
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
525
 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
526
 * implements
527
 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
528
 *                      security_strength) -> initial_working_state
529
 * with inputs
530
 *   custom[:len] = nonce || personalization_string
531
 * where entropy_input comes from f_entropy for ctx->entropy_len bytes
532
 * and with outputs
533
 *   ctx = initial_working_state
534
 */
535
int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
536
                          int (*f_entropy)(void *, unsigned char *, size_t),
537
                          void *p_entropy,
538
                          const unsigned char *custom,
539
                          size_t len)
540
2
{
541
2
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
542
2
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
543
2
    size_t nonce_len;
544
545
2
    memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE);
546
547
    /* The mutex is initialized iff f_entropy is set. */
548
2
#if defined(MBEDTLS_THREADING_C)
549
2
    mbedtls_mutex_init(&ctx->mutex);
550
2
#endif
551
552
2
    ctx->f_entropy = f_entropy;
553
2
    ctx->p_entropy = p_entropy;
554
555
2
    if (ctx->entropy_len == 0) {
556
2
        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
557
2
    }
558
    /* ctx->reseed_counter contains the desired amount of entropy to
559
     * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
560
     * If it's -1, indicating that the entropy nonce length was not set
561
     * explicitly, use a sufficiently large nonce for security. */
562
2
    nonce_len = (ctx->reseed_counter >= 0 ?
563
0
                 (size_t) ctx->reseed_counter :
564
2
                 good_nonce_len(ctx->entropy_len));
565
566
    /* Initialize with an empty key. */
567
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
568
    psa_status_t status;
569
570
    status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
571
    if (status != PSA_SUCCESS) {
572
        ret = psa_generic_status_to_mbedtls(status);
573
        return status;
574
    }
575
#else
576
2
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
577
2
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
578
0
        return ret;
579
0
    }
580
2
#endif
581
582
    /* Do the initial seeding. */
583
2
    if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
584
2
                                                nonce_len)) != 0) {
585
2
        return ret;
586
2
    }
587
0
    return 0;
588
2
}
589
590
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
591
 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
592
 * implements
593
 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
594
 *                -> working_state_after_reseed
595
 *                if required, then
596
 * CTR_DRBG_Generate(working_state_after_reseed,
597
 *                   requested_number_of_bits, additional_input)
598
 *                -> status, returned_bits, new_working_state
599
 * with inputs
600
 *   ctx contains working_state
601
 *   requested_number_of_bits = 8 * output_len
602
 *   additional[:add_len] = additional_input
603
 * and entropy_input comes from calling ctx->f_entropy
604
 * and with outputs
605
 *   status = SUCCESS (this function does the reseed internally)
606
 *   returned_bits = output[:output_len]
607
 *   ctx contains new_working_state
608
 */
609
int mbedtls_ctr_drbg_random_with_add(void *p_rng,
610
                                     unsigned char *output, size_t output_len,
611
                                     const unsigned char *additional, size_t add_len)
612
0
{
613
0
    int ret = 0;
614
0
    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
615
0
    unsigned char *p = output;
616
0
    struct {
617
0
        unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
618
0
        unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
619
0
    } locals;
620
0
    size_t use_len;
621
622
0
    if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
623
0
        return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
624
0
    }
625
626
0
    if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
627
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
628
0
    }
629
630
0
    memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
631
632
0
    if (ctx->reseed_counter > ctx->reseed_interval ||
633
0
        ctx->prediction_resistance) {
634
0
        if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
635
0
            return ret;
636
0
        }
637
0
        add_len = 0;
638
0
    }
639
640
0
    if (add_len > 0) {
641
0
        if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) {
642
0
            goto exit;
643
0
        }
644
0
        if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
645
0
            goto exit;
646
0
        }
647
0
    }
648
649
0
    while (output_len > 0) {
650
        /*
651
         * Increase counter (treat it as a 128-bit big-endian integer).
652
         */
653
0
        mbedtls_ctr_increment_counter(ctx->counter);
654
655
        /*
656
         * Crypt counter block
657
         */
658
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
659
        psa_status_t status;
660
        size_t tmp_len;
661
662
        status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
663
                                   locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
664
        if (status != PSA_SUCCESS) {
665
            ret = psa_generic_status_to_mbedtls(status);
666
            goto exit;
667
        }
668
#else
669
0
        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
670
0
                                         ctx->counter, locals.tmp)) != 0) {
671
0
            goto exit;
672
0
        }
673
0
#endif
674
675
0
        use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
676
0
            ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
677
        /*
678
         * Copy random block to destination
679
         */
680
0
        memcpy(p, locals.tmp, use_len);
681
0
        p += use_len;
682
0
        output_len -= use_len;
683
0
    }
684
685
0
    if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
686
0
        goto exit;
687
0
    }
688
689
0
    ctx->reseed_counter++;
690
691
0
exit:
692
0
    mbedtls_platform_zeroize(&locals, sizeof(locals));
693
0
    return ret;
694
0
}
695
696
int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
697
                            size_t output_len)
698
0
{
699
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
700
0
    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
701
702
0
#if defined(MBEDTLS_THREADING_C)
703
0
    if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
704
0
        return ret;
705
0
    }
706
0
#endif
707
708
0
    ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0);
709
710
0
#if defined(MBEDTLS_THREADING_C)
711
0
    if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
712
0
        return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
713
0
    }
714
0
#endif
715
716
0
    return ret;
717
0
}
718
719
#if defined(MBEDTLS_FS_IO)
720
int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
721
                                     const char *path)
722
0
{
723
0
    int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
724
0
    FILE *f;
725
0
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
726
727
0
    if ((f = fopen(path, "wb")) == NULL) {
728
0
        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
729
0
    }
730
731
    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
732
0
    mbedtls_setbuf(f, NULL);
733
734
0
    if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
735
0
                                       MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
736
0
        goto exit;
737
0
    }
738
739
0
    if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
740
0
        MBEDTLS_CTR_DRBG_MAX_INPUT) {
741
0
        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
742
0
    } else {
743
0
        ret = 0;
744
0
    }
745
746
0
exit:
747
0
    mbedtls_platform_zeroize(buf, sizeof(buf));
748
749
0
    fclose(f);
750
0
    return ret;
751
0
}
752
753
int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
754
                                      const char *path)
755
0
{
756
0
    int ret = 0;
757
0
    FILE *f = NULL;
758
0
    size_t n;
759
0
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
760
0
    unsigned char c;
761
762
0
    if ((f = fopen(path, "rb")) == NULL) {
763
0
        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
764
0
    }
765
766
    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
767
0
    mbedtls_setbuf(f, NULL);
768
769
0
    n = fread(buf, 1, sizeof(buf), f);
770
0
    if (fread(&c, 1, 1, f) != 0) {
771
0
        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
772
0
        goto exit;
773
0
    }
774
0
    if (n == 0 || ferror(f)) {
775
0
        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
776
0
        goto exit;
777
0
    }
778
0
    fclose(f);
779
0
    f = NULL;
780
781
0
    ret = mbedtls_ctr_drbg_update(ctx, buf, n);
782
783
0
exit:
784
0
    mbedtls_platform_zeroize(buf, sizeof(buf));
785
0
    if (f != NULL) {
786
0
        fclose(f);
787
0
    }
788
0
    if (ret != 0) {
789
0
        return ret;
790
0
    }
791
0
    return mbedtls_ctr_drbg_write_seed_file(ctx, path);
792
0
}
793
#endif /* MBEDTLS_FS_IO */
794
795
#if defined(MBEDTLS_SELF_TEST)
796
797
/* The CTR_DRBG NIST test vectors used here are available at
798
 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
799
 *
800
 * The parameters used to derive the test data are:
801
 *
802
 * [AES-128 use df]
803
 * [PredictionResistance = True/False]
804
 * [EntropyInputLen = 128]
805
 * [NonceLen = 64]
806
 * [PersonalizationStringLen = 128]
807
 * [AdditionalInputLen = 0]
808
 * [ReturnedBitsLen = 512]
809
 *
810
 * [AES-256 use df]
811
 * [PredictionResistance = True/False]
812
 * [EntropyInputLen = 256]
813
 * [NonceLen = 128]
814
 * [PersonalizationStringLen = 256]
815
 * [AdditionalInputLen = 0]
816
 * [ReturnedBitsLen = 512]
817
 *
818
 */
819
820
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
821
static const unsigned char entropy_source_pr[] =
822
{ 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
823
  0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
824
  0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
825
  0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
826
  0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
827
  0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
828
  0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
829
830
static const unsigned char entropy_source_nopr[] =
831
{ 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
832
  0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
833
  0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
834
  0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
835
  0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
836
837
static const unsigned char pers_pr[] =
838
{ 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
839
  0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
840
841
static const unsigned char pers_nopr[] =
842
{ 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
843
  0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
844
845
static const unsigned char result_pr[] =
846
{ 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
847
  0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
848
  0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
849
  0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
850
  0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
851
  0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
852
  0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
853
  0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
854
855
static const unsigned char result_nopr[] =
856
{ 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
857
  0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
858
  0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
859
  0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
860
  0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
861
  0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
862
  0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
863
  0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
864
#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
865
866
static const unsigned char entropy_source_pr[] =
867
{ 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
868
  0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
869
  0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
870
  0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
871
  0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
872
  0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
873
  0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
874
  0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
875
  0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
876
  0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
877
  0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
878
  0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
879
  0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
880
  0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
881
882
static const unsigned char entropy_source_nopr[] =
883
{ 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
884
  0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
885
  0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
886
  0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
887
  0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
888
  0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
889
  0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
890
  0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
891
  0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
892
  0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
893
894
static const unsigned char pers_pr[] =
895
{ 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
896
  0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
897
  0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
898
  0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
899
900
static const unsigned char pers_nopr[] =
901
{ 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
902
  0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
903
  0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
904
  0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
905
906
static const unsigned char result_pr[] =
907
{ 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
908
  0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
909
  0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
910
  0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
911
  0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
912
  0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
913
  0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
914
  0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
915
916
static const unsigned char result_nopr[] =
917
{ 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
918
  0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
919
  0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
920
  0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
921
  0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
922
  0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
923
  0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
924
  0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
925
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
926
927
static size_t test_offset;
928
static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
929
                                      size_t len)
930
0
{
931
0
    const unsigned char *p = data;
932
0
    memcpy(buf, p + test_offset, len);
933
0
    test_offset += len;
934
0
    return 0;
935
0
}
936
937
0
#define CHK(c)    if ((c) != 0)                          \
938
0
    {                                       \
939
0
        if (verbose != 0)                  \
940
0
        mbedtls_printf("failed\n");  \
941
0
        return 1;                        \
942
0
    }
943
944
#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
945
946
/*
947
 * Checkup routine
948
 */
949
int mbedtls_ctr_drbg_self_test(int verbose)
950
0
{
951
0
    mbedtls_ctr_drbg_context ctx;
952
0
    unsigned char buf[sizeof(result_pr)];
953
954
0
    mbedtls_ctr_drbg_init(&ctx);
955
956
    /*
957
     * Based on a NIST CTR_DRBG test vector (PR = True)
958
     */
959
0
    if (verbose != 0) {
960
0
        mbedtls_printf("  CTR_DRBG (PR = TRUE) : ");
961
0
    }
962
963
0
    test_offset = 0;
964
0
    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
965
0
    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
966
0
    CHK(mbedtls_ctr_drbg_seed(&ctx,
967
0
                              ctr_drbg_self_test_entropy,
968
0
                              (void *) entropy_source_pr,
969
0
                              pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
970
0
    mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
971
0
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
972
0
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
973
0
    CHK(memcmp(buf, result_pr, sizeof(result_pr)));
974
975
0
    mbedtls_ctr_drbg_free(&ctx);
976
977
0
    if (verbose != 0) {
978
0
        mbedtls_printf("passed\n");
979
0
    }
980
981
    /*
982
     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
983
     */
984
0
    if (verbose != 0) {
985
0
        mbedtls_printf("  CTR_DRBG (PR = FALSE): ");
986
0
    }
987
988
0
    mbedtls_ctr_drbg_init(&ctx);
989
990
0
    test_offset = 0;
991
0
    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
992
0
    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
993
0
    CHK(mbedtls_ctr_drbg_seed(&ctx,
994
0
                              ctr_drbg_self_test_entropy,
995
0
                              (void *) entropy_source_nopr,
996
0
                              pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
997
0
    CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
998
0
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
999
0
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
1000
0
    CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));
1001
1002
0
    mbedtls_ctr_drbg_free(&ctx);
1003
1004
0
    if (verbose != 0) {
1005
0
        mbedtls_printf("passed\n");
1006
0
    }
1007
1008
0
    if (verbose != 0) {
1009
0
        mbedtls_printf("\n");
1010
0
    }
1011
1012
0
    return 0;
1013
0
}
1014
#endif /* MBEDTLS_SELF_TEST */
1015
1016
#endif /* MBEDTLS_CTR_DRBG_C */