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