2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This file is part of mbed TLS (https://tls.mbed.org)
22 * The NIST SP 800-90 DRBGs are described in the following publication.
24 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
30 #include MBEDTLS_CONFIG_FILE
33 #if defined(MBEDTLS_CTR_DRBG_C)
35 #include "mbedtls/ctr_drbg.h"
36 #include "mbedtls/platform_util.h"
40 #if defined(MBEDTLS_FS_IO)
44 #if defined(MBEDTLS_SELF_TEST)
45 #if defined(MBEDTLS_PLATFORM_C)
46 #include "mbedtls/platform.h"
49 #define mbedtls_printf printf
50 #endif /* MBEDTLS_PLATFORM_C */
51 #endif /* MBEDTLS_SELF_TEST */
54 * CTR_DRBG context initialization
56 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
58 memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
60 #if defined(MBEDTLS_THREADING_C)
61 mbedtls_mutex_init( &ctx->mutex );
66 * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
67 * NIST tests to succeed (which require known length fixed entropy)
69 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
70 * mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
71 * custom, len, entropy_len)
73 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
74 * security_strength) -> initial_working_state
76 * custom[:len] = nonce || personalization_string
77 * where entropy_input comes from f_entropy for entropy_len bytes
79 * ctx = initial_working_state
81 int mbedtls_ctr_drbg_seed_entropy_len(
82 mbedtls_ctr_drbg_context *ctx,
83 int (*f_entropy)(void *, unsigned char *, size_t),
85 const unsigned char *custom,
90 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
92 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
94 mbedtls_aes_init( &ctx->aes_ctx );
96 ctx->f_entropy = f_entropy;
97 ctx->p_entropy = p_entropy;
99 ctx->entropy_len = entropy_len;
100 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
103 * Initialize with an empty key
105 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
106 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
111 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
118 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
119 int (*f_entropy)(void *, unsigned char *, size_t),
121 const unsigned char *custom,
124 return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy,
126 MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
129 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
134 #if defined(MBEDTLS_THREADING_C)
135 mbedtls_mutex_free( &ctx->mutex );
137 mbedtls_aes_free( &ctx->aes_ctx );
138 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
141 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
144 ctx->prediction_resistance = resistance;
147 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
150 ctx->entropy_len = len;
153 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
156 ctx->reseed_interval = interval;
159 static int block_cipher_df( unsigned char *output,
160 const unsigned char *data, size_t data_len )
162 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
163 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
164 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
165 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
166 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
167 unsigned char *p, *iv;
168 mbedtls_aes_context aes_ctx;
172 size_t buf_len, use_len;
174 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
175 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
177 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
178 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
179 mbedtls_aes_init( &aes_ctx );
182 * Construct IV (16 bytes) and S in buffer
183 * IV = Counter (in 32-bits) padded to 16 with zeroes
184 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
186 * (Total is padded to a multiple of 16-bytes with zeroes)
188 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
189 *p++ = ( data_len >> 24 ) & 0xff;
190 *p++ = ( data_len >> 16 ) & 0xff;
191 *p++ = ( data_len >> 8 ) & 0xff;
192 *p++ = ( data_len ) & 0xff;
194 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
195 memcpy( p, data, data_len );
198 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
200 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
203 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
204 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
210 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
212 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
215 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
220 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
222 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
223 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
224 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
226 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
227 chain, chain ) ) != 0 )
233 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
242 * Do final encryption with reduced data
244 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
245 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
249 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
252 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
254 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
259 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
260 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
263 mbedtls_aes_free( &aes_ctx );
267 mbedtls_platform_zeroize( buf, sizeof( buf ) );
268 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
269 mbedtls_platform_zeroize( key, sizeof( key ) );
270 mbedtls_platform_zeroize( chain, sizeof( chain ) );
274 * wipe partial seed from memory
276 mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
282 /* CTR_DRBG_Update (SP 800-90A §10.2.1.2)
283 * ctr_drbg_update_internal(ctx, provided_data)
285 * CTR_DRBG_Update(provided_data, Key, V)
286 * with inputs and outputs
290 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
291 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
293 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
294 unsigned char *p = tmp;
298 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
300 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
305 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
306 if( ++ctx->counter[i - 1] != 0 )
310 * Crypt counter block
312 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
313 ctx->counter, p ) ) != 0 )
318 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
321 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
325 * Update key and counter
327 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
328 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
332 memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
333 MBEDTLS_CTR_DRBG_BLOCKSIZE );
336 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
340 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
341 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
343 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
344 * security_strength) -> initial_working_state
346 * ctx->counter = all-bits-0
347 * ctx->aes_ctx = context from all-bits-0 key
348 * additional[:add_len] = entropy_input || nonce || personalization_string
350 * ctx = initial_working_state
352 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
353 const unsigned char *additional,
356 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
362 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
364 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
368 mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
372 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
373 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
374 const unsigned char *additional,
377 /* MAX_INPUT would be more logical here, but we have to match
378 * block_cipher_df()'s limits since we can't propagate errors */
379 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
380 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
381 (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
383 #endif /* MBEDTLS_DEPRECATED_REMOVED */
385 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
386 * mbedtls_ctr_drbg_reseed(ctx, additional, len)
388 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
389 * -> new_working_state
391 * ctx contains working_state
392 * additional[:len] = additional_input
393 * and entropy_input comes from calling ctx->f_entropy
395 * ctx contains new_working_state
397 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
398 const unsigned char *additional, size_t len )
400 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
404 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
405 len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
406 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
408 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
411 * Gather entropy_len bytes of entropy to seed state
413 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
416 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
419 seedlen += ctx->entropy_len;
422 * Add additional data
424 if( additional && len )
426 memcpy( seed + seedlen, additional, len );
433 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
439 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
441 ctx->reseed_counter = 1;
444 mbedtls_platform_zeroize( seed, sizeof( seed ) );
448 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
449 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
451 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
452 * -> working_state_after_reseed
454 * CTR_DRBG_Generate(working_state_after_reseed,
455 * requested_number_of_bits, additional_input)
456 * -> status, returned_bits, new_working_state
458 * ctx contains working_state
459 * requested_number_of_bits = 8 * output_len
460 * additional[:add_len] = additional_input
461 * and entropy_input comes from calling ctx->f_entropy
463 * status = SUCCESS (this function does the reseed internally)
464 * returned_bits = output[:output_len]
465 * ctx contains new_working_state
467 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
468 unsigned char *output, size_t output_len,
469 const unsigned char *additional, size_t add_len )
472 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
473 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
474 unsigned char *p = output;
475 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
479 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
480 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
482 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
483 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
485 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
487 if( ctx->reseed_counter > ctx->reseed_interval ||
488 ctx->prediction_resistance )
490 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
499 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
501 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
505 while( output_len > 0 )
510 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
511 if( ++ctx->counter[i - 1] != 0 )
515 * Crypt counter block
517 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
518 ctx->counter, tmp ) ) != 0 )
523 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
524 ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
526 * Copy random block to destination
528 memcpy( p, tmp, use_len );
530 output_len -= use_len;
533 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
536 ctx->reseed_counter++;
539 mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
540 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
544 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
548 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
550 #if defined(MBEDTLS_THREADING_C)
551 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
555 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
557 #if defined(MBEDTLS_THREADING_C)
558 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
559 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
565 #if defined(MBEDTLS_FS_IO)
566 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
569 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
571 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
573 if( ( f = fopen( path, "wb" ) ) == NULL )
574 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
576 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
577 MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
580 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
581 MBEDTLS_CTR_DRBG_MAX_INPUT )
583 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
591 mbedtls_platform_zeroize( buf, sizeof( buf ) );
597 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
603 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
606 if( ( f = fopen( path, "rb" ) ) == NULL )
607 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
609 n = fread( buf, 1, sizeof( buf ), f );
610 if( fread( &c, 1, 1, f ) != 0 )
612 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
615 if( n == 0 || ferror( f ) )
617 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
623 ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
626 mbedtls_platform_zeroize( buf, sizeof( buf ) );
631 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
633 #endif /* MBEDTLS_FS_IO */
635 #if defined(MBEDTLS_SELF_TEST)
637 static const unsigned char entropy_source_pr[96] =
638 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
639 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
640 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
641 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
642 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
643 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
644 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
645 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
646 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
647 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
648 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
649 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
651 static const unsigned char entropy_source_nopr[64] =
652 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
653 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
654 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
655 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
656 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
657 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
658 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
659 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
661 static const unsigned char nonce_pers_pr[16] =
662 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
663 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
665 static const unsigned char nonce_pers_nopr[16] =
666 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
667 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
669 static const unsigned char result_pr[16] =
670 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
671 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
673 static const unsigned char result_nopr[16] =
674 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
675 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
677 static size_t test_offset;
678 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
681 const unsigned char *p = data;
682 memcpy( buf, p + test_offset, len );
687 #define CHK( c ) if( (c) != 0 ) \
690 mbedtls_printf( "failed\n" ); \
697 int mbedtls_ctr_drbg_self_test( int verbose )
699 mbedtls_ctr_drbg_context ctx;
700 unsigned char buf[16];
702 mbedtls_ctr_drbg_init( &ctx );
705 * Based on a NIST CTR_DRBG test vector (PR = True)
708 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
711 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
712 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
713 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
714 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
715 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
716 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
718 mbedtls_ctr_drbg_free( &ctx );
721 mbedtls_printf( "passed\n" );
724 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
727 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
729 mbedtls_ctr_drbg_init( &ctx );
732 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
733 (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
734 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
735 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
736 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
737 CHK( memcmp( buf, result_nopr, 16 ) );
739 mbedtls_ctr_drbg_free( &ctx );
742 mbedtls_printf( "passed\n" );
745 mbedtls_printf( "\n" );
749 #endif /* MBEDTLS_SELF_TEST */
751 #endif /* MBEDTLS_CTR_DRBG_C */