• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context * ctx)33 void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
34 {
35     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     ctx->reseed_counter = -1;
39 
40     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
41 }
42 
43 /*
44  *  This function resets CTR_DRBG context to the state immediately
45  *  after initial call of mbedtls_ctr_drbg_init().
46  */
mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context * ctx)47 void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
48 {
49     if (ctx == NULL) {
50         return;
51     }
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     mbedtls_aes_free(&ctx->aes_ctx);
60     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
61     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
62     ctx->reseed_counter = -1;
63 }
64 
mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context * ctx,int resistance)65 void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
66                                                 int resistance)
67 {
68     ctx->prediction_resistance = resistance;
69 }
70 
mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context * ctx,size_t len)71 void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
72                                       size_t len)
73 {
74     ctx->entropy_len = len;
75 }
76 
mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context * ctx,size_t len)77 int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
78                                    size_t len)
79 {
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     if (ctx->f_entropy != NULL) {
83         return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
84     }
85 
86     if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
87         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
88     }
89 #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     if (len > INT_MAX) {
94         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
95     }
96 #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     ctx->reseed_counter = (int) len;
103     return 0;
104 }
105 
mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context * ctx,int interval)106 void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
107                                           int interval)
108 {
109     ctx->reseed_interval = interval;
110 }
111 
block_cipher_df(unsigned char * output,const unsigned char * data,size_t data_len)112 static int block_cipher_df(unsigned char *output,
113                            const unsigned char *data, size_t data_len)
114 {
115     unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
116                       MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
117     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
118     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
119     unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
120     unsigned char *p, *iv;
121     mbedtls_aes_context aes_ctx;
122     int ret = 0;
123 
124     int i, j;
125     size_t buf_len, use_len;
126 
127     if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
128         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
129     }
130 
131     memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
132            MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
133     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     p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
143     MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
144     p += 4 + 3;
145     *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
146     memcpy(p, data, data_len);
147     p[data_len] = 0x80;
148 
149     buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
150 
151     for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
152         key[i] = i;
153     }
154 
155     if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
156                                       MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
157         goto exit;
158     }
159 
160     /*
161      * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
162      */
163     for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
164         p = buf;
165         memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
166         use_len = buf_len;
167 
168         while (use_len > 0) {
169             for (i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++) {
170                 chain[i] ^= p[i];
171             }
172             p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
173             use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
174                        MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
175 
176             if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
177                                              chain, chain)) != 0) {
178                 goto exit;
179             }
180         }
181 
182         memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
183 
184         /*
185          * Update IV
186          */
187         buf[3]++;
188     }
189 
190     /*
191      * Do final encryption with reduced data
192      */
193     if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
194                                       MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
195         goto exit;
196     }
197     iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
198     p = output;
199 
200     for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
201         if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
202                                          iv, iv)) != 0) {
203             goto exit;
204         }
205         memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
206         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
207     }
208 exit:
209     mbedtls_aes_free(&aes_ctx);
210     /*
211      * tidy up the stack
212      */
213     mbedtls_platform_zeroize(buf, sizeof(buf));
214     mbedtls_platform_zeroize(tmp, sizeof(tmp));
215     mbedtls_platform_zeroize(key, sizeof(key));
216     mbedtls_platform_zeroize(chain, sizeof(chain));
217     if (0 != ret) {
218         /*
219          * wipe partial seed from memory
220          */
221         mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
222     }
223 
224     return ret;
225 }
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  */
ctr_drbg_update_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])235 static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
236                                     const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
237 {
238     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
239     unsigned char *p = tmp;
240     int i, j;
241     int ret = 0;
242 
243     memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
244 
245     for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
246         /*
247          * Increase counter
248          */
249         for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
250             if (++ctx->counter[i - 1] != 0) {
251                 break;
252             }
253         }
254 
255         /*
256          * Crypt counter block
257          */
258         if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
259                                          ctx->counter, p)) != 0) {
260             goto exit;
261         }
262 
263         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
264     }
265 
266     for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) {
267         tmp[i] ^= data[i];
268     }
269 
270     /*
271      * Update key and counter
272      */
273     if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
274                                       MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
275         goto exit;
276     }
277     memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
278            MBEDTLS_CTR_DRBG_BLOCKSIZE);
279 
280 exit:
281     mbedtls_platform_zeroize(tmp, sizeof(tmp));
282     return ret;
283 }
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  */
mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)297 int mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context *ctx,
298                                 const unsigned char *additional,
299                                 size_t add_len)
300 {
301     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
302     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
303 
304     if (add_len == 0) {
305         return 0;
306     }
307 
308     if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
309         goto exit;
310     }
311     if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
312         goto exit;
313     }
314 
315 exit:
316     mbedtls_platform_zeroize(add_input, sizeof(add_input));
317     return ret;
318 }
319 
320 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)321 void mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
322                              const unsigned char *additional,
323                              size_t add_len)
324 {
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     if (add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
328         add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
329     }
330     (void) mbedtls_ctr_drbg_update_ret(ctx, additional, add_len);
331 }
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  */
mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len,size_t nonce_len)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 {
352     unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
353     size_t seedlen = 0;
354     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
355 
356     if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
357         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
358     }
359     if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
360         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
361     }
362     if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
363         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
364     }
365 
366     memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
367 
368     /* Gather entropy_len bytes of entropy to seed state. */
369     if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
370         return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
371     }
372     seedlen += ctx->entropy_len;
373 
374     /* Gather entropy for a nonce if requested. */
375     if (nonce_len != 0) {
376         if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
377             return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
378         }
379         seedlen += nonce_len;
380     }
381 
382     /* Add additional data if provided. */
383     if (additional != NULL && len != 0) {
384         memcpy(seed + seedlen, additional, len);
385         seedlen += len;
386     }
387 
388     /* Reduce to 384 bits. */
389     if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
390         goto exit;
391     }
392 
393     /* Update state. */
394     if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
395         goto exit;
396     }
397     ctx->reseed_counter = 1;
398 
399 exit:
400     mbedtls_platform_zeroize(seed, sizeof(seed));
401     return ret;
402 }
403 
mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len)404 int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
405                             const unsigned char *additional, size_t len)
406 {
407     return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
408 }
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. */
good_nonce_len(size_t entropy_len)415 static size_t good_nonce_len(size_t entropy_len)
416 {
417     if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
418         return 0;
419     } else {
420         return (entropy_len + 1) / 2;
421     }
422 }
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  */
mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context * ctx,int (* f_entropy)(void *,unsigned char *,size_t),void * p_entropy,const unsigned char * custom,size_t len)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 {
441     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
442     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
443     size_t nonce_len;
444 
445     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     mbedtls_aes_init(&ctx->aes_ctx);
453 
454     ctx->f_entropy = f_entropy;
455     ctx->p_entropy = p_entropy;
456 
457     if (ctx->entropy_len == 0) {
458         ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
459     }
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     nonce_len = (ctx->reseed_counter >= 0 ?
465                  (size_t) ctx->reseed_counter :
466                  good_nonce_len(ctx->entropy_len));
467 
468     /* Initialize with an empty key. */
469     if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
470                                       MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
471         return ret;
472     }
473 
474     /* Do the initial seeding. */
475     if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
476                                                 nonce_len)) != 0) {
477         return ret;
478     }
479     return 0;
480 }
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  */
mbedtls_ctr_drbg_random_with_add(void * p_rng,unsigned char * output,size_t output_len,const unsigned char * additional,size_t add_len)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 {
505     int ret = 0;
506     mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
507     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
508     unsigned char *p = output;
509     unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
510     int i;
511     size_t use_len;
512 
513     if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
514         return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
515     }
516 
517     if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
518         return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
519     }
520 
521     memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
522 
523     if (ctx->reseed_counter > ctx->reseed_interval ||
524         ctx->prediction_resistance) {
525         if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
526             return ret;
527         }
528         add_len = 0;
529     }
530 
531     if (add_len > 0) {
532         if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
533             goto exit;
534         }
535         if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
536             goto exit;
537         }
538     }
539 
540     while (output_len > 0) {
541         /*
542          * Increase counter
543          */
544         for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
545             if (++ctx->counter[i - 1] != 0) {
546                 break;
547             }
548         }
549 
550         /*
551          * Crypt counter block
552          */
553         if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
554                                          ctx->counter, tmp)) != 0) {
555             goto exit;
556         }
557 
558         use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
559             ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
560         /*
561          * Copy random block to destination
562          */
563         memcpy(p, tmp, use_len);
564         p += use_len;
565         output_len -= use_len;
566     }
567 
568     if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
569         goto exit;
570     }
571 
572     ctx->reseed_counter++;
573 
574 exit:
575     mbedtls_platform_zeroize(add_input, sizeof(add_input));
576     mbedtls_platform_zeroize(tmp, sizeof(tmp));
577     return ret;
578 }
579 
mbedtls_ctr_drbg_random(void * p_rng,unsigned char * output,size_t output_len)580 int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
581                             size_t output_len)
582 {
583     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
584     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     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     return ret;
601 }
602 
603 #if defined(MBEDTLS_FS_IO)
mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)604 int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
605                                      const char *path)
606 {
607     int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
608     FILE *f;
609     unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
610 
611     if ((f = fopen(path, "wb")) == NULL) {
612         return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
613     }
614 
615     if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
616                                        MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
617         goto exit;
618     }
619 
620     if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
621         MBEDTLS_CTR_DRBG_MAX_INPUT) {
622         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
623     } else {
624         ret = 0;
625     }
626 
627 exit:
628     mbedtls_platform_zeroize(buf, sizeof(buf));
629 
630     fclose(f);
631     return ret;
632 }
633 
mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)634 int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
635                                       const char *path)
636 {
637     int ret = 0;
638     FILE *f = NULL;
639     size_t n;
640     unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
641     unsigned char c;
642 
643     if ((f = fopen(path, "rb")) == NULL) {
644         return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
645     }
646 
647     n = fread(buf, 1, sizeof(buf), f);
648     if (fread(&c, 1, 1, f) != 0) {
649         ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
650         goto exit;
651     }
652     if (n == 0 || ferror(f)) {
653         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
654         goto exit;
655     }
656     fclose(f);
657     f = NULL;
658 
659     ret = mbedtls_ctr_drbg_update_ret(ctx, buf, n);
660 
661 exit:
662     mbedtls_platform_zeroize(buf, sizeof(buf));
663     if (f != NULL) {
664         fclose(f);
665     }
666     if (ret != 0) {
667         return ret;
668     }
669     return mbedtls_ctr_drbg_write_seed_file(ctx, path);
670 }
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;
ctr_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)806 static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
807                                       size_t len)
808 {
809     const unsigned char *p = data;
810     memcpy(buf, p + test_offset, len);
811     test_offset += len;
812     return 0;
813 }
814 
815 #define CHK(c)    if ((c) != 0)                          \
816     {                                       \
817         if (verbose != 0)                  \
818         mbedtls_printf("failed\n");  \
819         return 1;                        \
820     }
821 
822 #define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
823 
824 /*
825  * Checkup routine
826  */
mbedtls_ctr_drbg_self_test(int verbose)827 int mbedtls_ctr_drbg_self_test(int verbose)
828 {
829     mbedtls_ctr_drbg_context ctx;
830     unsigned char buf[sizeof(result_pr)];
831 
832     mbedtls_ctr_drbg_init(&ctx);
833 
834     /*
835      * Based on a NIST CTR_DRBG test vector (PR = True)
836      */
837     if (verbose != 0) {
838         mbedtls_printf("  CTR_DRBG (PR = TRUE) : ");
839     }
840 
841     test_offset = 0;
842     mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
843     mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
844     CHK(mbedtls_ctr_drbg_seed(&ctx,
845                               ctr_drbg_self_test_entropy,
846                               (void *) entropy_source_pr,
847                               pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
848     mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
849     CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
850     CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
851     CHK(memcmp(buf, result_pr, sizeof(result_pr)));
852 
853     mbedtls_ctr_drbg_free(&ctx);
854 
855     if (verbose != 0) {
856         mbedtls_printf("passed\n");
857     }
858 
859     /*
860      * Based on a NIST CTR_DRBG test vector (PR = FALSE)
861      */
862     if (verbose != 0) {
863         mbedtls_printf("  CTR_DRBG (PR = FALSE): ");
864     }
865 
866     mbedtls_ctr_drbg_init(&ctx);
867 
868     test_offset = 0;
869     mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
870     mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
871     CHK(mbedtls_ctr_drbg_seed(&ctx,
872                               ctr_drbg_self_test_entropy,
873                               (void *) entropy_source_nopr,
874                               pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
875     CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
876     CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
877     CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
878     CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));
879 
880     mbedtls_ctr_drbg_free(&ctx);
881 
882     if (verbose != 0) {
883         mbedtls_printf("passed\n");
884     }
885 
886     if (verbose != 0) {
887         mbedtls_printf("\n");
888     }
889 
890     return 0;
891 }
892 #endif /* MBEDTLS_SELF_TEST */
893 
894 #endif /* MBEDTLS_CTR_DRBG_C */
895