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