xref: /third_party/mbedtls/library/ctr_drbg.c (revision a8e1175b)
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_AES_C)
30#include "psa_util_internal.h"
31#endif
32
33#include "mbedtls/platform.h"
34
35#if !defined(MBEDTLS_AES_C)
36static 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
55exit:
56    psa_reset_key_attributes(&key_attr);
57    return status;
58}
59
60static 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 */
73void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
74{
75    memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
76#if defined(MBEDTLS_AES_C)
77    mbedtls_aes_init(&ctx->aes_ctx);
78#else
79    ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
80    ctx->psa_ctx.operation = psa_cipher_operation_init();
81#endif
82    /* Indicate that the entropy nonce length is not set explicitly.
83     * See mbedtls_ctr_drbg_set_nonce_len(). */
84    ctx->reseed_counter = -1;
85
86    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
87}
88
89/*
90 *  This function resets CTR_DRBG context to the state immediately
91 *  after initial call of mbedtls_ctr_drbg_init().
92 */
93void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
94{
95    if (ctx == NULL) {
96        return;
97    }
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_AES_C)
106    mbedtls_aes_free(&ctx->aes_ctx);
107#else
108    ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
109#endif
110    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
111    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
112    ctx->reseed_counter = -1;
113}
114
115void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
116                                                int resistance)
117{
118    ctx->prediction_resistance = resistance;
119}
120
121void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
122                                      size_t len)
123{
124    ctx->entropy_len = len;
125}
126
127int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
128                                   size_t len)
129{
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    if (ctx->f_entropy != NULL) {
133        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
134    }
135
136    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
137        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
138    }
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    if (len > INT_MAX) {
144        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
145    }
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    ctx->reseed_counter = (int) len;
152    return 0;
153}
154
155void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
156                                          int interval)
157{
158    ctx->reseed_interval = interval;
159}
160
161static int block_cipher_df(unsigned char *output,
162                           const unsigned char *data, size_t data_len)
163{
164    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
165                      MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
166    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
167    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
168    unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
169    unsigned char *p, *iv;
170    int ret = 0;
171#if defined(MBEDTLS_AES_C)
172    mbedtls_aes_context aes_ctx;
173#else
174    psa_status_t status;
175    size_t tmp_len;
176    mbedtls_ctr_drbg_psa_context psa_ctx;
177
178    psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
179    psa_ctx.operation = psa_cipher_operation_init();
180#endif
181
182    int i, j;
183    size_t buf_len, use_len;
184
185    if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
186        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
187    }
188
189    memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
190           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    p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
200    MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
201    p += 4 + 3;
202    *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
203    memcpy(p, data, data_len);
204    p[data_len] = 0x80;
205
206    buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
207
208    for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
209        key[i] = i;
210    }
211
212#if defined(MBEDTLS_AES_C)
213    mbedtls_aes_init(&aes_ctx);
214
215    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
216                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
217        goto exit;
218    }
219#else
220    status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
221    if (status != PSA_SUCCESS) {
222        ret = psa_generic_status_to_mbedtls(status);
223        goto exit;
224    }
225#endif
226
227    /*
228     * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
229     */
230    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
231        p = buf;
232        memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
233        use_len = buf_len;
234
235        while (use_len > 0) {
236            mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE);
237            p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
238            use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
239                       MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
240
241#if defined(MBEDTLS_AES_C)
242            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
243                                             chain, chain)) != 0) {
244                goto exit;
245            }
246#else
247            status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
248                                       chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
249            if (status != PSA_SUCCESS) {
250                ret = psa_generic_status_to_mbedtls(status);
251                goto exit;
252            }
253#endif
254        }
255
256        memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
257
258        /*
259         * Update IV
260         */
261        buf[3]++;
262    }
263
264    /*
265     * Do final encryption with reduced data
266     */
267#if defined(MBEDTLS_AES_C)
268    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
269                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
270        goto exit;
271    }
272#else
273    ctr_drbg_destroy_psa_contex(&psa_ctx);
274
275    status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
276    if (status != PSA_SUCCESS) {
277        ret = psa_generic_status_to_mbedtls(status);
278        goto exit;
279    }
280#endif
281    iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
282    p = output;
283
284    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
285#if defined(MBEDTLS_AES_C)
286        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
287                                         iv, iv)) != 0) {
288            goto exit;
289        }
290#else
291        status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
292                                   iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
293        if (status != PSA_SUCCESS) {
294            ret = psa_generic_status_to_mbedtls(status);
295            goto exit;
296        }
297#endif
298        memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
299        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
300    }
301exit:
302#if defined(MBEDTLS_AES_C)
303    mbedtls_aes_free(&aes_ctx);
304#else
305    ctr_drbg_destroy_psa_contex(&psa_ctx);
306#endif
307    /*
308     * tidy up the stack
309     */
310    mbedtls_platform_zeroize(buf, sizeof(buf));
311    mbedtls_platform_zeroize(tmp, sizeof(tmp));
312    mbedtls_platform_zeroize(key, sizeof(key));
313    mbedtls_platform_zeroize(chain, sizeof(chain));
314    if (0 != ret) {
315        /*
316         * wipe partial seed from memory
317         */
318        mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
319    }
320
321    return ret;
322}
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 */
332static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
333                                    const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
334{
335    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
336    unsigned char *p = tmp;
337    int j;
338    int ret = 0;
339#if !defined(MBEDTLS_AES_C)
340    psa_status_t status;
341    size_t tmp_len;
342#endif
343
344    memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
345
346    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
347        /*
348         * Increase counter
349         */
350        mbedtls_ctr_increment_counter(ctx->counter);
351
352        /*
353         * Crypt counter block
354         */
355#if defined(MBEDTLS_AES_C)
356        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
357                                         ctx->counter, p)) != 0) {
358            goto exit;
359        }
360#else
361        status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
362                                   p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
363        if (status != PSA_SUCCESS) {
364            ret = psa_generic_status_to_mbedtls(status);
365            goto exit;
366        }
367#endif
368
369        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
370    }
371
372    mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN);
373
374    /*
375     * Update key and counter
376     */
377#if defined(MBEDTLS_AES_C)
378    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
379                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
380        goto exit;
381    }
382#else
383    ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
384
385    status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
386    if (status != PSA_SUCCESS) {
387        ret = psa_generic_status_to_mbedtls(status);
388        goto exit;
389    }
390#endif
391    memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
392           MBEDTLS_CTR_DRBG_BLOCKSIZE);
393
394exit:
395    mbedtls_platform_zeroize(tmp, sizeof(tmp));
396    return ret;
397}
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 */
411int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
412                            const unsigned char *additional,
413                            size_t add_len)
414{
415    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
416    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
417
418    if (add_len == 0) {
419        return 0;
420    }
421
422    if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
423        goto exit;
424    }
425    if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
426        goto exit;
427    }
428
429exit:
430    mbedtls_platform_zeroize(add_input, sizeof(add_input));
431    return ret;
432}
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 */
447static 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{
452    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
453    size_t seedlen = 0;
454    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
455
456    if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
457        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
458    }
459    if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
460        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
461    }
462    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
463        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
464    }
465
466    memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
467
468    /* Gather entropy_len bytes of entropy to seed state. */
469    if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
470        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
471    }
472    seedlen += ctx->entropy_len;
473
474    /* Gather entropy for a nonce if requested. */
475    if (nonce_len != 0) {
476        if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
477            return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
478        }
479        seedlen += nonce_len;
480    }
481
482    /* Add additional data if provided. */
483    if (additional != NULL && len != 0) {
484        memcpy(seed + seedlen, additional, len);
485        seedlen += len;
486    }
487
488    /* Reduce to 384 bits. */
489    if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
490        goto exit;
491    }
492
493    /* Update state. */
494    if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
495        goto exit;
496    }
497    ctx->reseed_counter = 1;
498
499exit:
500    mbedtls_platform_zeroize(seed, sizeof(seed));
501    return ret;
502}
503
504int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
505                            const unsigned char *additional, size_t len)
506{
507    return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
508}
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. */
515static size_t good_nonce_len(size_t entropy_len)
516{
517    if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
518        return 0;
519    } else {
520        return (entropy_len + 1) / 2;
521    }
522}
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 */
535int 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{
541    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
542    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
543    size_t nonce_len;
544
545    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    ctx->f_entropy = f_entropy;
553    ctx->p_entropy = p_entropy;
554
555    if (ctx->entropy_len == 0) {
556        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
557    }
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    nonce_len = (ctx->reseed_counter >= 0 ?
563                 (size_t) ctx->reseed_counter :
564                 good_nonce_len(ctx->entropy_len));
565
566    /* Initialize with an empty key. */
567#if defined(MBEDTLS_AES_C)
568    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
569                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
570        return ret;
571    }
572#else
573    psa_status_t status;
574
575    status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
576    if (status != PSA_SUCCESS) {
577        ret = psa_generic_status_to_mbedtls(status);
578        return status;
579    }
580#endif
581
582    /* Do the initial seeding. */
583    if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
584                                                nonce_len)) != 0) {
585        return ret;
586    }
587    return 0;
588}
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 */
609int 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{
613    int ret = 0;
614    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
615    unsigned char *p = output;
616    struct {
617        unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
618        unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
619    } locals;
620    size_t use_len;
621
622    if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
623        return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
624    }
625
626    if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
627        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
628    }
629
630    memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
631
632    if (ctx->reseed_counter > ctx->reseed_interval ||
633        ctx->prediction_resistance) {
634        if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
635            return ret;
636        }
637        add_len = 0;
638    }
639
640    if (add_len > 0) {
641        if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) {
642            goto exit;
643        }
644        if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
645            goto exit;
646        }
647    }
648
649    while (output_len > 0) {
650        /*
651         * Increase counter (treat it as a 128-bit big-endian integer).
652         */
653        mbedtls_ctr_increment_counter(ctx->counter);
654
655        /*
656         * Crypt counter block
657         */
658#if defined(MBEDTLS_AES_C)
659        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
660                                         ctx->counter, locals.tmp)) != 0) {
661            goto exit;
662        }
663#else
664        psa_status_t status;
665        size_t tmp_len;
666
667        status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
668                                   locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
669        if (status != PSA_SUCCESS) {
670            ret = psa_generic_status_to_mbedtls(status);
671            goto exit;
672        }
673#endif
674
675        use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
676            ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
677        /*
678         * Copy random block to destination
679         */
680        memcpy(p, locals.tmp, use_len);
681        p += use_len;
682        output_len -= use_len;
683    }
684
685    if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
686        goto exit;
687    }
688
689    ctx->reseed_counter++;
690
691exit:
692    mbedtls_platform_zeroize(&locals, sizeof(locals));
693    return ret;
694}
695
696int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
697                            size_t output_len)
698{
699    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
700    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    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    return ret;
717}
718
719#if defined(MBEDTLS_FS_IO)
720int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
721                                     const char *path)
722{
723    int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
724    FILE *f;
725    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
726
727    if ((f = fopen(path, "wb")) == NULL) {
728        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
729    }
730
731    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
732    mbedtls_setbuf(f, NULL);
733
734    if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
735                                       MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
736        goto exit;
737    }
738
739    if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
740        MBEDTLS_CTR_DRBG_MAX_INPUT) {
741        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
742    } else {
743        ret = 0;
744    }
745
746exit:
747    mbedtls_platform_zeroize(buf, sizeof(buf));
748
749    fclose(f);
750    return ret;
751}
752
753int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
754                                      const char *path)
755{
756    int ret = 0;
757    FILE *f = NULL;
758    size_t n;
759    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
760    unsigned char c;
761
762    if ((f = fopen(path, "rb")) == NULL) {
763        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
764    }
765
766    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
767    mbedtls_setbuf(f, NULL);
768
769    n = fread(buf, 1, sizeof(buf), f);
770    if (fread(&c, 1, 1, f) != 0) {
771        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
772        goto exit;
773    }
774    if (n == 0 || ferror(f)) {
775        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
776        goto exit;
777    }
778    fclose(f);
779    f = NULL;
780
781    ret = mbedtls_ctr_drbg_update(ctx, buf, n);
782
783exit:
784    mbedtls_platform_zeroize(buf, sizeof(buf));
785    if (f != NULL) {
786        fclose(f);
787    }
788    if (ret != 0) {
789        return ret;
790    }
791    return mbedtls_ctr_drbg_write_seed_file(ctx, path);
792}
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)
821static 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
830static 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
837static const unsigned char pers_pr[] =
838{ 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
839  0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
840
841static const unsigned char pers_nopr[] =
842{ 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
843  0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
844
845static 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
855static 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
866static 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
882static 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
894static 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
900static 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
906static 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
916static 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
927static size_t test_offset;
928static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
929                                      size_t len)
930{
931    const unsigned char *p = data;
932    memcpy(buf, p + test_offset, len);
933    test_offset += len;
934    return 0;
935}
936
937#define CHK(c)    if ((c) != 0)                          \
938    {                                       \
939        if (verbose != 0)                  \
940        mbedtls_printf("failed\n");  \
941        return 1;                        \
942    }
943
944#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
945
946/*
947 * Checkup routine
948 */
949int mbedtls_ctr_drbg_self_test(int verbose)
950{
951    mbedtls_ctr_drbg_context ctx;
952    unsigned char buf[sizeof(result_pr)];
953
954    mbedtls_ctr_drbg_init(&ctx);
955
956    /*
957     * Based on a NIST CTR_DRBG test vector (PR = True)
958     */
959    if (verbose != 0) {
960        mbedtls_printf("  CTR_DRBG (PR = TRUE) : ");
961    }
962
963    test_offset = 0;
964    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
965    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
966    CHK(mbedtls_ctr_drbg_seed(&ctx,
967                              ctr_drbg_self_test_entropy,
968                              (void *) entropy_source_pr,
969                              pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
970    mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
971    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
972    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
973    CHK(memcmp(buf, result_pr, sizeof(result_pr)));
974
975    mbedtls_ctr_drbg_free(&ctx);
976
977    if (verbose != 0) {
978        mbedtls_printf("passed\n");
979    }
980
981    /*
982     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
983     */
984    if (verbose != 0) {
985        mbedtls_printf("  CTR_DRBG (PR = FALSE): ");
986    }
987
988    mbedtls_ctr_drbg_init(&ctx);
989
990    test_offset = 0;
991    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
992    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
993    CHK(mbedtls_ctr_drbg_seed(&ctx,
994                              ctr_drbg_self_test_entropy,
995                              (void *) entropy_source_nopr,
996                              pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
997    CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
998    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
999    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
1000    CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));
1001
1002    mbedtls_ctr_drbg_free(&ctx);
1003
1004    if (verbose != 0) {
1005        mbedtls_printf("passed\n");
1006    }
1007
1008    if (verbose != 0) {
1009        mbedtls_printf("\n");
1010    }
1011
1012    return 0;
1013}
1014#endif /* MBEDTLS_SELF_TEST */
1015
1016#endif /* MBEDTLS_CTR_DRBG_C */
1017