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