1 /* 2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 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 /* 20 * The NIST SP 800-90 DRBGs are described in the following publication. 21 * 22 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf 23 */ 24 25 #include "common.h" 26 27 #if defined(MBEDTLS_CTR_DRBG_C) 28 29 #include "mbedtls/ctr_drbg.h" 30 #include "mbedtls/platform_util.h" 31 #include "mbedtls/error.h" 32 33 #include <string.h> 34 35 #if defined(MBEDTLS_FS_IO) 36 #include <stdio.h> 37 #endif 38 39 #include "mbedtls/platform.h" 40 41 /* 42 * CTR_DRBG context initialization 43 */ 44 void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) 45 { 46 memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context)); 47 mbedtls_aes_init(&ctx->aes_ctx); 48 /* Indicate that the entropy nonce length is not set explicitly. 49 * See mbedtls_ctr_drbg_set_nonce_len(). */ 50 ctx->reseed_counter = -1; 51 52 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; 53 } 54 55 /* 56 * This function resets CTR_DRBG context to the state immediately 57 * after initial call of mbedtls_ctr_drbg_init(). 58 */ 59 void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx) 60 { 61 if (ctx == NULL) { 62 return; 63 } 64 65 #if defined(MBEDTLS_THREADING_C) 66 /* The mutex is initialized iff f_entropy is set. */ 67 if (ctx->f_entropy != NULL) { 68 mbedtls_mutex_free(&ctx->mutex); 69 } 70 #endif 71 mbedtls_aes_free(&ctx->aes_ctx); 72 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context)); 73 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; 74 ctx->reseed_counter = -1; 75 } 76 77 void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx, 78 int resistance) 79 { 80 ctx->prediction_resistance = resistance; 81 } 82 83 void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx, 84 size_t len) 85 { 86 ctx->entropy_len = len; 87 } 88 89 int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx, 90 size_t len) 91 { 92 /* If mbedtls_ctr_drbg_seed() has already been called, it's 93 * too late. Return the error code that's closest to making sense. */ 94 if (ctx->f_entropy != NULL) { 95 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; 96 } 97 98 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { 99 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 100 } 101 102 /* This shouldn't be an issue because 103 * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible 104 * configuration, but make sure anyway. */ 105 if (len > INT_MAX) { 106 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 107 } 108 109 /* For backward compatibility with Mbed TLS <= 2.19, store the 110 * entropy nonce length in a field that already exists, but isn't 111 * used until after the initial seeding. */ 112 /* Due to the capping of len above, the value fits in an int. */ 113 ctx->reseed_counter = (int) len; 114 return 0; 115 } 116 117 void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx, 118 int interval) 119 { 120 ctx->reseed_interval = interval; 121 } 122 123 static int block_cipher_df(unsigned char *output, 124 const unsigned char *data, size_t data_len) 125 { 126 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 127 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; 128 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; 129 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; 130 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; 131 unsigned char *p, *iv; 132 mbedtls_aes_context aes_ctx; 133 int ret = 0; 134 135 int i, j; 136 size_t buf_len, use_len; 137 138 if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { 139 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 140 } 141 142 memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 143 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16); 144 mbedtls_aes_init(&aes_ctx); 145 146 /* 147 * Construct IV (16 bytes) and S in buffer 148 * IV = Counter (in 32-bits) padded to 16 with zeroes 149 * S = Length input string (in 32-bits) || Length of output (in 32-bits) || 150 * data || 0x80 151 * (Total is padded to a multiple of 16-bytes with zeroes) 152 */ 153 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; 154 MBEDTLS_PUT_UINT32_BE(data_len, p, 0); 155 p += 4 + 3; 156 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; 157 memcpy(p, data, data_len); 158 p[data_len] = 0x80; 159 160 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; 161 162 for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) { 163 key[i] = i; 164 } 165 166 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 167 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { 168 goto exit; 169 } 170 171 /* 172 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data 173 */ 174 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { 175 p = buf; 176 memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE); 177 use_len = buf_len; 178 179 while (use_len > 0) { 180 mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE); 181 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 182 use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ? 183 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; 184 185 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, 186 chain, chain)) != 0) { 187 goto exit; 188 } 189 } 190 191 memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE); 192 193 /* 194 * Update IV 195 */ 196 buf[3]++; 197 } 198 199 /* 200 * Do final encryption with reduced data 201 */ 202 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, 203 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { 204 goto exit; 205 } 206 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; 207 p = output; 208 209 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { 210 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, 211 iv, iv)) != 0) { 212 goto exit; 213 } 214 memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE); 215 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 216 } 217 exit: 218 mbedtls_aes_free(&aes_ctx); 219 /* 220 * tidy up the stack 221 */ 222 mbedtls_platform_zeroize(buf, sizeof(buf)); 223 mbedtls_platform_zeroize(tmp, sizeof(tmp)); 224 mbedtls_platform_zeroize(key, sizeof(key)); 225 mbedtls_platform_zeroize(chain, sizeof(chain)); 226 if (0 != ret) { 227 /* 228 * wipe partial seed from memory 229 */ 230 mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN); 231 } 232 233 return ret; 234 } 235 236 /* CTR_DRBG_Update (SP 800-90A §10.2.1.2) 237 * ctr_drbg_update_internal(ctx, provided_data) 238 * implements 239 * CTR_DRBG_Update(provided_data, Key, V) 240 * with inputs and outputs 241 * ctx->aes_ctx = Key 242 * ctx->counter = V 243 */ 244 static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, 245 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN]) 246 { 247 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; 248 unsigned char *p = tmp; 249 int i, j; 250 int ret = 0; 251 252 memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN); 253 254 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { 255 /* 256 * Increase counter 257 */ 258 for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) { 259 if (++ctx->counter[i - 1] != 0) { 260 break; 261 } 262 } 263 264 /* 265 * Crypt counter block 266 */ 267 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, 268 ctx->counter, p)) != 0) { 269 goto exit; 270 } 271 272 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 273 } 274 275 for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) { 276 tmp[i] ^= data[i]; 277 } 278 279 /* 280 * Update key and counter 281 */ 282 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, 283 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { 284 goto exit; 285 } 286 memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, 287 MBEDTLS_CTR_DRBG_BLOCKSIZE); 288 289 exit: 290 mbedtls_platform_zeroize(tmp, sizeof(tmp)); 291 return ret; 292 } 293 294 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) 295 * mbedtls_ctr_drbg_update(ctx, additional, add_len) 296 * implements 297 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, 298 * security_strength) -> initial_working_state 299 * with inputs 300 * ctx->counter = all-bits-0 301 * ctx->aes_ctx = context from all-bits-0 key 302 * additional[:add_len] = entropy_input || nonce || personalization_string 303 * and with outputs 304 * ctx = initial_working_state 305 */ 306 int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx, 307 const unsigned char *additional, 308 size_t add_len) 309 { 310 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; 311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 312 313 if (add_len == 0) { 314 return 0; 315 } 316 317 if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) { 318 goto exit; 319 } 320 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { 321 goto exit; 322 } 323 324 exit: 325 mbedtls_platform_zeroize(add_input, sizeof(add_input)); 326 return ret; 327 } 328 329 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) 330 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len) 331 * implements 332 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input) 333 * -> new_working_state 334 * with inputs 335 * ctx contains working_state 336 * additional[:len] = additional_input 337 * and entropy_input comes from calling ctx->f_entropy 338 * for (ctx->entropy_len + nonce_len) bytes 339 * and with output 340 * ctx contains new_working_state 341 */ 342 static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx, 343 const unsigned char *additional, 344 size_t len, 345 size_t nonce_len) 346 { 347 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; 348 size_t seedlen = 0; 349 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 350 351 if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { 352 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 353 } 354 if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) { 355 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 356 } 357 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) { 358 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 359 } 360 361 memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT); 362 363 /* Gather entropy_len bytes of entropy to seed state. */ 364 if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) { 365 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; 366 } 367 seedlen += ctx->entropy_len; 368 369 /* Gather entropy for a nonce if requested. */ 370 if (nonce_len != 0) { 371 if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) { 372 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; 373 } 374 seedlen += nonce_len; 375 } 376 377 /* Add additional data if provided. */ 378 if (additional != NULL && len != 0) { 379 memcpy(seed + seedlen, additional, len); 380 seedlen += len; 381 } 382 383 /* Reduce to 384 bits. */ 384 if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) { 385 goto exit; 386 } 387 388 /* Update state. */ 389 if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) { 390 goto exit; 391 } 392 ctx->reseed_counter = 1; 393 394 exit: 395 mbedtls_platform_zeroize(seed, sizeof(seed)); 396 return ret; 397 } 398 399 int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx, 400 const unsigned char *additional, size_t len) 401 { 402 return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0); 403 } 404 405 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length 406 * is sufficient to achieve the maximum security strength given the key 407 * size and entropy length. If there is enough entropy in the initial 408 * call to the entropy function to serve as both the entropy input and 409 * the nonce, don't make a second call to get a nonce. */ 410 static size_t good_nonce_len(size_t entropy_len) 411 { 412 if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) { 413 return 0; 414 } else { 415 return (entropy_len + 1) / 2; 416 } 417 } 418 419 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) 420 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len) 421 * implements 422 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, 423 * security_strength) -> initial_working_state 424 * with inputs 425 * custom[:len] = nonce || personalization_string 426 * where entropy_input comes from f_entropy for ctx->entropy_len bytes 427 * and with outputs 428 * ctx = initial_working_state 429 */ 430 int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, 431 int (*f_entropy)(void *, unsigned char *, size_t), 432 void *p_entropy, 433 const unsigned char *custom, 434 size_t len) 435 { 436 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 437 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; 438 size_t nonce_len; 439 440 memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE); 441 442 /* The mutex is initialized iff f_entropy is set. */ 443 #if defined(MBEDTLS_THREADING_C) 444 mbedtls_mutex_init(&ctx->mutex); 445 #endif 446 447 ctx->f_entropy = f_entropy; 448 ctx->p_entropy = p_entropy; 449 450 if (ctx->entropy_len == 0) { 451 ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; 452 } 453 /* ctx->reseed_counter contains the desired amount of entropy to 454 * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()). 455 * If it's -1, indicating that the entropy nonce length was not set 456 * explicitly, use a sufficiently large nonce for security. */ 457 nonce_len = (ctx->reseed_counter >= 0 ? 458 (size_t) ctx->reseed_counter : 459 good_nonce_len(ctx->entropy_len)); 460 461 /* Initialize with an empty key. */ 462 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, 463 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { 464 return ret; 465 } 466 467 /* Do the initial seeding. */ 468 if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len, 469 nonce_len)) != 0) { 470 return ret; 471 } 472 return 0; 473 } 474 475 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) 476 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) 477 * implements 478 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) 479 * -> working_state_after_reseed 480 * if required, then 481 * CTR_DRBG_Generate(working_state_after_reseed, 482 * requested_number_of_bits, additional_input) 483 * -> status, returned_bits, new_working_state 484 * with inputs 485 * ctx contains working_state 486 * requested_number_of_bits = 8 * output_len 487 * additional[:add_len] = additional_input 488 * and entropy_input comes from calling ctx->f_entropy 489 * and with outputs 490 * status = SUCCESS (this function does the reseed internally) 491 * returned_bits = output[:output_len] 492 * ctx contains new_working_state 493 */ 494 int mbedtls_ctr_drbg_random_with_add(void *p_rng, 495 unsigned char *output, size_t output_len, 496 const unsigned char *additional, size_t add_len) 497 { 498 int ret = 0; 499 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 500 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; 501 unsigned char *p = output; 502 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; 503 int i; 504 size_t use_len; 505 506 if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) { 507 return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG; 508 } 509 510 if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) { 511 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 512 } 513 514 memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN); 515 516 if (ctx->reseed_counter > ctx->reseed_interval || 517 ctx->prediction_resistance) { 518 if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) { 519 return ret; 520 } 521 add_len = 0; 522 } 523 524 if (add_len > 0) { 525 if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) { 526 goto exit; 527 } 528 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { 529 goto exit; 530 } 531 } 532 533 while (output_len > 0) { 534 /* 535 * Increase counter 536 */ 537 for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) { 538 if (++ctx->counter[i - 1] != 0) { 539 break; 540 } 541 } 542 543 /* 544 * Crypt counter block 545 */ 546 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, 547 ctx->counter, tmp)) != 0) { 548 goto exit; 549 } 550 551 use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE) 552 ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len; 553 /* 554 * Copy random block to destination 555 */ 556 memcpy(p, tmp, use_len); 557 p += use_len; 558 output_len -= use_len; 559 } 560 561 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { 562 goto exit; 563 } 564 565 ctx->reseed_counter++; 566 567 exit: 568 mbedtls_platform_zeroize(add_input, sizeof(add_input)); 569 mbedtls_platform_zeroize(tmp, sizeof(tmp)); 570 return ret; 571 } 572 573 int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output, 574 size_t output_len) 575 { 576 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 577 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 578 579 #if defined(MBEDTLS_THREADING_C) 580 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { 581 return ret; 582 } 583 #endif 584 585 ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0); 586 587 #if defined(MBEDTLS_THREADING_C) 588 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { 589 return MBEDTLS_ERR_THREADING_MUTEX_ERROR; 590 } 591 #endif 592 593 return ret; 594 } 595 596 #if defined(MBEDTLS_FS_IO) 597 int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, 598 const char *path) 599 { 600 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 601 FILE *f; 602 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT]; 603 604 if ((f = fopen(path, "wb")) == NULL) { 605 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 606 } 607 608 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ 609 mbedtls_setbuf(f, NULL); 610 611 if ((ret = mbedtls_ctr_drbg_random(ctx, buf, 612 MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) { 613 goto exit; 614 } 615 616 if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) != 617 MBEDTLS_CTR_DRBG_MAX_INPUT) { 618 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 619 } else { 620 ret = 0; 621 } 622 623 exit: 624 mbedtls_platform_zeroize(buf, sizeof(buf)); 625 626 fclose(f); 627 return ret; 628 } 629 630 int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx, 631 const char *path) 632 { 633 int ret = 0; 634 FILE *f = NULL; 635 size_t n; 636 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT]; 637 unsigned char c; 638 639 if ((f = fopen(path, "rb")) == NULL) { 640 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 641 } 642 643 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ 644 mbedtls_setbuf(f, NULL); 645 646 n = fread(buf, 1, sizeof(buf), f); 647 if (fread(&c, 1, 1, f) != 0) { 648 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; 649 goto exit; 650 } 651 if (n == 0 || ferror(f)) { 652 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 653 goto exit; 654 } 655 fclose(f); 656 f = NULL; 657 658 ret = mbedtls_ctr_drbg_update(ctx, buf, n); 659 660 exit: 661 mbedtls_platform_zeroize(buf, sizeof(buf)); 662 if (f != NULL) { 663 fclose(f); 664 } 665 if (ret != 0) { 666 return ret; 667 } 668 return mbedtls_ctr_drbg_write_seed_file(ctx, path); 669 } 670 #endif /* MBEDTLS_FS_IO */ 671 672 #if defined(MBEDTLS_SELF_TEST) 673 674 /* The CTR_DRBG NIST test vectors used here are available at 675 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip 676 * 677 * The parameters used to derive the test data are: 678 * 679 * [AES-128 use df] 680 * [PredictionResistance = True/False] 681 * [EntropyInputLen = 128] 682 * [NonceLen = 64] 683 * [PersonalizationStringLen = 128] 684 * [AdditionalInputLen = 0] 685 * [ReturnedBitsLen = 512] 686 * 687 * [AES-256 use df] 688 * [PredictionResistance = True/False] 689 * [EntropyInputLen = 256] 690 * [NonceLen = 128] 691 * [PersonalizationStringLen = 256] 692 * [AdditionalInputLen = 0] 693 * [ReturnedBitsLen = 512] 694 * 695 */ 696 697 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) 698 static const unsigned char entropy_source_pr[] = 699 { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb, 700 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92, 701 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8, 702 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20, 703 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0, 704 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad, 705 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 }; 706 707 static const unsigned char entropy_source_nopr[] = 708 { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45, 709 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9, 710 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20, 711 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f, 712 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c }; 713 714 static const unsigned char pers_pr[] = 715 { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a, 716 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad }; 717 718 static const unsigned char pers_nopr[] = 719 { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c, 720 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f }; 721 722 static const unsigned char result_pr[] = 723 { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66, 724 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff, 725 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10, 726 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30, 727 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4, 728 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc, 729 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06, 730 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf }; 731 732 static const unsigned char result_nopr[] = 733 { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13, 734 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0, 735 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf, 736 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2, 737 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7, 738 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2, 739 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02, 740 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 }; 741 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ 742 743 static const unsigned char entropy_source_pr[] = 744 { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49, 745 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a, 746 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85, 747 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e, 748 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15, 749 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45, 750 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8, 751 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c, 752 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3, 753 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce, 754 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e, 755 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76, 756 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77, 757 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe }; 758 759 static const unsigned char entropy_source_nopr[] = 760 { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d, 761 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0, 762 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73, 763 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c, 764 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2, 765 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1, 766 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a, 767 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb, 768 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a, 769 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 }; 770 771 static const unsigned char pers_pr[] = 772 { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33, 773 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e, 774 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0, 775 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 }; 776 777 static const unsigned char pers_nopr[] = 778 { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29, 779 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf, 780 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb, 781 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b }; 782 783 static const unsigned char result_pr[] = 784 { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85, 785 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d, 786 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62, 787 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d, 788 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb, 789 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39, 790 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40, 791 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 }; 792 793 static const unsigned char result_nopr[] = 794 { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad, 795 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3, 796 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b, 797 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14, 798 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54, 799 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30, 800 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a, 801 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 }; 802 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ 803 804 static size_t test_offset; 805 static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf, 806 size_t len) 807 { 808 const unsigned char *p = data; 809 memcpy(buf, p + test_offset, len); 810 test_offset += len; 811 return 0; 812 } 813 814 #define CHK(c) if ((c) != 0) \ 815 { \ 816 if (verbose != 0) \ 817 mbedtls_printf("failed\n"); \ 818 return 1; \ 819 } 820 821 #define SELF_TEST_OUTPUT_DISCARD_LENGTH 64 822 823 /* 824 * Checkup routine 825 */ 826 int mbedtls_ctr_drbg_self_test(int verbose) 827 { 828 mbedtls_ctr_drbg_context ctx; 829 unsigned char buf[sizeof(result_pr)]; 830 831 mbedtls_ctr_drbg_init(&ctx); 832 833 /* 834 * Based on a NIST CTR_DRBG test vector (PR = True) 835 */ 836 if (verbose != 0) { 837 mbedtls_printf(" CTR_DRBG (PR = TRUE) : "); 838 } 839 840 test_offset = 0; 841 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE); 842 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2); 843 CHK(mbedtls_ctr_drbg_seed(&ctx, 844 ctr_drbg_self_test_entropy, 845 (void *) entropy_source_pr, 846 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE)); 847 mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON); 848 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH)); 849 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr))); 850 CHK(memcmp(buf, result_pr, sizeof(result_pr))); 851 852 mbedtls_ctr_drbg_free(&ctx); 853 854 if (verbose != 0) { 855 mbedtls_printf("passed\n"); 856 } 857 858 /* 859 * Based on a NIST CTR_DRBG test vector (PR = FALSE) 860 */ 861 if (verbose != 0) { 862 mbedtls_printf(" CTR_DRBG (PR = FALSE): "); 863 } 864 865 mbedtls_ctr_drbg_init(&ctx); 866 867 test_offset = 0; 868 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE); 869 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2); 870 CHK(mbedtls_ctr_drbg_seed(&ctx, 871 ctr_drbg_self_test_entropy, 872 (void *) entropy_source_nopr, 873 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE)); 874 CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0)); 875 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH)); 876 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr))); 877 CHK(memcmp(buf, result_nopr, sizeof(result_nopr))); 878 879 mbedtls_ctr_drbg_free(&ctx); 880 881 if (verbose != 0) { 882 mbedtls_printf("passed\n"); 883 } 884 885 if (verbose != 0) { 886 mbedtls_printf("\n"); 887 } 888 889 return 0; 890 } 891 #endif /* MBEDTLS_SELF_TEST */ 892 893 #endif /* MBEDTLS_CTR_DRBG_C */ 894