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