Coverage Report

Created: 2025-07-01 06:54

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