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 §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 §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 §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 §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 §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