Coverage Report

Created: 2024-11-21 07:03

/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
10
{
75
10
    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
10
    mbedtls_aes_init(&ctx->aes_ctx);
81
10
#endif
82
    /* Indicate that the entropy nonce length is not set explicitly.
83
     * See mbedtls_ctr_drbg_set_nonce_len(). */
84
10
    ctx->reseed_counter = -1;
85
86
10
    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
87
10
}
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
0
{
95
0
    if (ctx == NULL) {
96
0
        return;
97
0
    }
98
99
#if defined(MBEDTLS_THREADING_C)
100
    /* The mutex is initialized iff f_entropy is set. */
101
    if (ctx->f_entropy != NULL) {
102
        mbedtls_mutex_free(&ctx->mutex);
103
    }
104
#endif
105
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
106
    ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
107
#else
108
0
    mbedtls_aes_free(&ctx->aes_ctx);
109
0
#endif
110
0
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
111
0
    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
112
0
    ctx->reseed_counter = -1;
113
0
}
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
10
{
164
10
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
165
10
                      MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
166
10
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
167
10
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
168
10
    unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
169
10
    unsigned char *p, *iv;
170
10
    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
10
    mbedtls_aes_context aes_ctx;
180
10
#endif
181
182
10
    int i, j;
183
10
    size_t buf_len, use_len;
184
185
10
    if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
186
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
187
0
    }
188
189
10
    memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
190
10
           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
10
    p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
200
10
    MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
201
10
    p += 4 + 3;
202
10
    *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
203
10
    memcpy(p, data, data_len);
204
10
    p[data_len] = 0x80;
205
206
10
    buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
207
208
330
    for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
209
320
        key[i] = i;
210
320
    }
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
10
    mbedtls_aes_init(&aes_ctx);
220
221
10
    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
222
10
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
223
0
        goto exit;
224
0
    }
225
10
#endif
226
227
    /*
228
     * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
229
     */
230
40
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
231
30
        p = buf;
232
30
        memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
233
30
        use_len = buf_len;
234
235
180
        while (use_len > 0) {
236
150
            mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE);
237
150
            p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
238
150
            use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
239
120
                       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
150
            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
250
150
                                             chain, chain)) != 0) {
251
0
                goto exit;
252
0
            }
253
150
#endif
254
150
        }
255
256
30
        memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
257
258
        /*
259
         * Update IV
260
         */
261
30
        buf[3]++;
262
30
    }
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
10
    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
277
10
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
278
0
        goto exit;
279
0
    }
280
10
#endif
281
10
    iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
282
10
    p = output;
283
284
40
    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
30
        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
294
30
                                         iv, iv)) != 0) {
295
0
            goto exit;
296
0
        }
297
30
#endif
298
30
        memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
299
30
        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
300
30
    }
301
10
exit:
302
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
303
    ctr_drbg_destroy_psa_contex(&psa_ctx);
304
#else
305
10
    mbedtls_aes_free(&aes_ctx);
306
10
#endif
307
    /*
308
     * tidy up the stack
309
     */
310
10
    mbedtls_platform_zeroize(buf, sizeof(buf));
311
10
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
312
10
    mbedtls_platform_zeroize(key, sizeof(key));
313
10
    mbedtls_platform_zeroize(chain, sizeof(chain));
314
10
    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
10
    return ret;
322
10
}
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
10
{
335
10
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
336
10
    unsigned char *p = tmp;
337
10
    int j;
338
10
    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
10
    memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
345
346
40
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
347
        /*
348
         * Increase counter
349
         */
350
30
        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
30
        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
364
30
                                         ctx->counter, p)) != 0) {
365
0
            goto exit;
366
0
        }
367
30
#endif
368
369
30
        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
370
30
    }
371
372
10
    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
10
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
387
10
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
388
0
        goto exit;
389
0
    }
390
10
#endif
391
10
    memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
392
10
           MBEDTLS_CTR_DRBG_BLOCKSIZE);
393
394
10
exit:
395
10
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
396
10
    return ret;
397
10
}
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
10
{
452
10
    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
453
10
    size_t seedlen = 0;
454
10
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
455
456
10
    if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
457
0
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
458
0
    }
459
10
    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
10
    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
10
    memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
467
468
    /* Gather entropy_len bytes of entropy to seed state. */
469
10
    if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
470
0
        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
471
0
    }
472
10
    seedlen += ctx->entropy_len;
473
474
    /* Gather entropy for a nonce if requested. */
475
10
    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
10
    if (additional != NULL && len != 0) {
484
10
        memcpy(seed + seedlen, additional, len);
485
10
        seedlen += len;
486
10
    }
487
488
    /* Reduce to 384 bits. */
489
10
    if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
490
0
        goto exit;
491
0
    }
492
493
    /* Update state. */
494
10
    if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
495
0
        goto exit;
496
0
    }
497
10
    ctx->reseed_counter = 1;
498
499
10
exit:
500
10
    mbedtls_platform_zeroize(seed, sizeof(seed));
501
10
    return ret;
502
10
}
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
10
{
517
10
    if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
518
10
        return 0;
519
10
    } else {
520
0
        return (entropy_len + 1) / 2;
521
0
    }
522
10
}
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
10
{
541
10
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
542
10
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
543
10
    size_t nonce_len;
544
545
10
    memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE);
546
547
    /* The mutex is initialized iff f_entropy is set. */
548
#if defined(MBEDTLS_THREADING_C)
549
    mbedtls_mutex_init(&ctx->mutex);
550
#endif
551
552
10
    ctx->f_entropy = f_entropy;
553
10
    ctx->p_entropy = p_entropy;
554
555
10
    if (ctx->entropy_len == 0) {
556
10
        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
557
10
    }
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
10
    nonce_len = (ctx->reseed_counter >= 0 ?
563
0
                 (size_t) ctx->reseed_counter :
564
10
                 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
10
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
577
10
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
578
0
        return ret;
579
0
    }
580
10
#endif
581
582
    /* Do the initial seeding. */
583
10
    if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
584
10
                                                nonce_len)) != 0) {
585
0
        return ret;
586
0
    }
587
10
    return 0;
588
10
}
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
#if defined(MBEDTLS_THREADING_C)
703
    if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
704
        return ret;
705
    }
706
#endif
707
708
0
    ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0);
709
710
#if defined(MBEDTLS_THREADING_C)
711
    if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
712
        return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
713
    }
714
#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 */