xref: /optee_os/lib/libmbedtls/mbedtls/library/ctr_drbg.c (revision c6672fdcd95b9a895eb5b4191f8ba3483a34a442)
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 publucation.
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 
37 #include <string.h>
38 
39 #if defined(MBEDTLS_FS_IO)
40 #include <stdio.h>
41 #endif
42 
43 #if defined(MBEDTLS_SELF_TEST)
44 #if defined(MBEDTLS_PLATFORM_C)
45 #include "mbedtls/platform.h"
46 #else
47 #include <stdio.h>
48 #define mbedtls_printf printf
49 #endif /* MBEDTLS_PLATFORM_C */
50 #endif /* MBEDTLS_SELF_TEST */
51 
52 /* Implementation that should never be optimized out by the compiler */
53 static void mbedtls_zeroize( void *v, size_t n ) {
54     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
55 }
56 
57 /*
58  * CTR_DRBG context initialization
59  */
60 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
61 {
62     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
63 
64 #if defined(MBEDTLS_THREADING_C)
65     mbedtls_mutex_init( &ctx->mutex );
66 #endif
67 }
68 
69 /*
70  * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
71  * NIST tests to succeed (which require known length fixed entropy)
72  */
73 int mbedtls_ctr_drbg_seed_entropy_len(
74                    mbedtls_ctr_drbg_context *ctx,
75                    int (*f_entropy)(void *, unsigned char *, size_t),
76                    void *p_entropy,
77                    const unsigned char *custom,
78                    size_t len,
79                    size_t entropy_len )
80 {
81     int ret;
82     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
83 
84     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
85 
86     mbedtls_aes_init( &ctx->aes_ctx );
87 
88     ctx->f_entropy = f_entropy;
89     ctx->p_entropy = p_entropy;
90 
91     ctx->entropy_len = entropy_len;
92     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
93 
94     /*
95      * Initialize with an empty key
96      */
97     mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
98 
99     if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
100         return( ret );
101 
102     return( 0 );
103 }
104 
105 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
106                    int (*f_entropy)(void *, unsigned char *, size_t),
107                    void *p_entropy,
108                    const unsigned char *custom,
109                    size_t len )
110 {
111     return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
112                                        MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
113 }
114 
115 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
116 {
117     if( ctx == NULL )
118         return;
119 
120 #if defined(MBEDTLS_THREADING_C)
121     mbedtls_mutex_free( &ctx->mutex );
122 #endif
123     mbedtls_aes_free( &ctx->aes_ctx );
124     mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
125 }
126 
127 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
128 {
129     ctx->prediction_resistance = resistance;
130 }
131 
132 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
133 {
134     ctx->entropy_len = len;
135 }
136 
137 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
138 {
139     ctx->reseed_interval = interval;
140 }
141 
142 static int block_cipher_df( unsigned char *output,
143                             const unsigned char *data, size_t data_len )
144 {
145     unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
146     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
147     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
148     unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
149     unsigned char *p, *iv;
150     mbedtls_aes_context aes_ctx;
151 
152     int i, j;
153     size_t buf_len, use_len;
154 
155     if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
156         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
157 
158     memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
159     mbedtls_aes_init( &aes_ctx );
160 
161     /*
162      * Construct IV (16 bytes) and S in buffer
163      * IV = Counter (in 32-bits) padded to 16 with zeroes
164      * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
165      *     data || 0x80
166      *     (Total is padded to a multiple of 16-bytes with zeroes)
167      */
168     p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
169     *p++ = ( data_len >> 24 ) & 0xff;
170     *p++ = ( data_len >> 16 ) & 0xff;
171     *p++ = ( data_len >> 8  ) & 0xff;
172     *p++ = ( data_len       ) & 0xff;
173     p += 3;
174     *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
175     memcpy( p, data, data_len );
176     p[data_len] = 0x80;
177 
178     buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
179 
180     for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
181         key[i] = i;
182 
183     mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
184 
185     /*
186      * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
187      */
188     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
189     {
190         p = buf;
191         memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
192         use_len = buf_len;
193 
194         while( use_len > 0 )
195         {
196             for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
197                 chain[i] ^= p[i];
198             p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
199             use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
200                        MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
201 
202             mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain );
203         }
204 
205         memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
206 
207         /*
208          * Update IV
209          */
210         buf[3]++;
211     }
212 
213     /*
214      * Do final encryption with reduced data
215      */
216     mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
217     iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
218     p = output;
219 
220     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
221     {
222         mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
223         memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
224         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
225     }
226 
227     mbedtls_aes_free( &aes_ctx );
228 
229     return( 0 );
230 }
231 
232 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
233                               const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
234 {
235     unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
236     unsigned char *p = tmp;
237     int i, j;
238 
239     memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
240 
241     for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
242     {
243         /*
244          * Increase counter
245          */
246         for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
247             if( ++ctx->counter[i - 1] != 0 )
248                 break;
249 
250         /*
251          * Crypt counter block
252          */
253         mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p );
254 
255         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
256     }
257 
258     for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
259         tmp[i] ^= data[i];
260 
261     /*
262      * Update key and counter
263      */
264     mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
265     memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
266 
267     return( 0 );
268 }
269 
270 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
271                       const unsigned char *additional, size_t add_len )
272 {
273     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
274 
275     if( add_len > 0 )
276     {
277         /* MAX_INPUT would be more logical here, but we have to match
278          * block_cipher_df()'s limits since we can't propagate errors */
279         if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
280             add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
281 
282         block_cipher_df( add_input, additional, add_len );
283         ctr_drbg_update_internal( ctx, add_input );
284     }
285 }
286 
287 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
288                      const unsigned char *additional, size_t len )
289 {
290     unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
291     size_t seedlen = 0;
292 
293     if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
294         len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
295         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
296 
297     memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
298 
299     /*
300      * Gather entropy_len bytes of entropy to seed state
301      */
302     if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
303                              ctx->entropy_len ) )
304     {
305         return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
306     }
307 
308     seedlen += ctx->entropy_len;
309 
310     /*
311      * Add additional data
312      */
313     if( additional && len )
314     {
315         memcpy( seed + seedlen, additional, len );
316         seedlen += len;
317     }
318 
319     /*
320      * Reduce to 384 bits
321      */
322     block_cipher_df( seed, seed, seedlen );
323 
324     /*
325      * Update state
326      */
327     ctr_drbg_update_internal( ctx, seed );
328     ctx->reseed_counter = 1;
329 
330     return( 0 );
331 }
332 
333 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
334                               unsigned char *output, size_t output_len,
335                               const unsigned char *additional, size_t add_len )
336 {
337     int ret = 0;
338     mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
339     unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
340     unsigned char *p = output;
341     unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
342     int i;
343     size_t use_len;
344 
345     if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
346         return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
347 
348     if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
349         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
350 
351     memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
352 
353     if( ctx->reseed_counter > ctx->reseed_interval ||
354         ctx->prediction_resistance )
355     {
356         if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
357             return( ret );
358 
359         add_len = 0;
360     }
361 
362     if( add_len > 0 )
363     {
364         block_cipher_df( add_input, additional, add_len );
365         ctr_drbg_update_internal( ctx, add_input );
366     }
367 
368     while( output_len > 0 )
369     {
370         /*
371          * Increase counter
372          */
373         for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
374             if( ++ctx->counter[i - 1] != 0 )
375                 break;
376 
377         /*
378          * Crypt counter block
379          */
380         mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp );
381 
382         use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
383                                                        output_len;
384         /*
385          * Copy random block to destination
386          */
387         memcpy( p, tmp, use_len );
388         p += use_len;
389         output_len -= use_len;
390     }
391 
392     ctr_drbg_update_internal( ctx, add_input );
393 
394     ctx->reseed_counter++;
395 
396     return( 0 );
397 }
398 
399 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
400 {
401     int ret;
402     mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
403 
404 #if defined(MBEDTLS_THREADING_C)
405     if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
406         return( ret );
407 #endif
408 
409     ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
410 
411 #if defined(MBEDTLS_THREADING_C)
412     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
413         return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
414 #endif
415 
416     return( ret );
417 }
418 
419 #if defined(MBEDTLS_FS_IO)
420 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
421 {
422     int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
423     FILE *f;
424     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
425 
426     if( ( f = fopen( path, "wb" ) ) == NULL )
427         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
428 
429     if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
430         goto exit;
431 
432     if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
433     {
434         ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
435         goto exit;
436     }
437 
438     ret = 0;
439 
440 exit:
441     fclose( f );
442     return( ret );
443 }
444 
445 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
446 {
447     FILE *f;
448     size_t n;
449     unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
450 
451     if( ( f = fopen( path, "rb" ) ) == NULL )
452         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
453 
454     fseek( f, 0, SEEK_END );
455     n = (size_t) ftell( f );
456     fseek( f, 0, SEEK_SET );
457 
458     if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
459     {
460         fclose( f );
461         return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
462     }
463 
464     if( fread( buf, 1, n, f ) != n )
465     {
466         fclose( f );
467         return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
468     }
469 
470     fclose( f );
471 
472     mbedtls_ctr_drbg_update( ctx, buf, n );
473 
474     return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
475 }
476 #endif /* MBEDTLS_FS_IO */
477 
478 #if defined(MBEDTLS_SELF_TEST)
479 
480 static const unsigned char entropy_source_pr[96] =
481     { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
482       0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
483       0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
484       0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
485       0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
486       0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
487       0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
488       0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
489       0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
490       0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
491       0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
492       0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
493 
494 static const unsigned char entropy_source_nopr[64] =
495     { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
496       0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
497       0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
498       0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
499       0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
500       0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
501       0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
502       0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
503 
504 static const unsigned char nonce_pers_pr[16] =
505     { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
506       0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
507 
508 static const unsigned char nonce_pers_nopr[16] =
509     { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
510       0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
511 
512 static const unsigned char result_pr[16] =
513     { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
514       0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
515 
516 static const unsigned char result_nopr[16] =
517     { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
518       0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
519 
520 static size_t test_offset;
521 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
522                                        size_t len )
523 {
524     const unsigned char *p = data;
525     memcpy( buf, p + test_offset, len );
526     test_offset += len;
527     return( 0 );
528 }
529 
530 #define CHK( c )    if( (c) != 0 )                          \
531                     {                                       \
532                         if( verbose != 0 )                  \
533                             mbedtls_printf( "failed\n" );  \
534                         return( 1 );                        \
535                     }
536 
537 /*
538  * Checkup routine
539  */
540 int mbedtls_ctr_drbg_self_test( int verbose )
541 {
542     mbedtls_ctr_drbg_context ctx;
543     unsigned char buf[16];
544 
545     mbedtls_ctr_drbg_init( &ctx );
546 
547     /*
548      * Based on a NIST CTR_DRBG test vector (PR = True)
549      */
550     if( verbose != 0 )
551         mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );
552 
553     test_offset = 0;
554     CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
555                                 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
556     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
557     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
558     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
559     CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
560 
561     mbedtls_ctr_drbg_free( &ctx );
562 
563     if( verbose != 0 )
564         mbedtls_printf( "passed\n" );
565 
566     /*
567      * Based on a NIST CTR_DRBG test vector (PR = FALSE)
568      */
569     if( verbose != 0 )
570         mbedtls_printf( "  CTR_DRBG (PR = FALSE): " );
571 
572     mbedtls_ctr_drbg_init( &ctx );
573 
574     test_offset = 0;
575     CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
576                             (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
577     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
578     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
579     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
580     CHK( memcmp( buf, result_nopr, 16 ) );
581 
582     mbedtls_ctr_drbg_free( &ctx );
583 
584     if( verbose != 0 )
585         mbedtls_printf( "passed\n" );
586 
587     if( verbose != 0 )
588             mbedtls_printf( "\n" );
589 
590     return( 0 );
591 }
592 #endif /* MBEDTLS_SELF_TEST */
593 
594 #endif /* MBEDTLS_CTR_DRBG_C */
595