xref: /optee_os/lib/libmbedtls/mbedtls/library/ctr_drbg.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
1 // SPDX-License-Identifier: Apache-2.0
2 /*
3  *  CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
4  *
5  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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  *  This file is part of mbed TLS (https://tls.mbed.org)
20  */
21 /*
22  *  The NIST SP 800-90 DRBGs are described in the following publication.
23  *
24  *  http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
25  */
26 
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
29 #else
30 #include MBEDTLS_CONFIG_FILE
31 #endif
32 
33 #if defined(MBEDTLS_CTR_DRBG_C)
34 
35 #include "mbedtls/ctr_drbg.h"
36 #include "mbedtls/platform_util.h"
37 #include "mbedtls/error.h"
38 
39 #include <string.h>
40 
41 #if defined(MBEDTLS_FS_IO)
42 #include <stdio.h>
43 #endif
44 
45 #if defined(MBEDTLS_SELF_TEST)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
48 #else
49 #include <stdio.h>
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_PLATFORM_C */
52 #endif /* MBEDTLS_SELF_TEST */
53 
54 /*
55  * CTR_DRBG context initialization
56  */
57 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
58 {
59     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
60     /* Indicate that the entropy nonce length is not set explicitly.
61      * See mbedtls_ctr_drbg_set_nonce_len(). */
62     ctx->reseed_counter = -1;
63 
64 #if defined(MBEDTLS_THREADING_C)
65     mbedtls_mutex_init( &ctx->mutex );
66 #endif
67 }
68 
69 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
70 {
71     if( ctx == NULL )
72         return;
73 
74 #if defined(MBEDTLS_THREADING_C)
75     mbedtls_mutex_free( &ctx->mutex );
76 #endif
77     mbedtls_aes_free( &ctx->aes_ctx );
78     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
79 }
80 
81 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
82                                                  int resistance )
83 {
84     ctx->prediction_resistance = resistance;
85 }
86 
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 
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 
119 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
120                                            int interval )
121 {
122     ctx->reseed_interval = interval;
123 }
124 
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     *p++ = ( data_len >> 24 ) & 0xff;
156     *p++ = ( data_len >> 16 ) & 0xff;
157     *p++ = ( data_len >> 8  ) & 0xff;
158     *p++ = ( data_len       ) & 0xff;
159     p += 3;
160     *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
161     memcpy( p, data, data_len );
162     p[data_len] = 0x80;
163 
164     buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
165 
166     for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
167         key[i] = i;
168 
169     if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
170                                         MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
171     {
172         goto exit;
173     }
174 
175     /*
176      * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
177      */
178     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
179     {
180         p = buf;
181         memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
182         use_len = buf_len;
183 
184         while( use_len > 0 )
185         {
186             for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
187                 chain[i] ^= p[i];
188             p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
189             use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
190                        MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
191 
192             if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
193                                                chain, chain ) ) != 0 )
194             {
195                 goto exit;
196             }
197         }
198 
199         memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
200 
201         /*
202          * Update IV
203          */
204         buf[3]++;
205     }
206 
207     /*
208      * Do final encryption with reduced data
209      */
210     if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
211                                         MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
212     {
213         goto exit;
214     }
215     iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
216     p = output;
217 
218     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
219     {
220         if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
221                                            iv, iv ) ) != 0 )
222         {
223             goto exit;
224         }
225         memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
226         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
227     }
228 exit:
229     mbedtls_aes_free( &aes_ctx );
230     /*
231     * tidy up the stack
232     */
233     mbedtls_platform_zeroize( buf, sizeof( buf ) );
234     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
235     mbedtls_platform_zeroize( key, sizeof( key ) );
236     mbedtls_platform_zeroize( chain, sizeof( chain ) );
237     if( 0 != ret )
238     {
239         /*
240         * wipe partial seed from memory
241         */
242         mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
243     }
244 
245     return( ret );
246 }
247 
248 /* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
249  * ctr_drbg_update_internal(ctx, provided_data)
250  * implements
251  * CTR_DRBG_Update(provided_data, Key, V)
252  * with inputs and outputs
253  *   ctx->aes_ctx = Key
254  *   ctx->counter = V
255  */
256 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
257                           const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
258 {
259     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
260     unsigned char *p = tmp;
261     int i, j;
262     int ret = 0;
263 
264     memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
265 
266     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
267     {
268         /*
269          * Increase counter
270          */
271         for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
272             if( ++ctx->counter[i - 1] != 0 )
273                 break;
274 
275         /*
276          * Crypt counter block
277          */
278         if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
279                                            ctx->counter, p ) ) != 0 )
280         {
281             goto exit;
282         }
283 
284         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
285     }
286 
287     for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
288         tmp[i] ^= data[i];
289 
290     /*
291      * Update key and counter
292      */
293     if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
294                                         MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
295     {
296         goto exit;
297     }
298     memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
299             MBEDTLS_CTR_DRBG_BLOCKSIZE );
300 
301 exit:
302     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
303     return( ret );
304 }
305 
306 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
307  * mbedtls_ctr_drbg_update(ctx, additional, add_len)
308  * implements
309  * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
310  *                      security_strength) -> initial_working_state
311  * with inputs
312  *   ctx->counter = all-bits-0
313  *   ctx->aes_ctx = context from all-bits-0 key
314  *   additional[:add_len] = entropy_input || nonce || personalization_string
315  * and with outputs
316  *   ctx = initial_working_state
317  */
318 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
319                                  const unsigned char *additional,
320                                  size_t add_len )
321 {
322     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
323     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
324 
325     if( add_len == 0 )
326         return( 0 );
327 
328     if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
329         goto exit;
330     if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
331         goto exit;
332 
333 exit:
334     mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
335     return( ret );
336 }
337 
338 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
339 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
340                               const unsigned char *additional,
341                               size_t add_len )
342 {
343     /* MAX_INPUT would be more logical here, but we have to match
344      * block_cipher_df()'s limits since we can't propagate errors */
345     if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
346         add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
347     (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
348 }
349 #endif /* MBEDTLS_DEPRECATED_REMOVED */
350 
351 /* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
352  * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
353  * implements
354  * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
355  *                -> new_working_state
356  * with inputs
357  *   ctx contains working_state
358  *   additional[:len] = additional_input
359  * and entropy_input comes from calling ctx->f_entropy
360  *                              for (ctx->entropy_len + nonce_len) bytes
361  * and with output
362  *   ctx contains new_working_state
363  */
364 static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
365                                              const unsigned char *additional,
366                                              size_t len,
367                                              size_t nonce_len )
368 {
369     unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
370     size_t seedlen = 0;
371     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
372 
373     if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
374         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
375     if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
376         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
377     if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len )
378         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
379 
380     memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
381 
382     /* Gather entropy_len bytes of entropy to seed state. */
383     if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
384     {
385         return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
386     }
387     seedlen += ctx->entropy_len;
388 
389     /* Gather entropy for a nonce if requested. */
390     if( nonce_len != 0 )
391     {
392         if( 0 != ctx->f_entropy( ctx->p_entropy, seed, nonce_len ) )
393         {
394             return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
395         }
396         seedlen += nonce_len;
397     }
398 
399     /* Add additional data if provided. */
400     if( additional != NULL && len != 0 )
401     {
402         memcpy( seed + seedlen, additional, len );
403         seedlen += len;
404     }
405 
406     /* Reduce to 384 bits. */
407     if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
408         goto exit;
409 
410     /* Update state. */
411     if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
412         goto exit;
413     ctx->reseed_counter = 1;
414 
415 exit:
416     mbedtls_platform_zeroize( seed, sizeof( seed ) );
417     return( ret );
418 }
419 
420 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
421                              const unsigned char *additional, size_t len )
422 {
423     return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
424 }
425 
426 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
427  * is sufficient to achieve the maximum security strength given the key
428  * size and entropy length. If there is enough entropy in the initial
429  * call to the entropy function to serve as both the entropy input and
430  * the nonce, don't make a second call to get a nonce. */
431 static size_t good_nonce_len( size_t entropy_len )
432 {
433     if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
434         return( 0 );
435     else
436         return( ( entropy_len + 1 ) / 2 );
437 }
438 
439 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
440  * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
441  * implements
442  * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
443  *                      security_strength) -> initial_working_state
444  * with inputs
445  *   custom[:len] = nonce || personalization_string
446  * where entropy_input comes from f_entropy for ctx->entropy_len bytes
447  * and with outputs
448  *   ctx = initial_working_state
449  */
450 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
451                            int (*f_entropy)(void *, unsigned char *, size_t),
452                            void *p_entropy,
453                            const unsigned char *custom,
454                            size_t len )
455 {
456     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
457     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
458     size_t nonce_len;
459 
460     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
461 
462     mbedtls_aes_init( &ctx->aes_ctx );
463 
464     ctx->f_entropy = f_entropy;
465     ctx->p_entropy = p_entropy;
466 
467     if( ctx->entropy_len == 0 )
468         ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
469     /* ctx->reseed_counter contains the desired amount of entropy to
470      * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
471      * If it's -1, indicating that the entropy nonce length was not set
472      * explicitly, use a sufficiently large nonce for security. */
473     nonce_len = ( ctx->reseed_counter >= 0 ?
474                   (size_t) ctx->reseed_counter :
475                   good_nonce_len( ctx->entropy_len ) );
476 
477     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
478 
479     /* Initialize with an empty key. */
480     if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
481                                         MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
482     {
483         return( ret );
484     }
485 
486     /* Do the initial seeding. */
487     if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
488                                                   nonce_len ) ) != 0 )
489     {
490         return( ret );
491     }
492     return( 0 );
493 }
494 
495 /* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
496  * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
497  * implements
498  * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
499  *                -> working_state_after_reseed
500  *                if required, then
501  * CTR_DRBG_Generate(working_state_after_reseed,
502  *                   requested_number_of_bits, additional_input)
503  *                -> status, returned_bits, new_working_state
504  * with inputs
505  *   ctx contains working_state
506  *   requested_number_of_bits = 8 * output_len
507  *   additional[:add_len] = additional_input
508  * and entropy_input comes from calling ctx->f_entropy
509  * and with outputs
510  *   status = SUCCESS (this function does the reseed internally)
511  *   returned_bits = output[:output_len]
512  *   ctx contains new_working_state
513  */
514 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
515                               unsigned char *output, size_t output_len,
516                               const unsigned char *additional, size_t add_len )
517 {
518     int ret = 0;
519     mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
520     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
521     unsigned char *p = output;
522     unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
523     int i;
524     size_t use_len;
525 
526     if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
527         return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
528 
529     if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
530         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
531 
532     memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
533 
534     if( ctx->reseed_counter > ctx->reseed_interval ||
535         ctx->prediction_resistance )
536     {
537         if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
538         {
539             return( ret );
540         }
541         add_len = 0;
542     }
543 
544     if( add_len > 0 )
545     {
546         if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
547             goto exit;
548         if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
549             goto exit;
550     }
551 
552     while( output_len > 0 )
553     {
554         /*
555          * Increase counter
556          */
557         for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
558             if( ++ctx->counter[i - 1] != 0 )
559                 break;
560 
561         /*
562          * Crypt counter block
563          */
564         if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
565                                            ctx->counter, tmp ) ) != 0 )
566         {
567             goto exit;
568         }
569 
570         use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
571             ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
572         /*
573          * Copy random block to destination
574          */
575         memcpy( p, tmp, use_len );
576         p += use_len;
577         output_len -= use_len;
578     }
579 
580     if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
581         goto exit;
582 
583     ctx->reseed_counter++;
584 
585 exit:
586     mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
587     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
588     return( ret );
589 }
590 
591 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
592                              size_t output_len )
593 {
594     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
595     mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
596 
597 #if defined(MBEDTLS_THREADING_C)
598     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
599         return( ret );
600 #endif
601 
602     ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
603 
604 #if defined(MBEDTLS_THREADING_C)
605     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
606         return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
607 #endif
608 
609     return( ret );
610 }
611 
612 #if defined(MBEDTLS_FS_IO)
613 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
614                                       const char *path )
615 {
616     int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
617     FILE *f;
618     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
619 
620     if( ( f = fopen( path, "wb" ) ) == NULL )
621         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
622 
623     if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
624                                          MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
625         goto exit;
626 
627     if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
628         MBEDTLS_CTR_DRBG_MAX_INPUT )
629     {
630         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
631     }
632     else
633     {
634         ret = 0;
635     }
636 
637 exit:
638     mbedtls_platform_zeroize( buf, sizeof( buf ) );
639 
640     fclose( f );
641     return( ret );
642 }
643 
644 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
645                                        const char *path )
646 {
647     int ret = 0;
648     FILE *f = NULL;
649     size_t n;
650     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
651     unsigned char c;
652 
653     if( ( f = fopen( path, "rb" ) ) == NULL )
654         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
655 
656     n = fread( buf, 1, sizeof( buf ), f );
657     if( fread( &c, 1, 1, f ) != 0 )
658     {
659         ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
660         goto exit;
661     }
662     if( n == 0 || ferror( f ) )
663     {
664         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
665         goto exit;
666     }
667     fclose( f );
668     f = NULL;
669 
670     ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
671 
672 exit:
673     mbedtls_platform_zeroize( buf, sizeof( buf ) );
674     if( f != NULL )
675         fclose( f );
676     if( ret != 0 )
677         return( ret );
678     return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
679 }
680 #endif /* MBEDTLS_FS_IO */
681 
682 #if defined(MBEDTLS_SELF_TEST)
683 
684 static const unsigned char entropy_source_pr[96] =
685     { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
686       0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
687       0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
688       0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
689       0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
690       0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
691       0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
692       0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
693       0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
694       0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
695       0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
696       0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
697 
698 static const unsigned char entropy_source_nopr[64] =
699     { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
700       0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
701       0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
702       0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
703       0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
704       0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
705       0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
706       0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
707 
708 static const unsigned char nonce_pers_pr[16] =
709     { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
710       0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
711 
712 static const unsigned char nonce_pers_nopr[16] =
713     { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
714       0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
715 
716 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
717 static const unsigned char result_pr[16] =
718     { 0x95, 0x3c, 0xa5, 0xbd, 0x44, 0x1, 0x34, 0xb7,
719       0x13, 0x58, 0x3e, 0x6a, 0x6c, 0x7e, 0x88, 0x8a };
720 
721 static const unsigned char result_nopr[16] =
722     { 0x6c, 0x25, 0x27, 0x95, 0xa3, 0x62, 0xd6, 0xdb,
723       0x90, 0xfd, 0x69, 0xb5, 0x42, 0x9, 0x4b, 0x84 };
724 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
725 static const unsigned char result_pr[16] =
726     { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
727       0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
728 
729 static const unsigned char result_nopr[16] =
730     { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
731       0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
732 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
733 
734 static size_t test_offset;
735 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
736                                        size_t len )
737 {
738     const unsigned char *p = data;
739     memcpy( buf, p + test_offset, len );
740     test_offset += len;
741     return( 0 );
742 }
743 
744 #define CHK( c )    if( (c) != 0 )                          \
745                     {                                       \
746                         if( verbose != 0 )                  \
747                             mbedtls_printf( "failed\n" );  \
748                         return( 1 );                        \
749                     }
750 
751 /*
752  * Checkup routine
753  */
754 int mbedtls_ctr_drbg_self_test( int verbose )
755 {
756     mbedtls_ctr_drbg_context ctx;
757     unsigned char buf[16];
758 
759     mbedtls_ctr_drbg_init( &ctx );
760 
761     /*
762      * Based on a NIST CTR_DRBG test vector (PR = True)
763      */
764     if( verbose != 0 )
765         mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );
766 
767     test_offset = 0;
768     mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
769     mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
770     CHK( mbedtls_ctr_drbg_seed( &ctx,
771                                 ctr_drbg_self_test_entropy,
772                                 (void *) entropy_source_pr,
773                                 nonce_pers_pr, 16 ) );
774     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
775     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
776     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
777     CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
778 
779     mbedtls_ctr_drbg_free( &ctx );
780 
781     if( verbose != 0 )
782         mbedtls_printf( "passed\n" );
783 
784     /*
785      * Based on a NIST CTR_DRBG test vector (PR = FALSE)
786      */
787     if( verbose != 0 )
788         mbedtls_printf( "  CTR_DRBG (PR = FALSE): " );
789 
790     mbedtls_ctr_drbg_init( &ctx );
791 
792     test_offset = 0;
793     mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
794     mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
795     CHK( mbedtls_ctr_drbg_seed( &ctx,
796                                 ctr_drbg_self_test_entropy,
797                                 (void *) entropy_source_nopr,
798                                 nonce_pers_nopr, 16 ) );
799     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
800     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
801     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
802     CHK( memcmp( buf, result_nopr, 16 ) );
803 
804     mbedtls_ctr_drbg_free( &ctx );
805 
806     if( verbose != 0 )
807         mbedtls_printf( "passed\n" );
808 
809     if( verbose != 0 )
810             mbedtls_printf( "\n" );
811 
812     return( 0 );
813 }
814 #endif /* MBEDTLS_SELF_TEST */
815 
816 #endif /* MBEDTLS_CTR_DRBG_C */
817