1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * HMAC_DRBG implementation (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 /* 23 * The NIST SP 800-90A DRBGs are described in the following publication. 24 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf 25 * References below are based on rev. 1 (January 2012). 26 */ 27 28 #if !defined(MBEDTLS_CONFIG_FILE) 29 #include "mbedtls/config.h" 30 #else 31 #include MBEDTLS_CONFIG_FILE 32 #endif 33 34 #if defined(MBEDTLS_HMAC_DRBG_C) 35 36 #include "mbedtls/hmac_drbg.h" 37 #include "mbedtls/platform_util.h" 38 #include "mbedtls/error.h" 39 40 #include <string.h> 41 42 #if defined(MBEDTLS_FS_IO) 43 #include <stdio.h> 44 #endif 45 46 #if defined(MBEDTLS_SELF_TEST) 47 #if defined(MBEDTLS_PLATFORM_C) 48 #include "mbedtls/platform.h" 49 #else 50 #include <stdio.h> 51 #define mbedtls_printf printf 52 #endif /* MBEDTLS_SELF_TEST */ 53 #endif /* MBEDTLS_PLATFORM_C */ 54 55 /* 56 * HMAC_DRBG context initialization 57 */ 58 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) 59 { 60 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); 61 62 #if defined(MBEDTLS_THREADING_C) 63 mbedtls_mutex_init( &ctx->mutex ); 64 #endif 65 } 66 67 /* 68 * HMAC_DRBG update, using optional additional data (10.1.2.2) 69 */ 70 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, 71 const unsigned char *additional, 72 size_t add_len ) 73 { 74 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); 75 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; 76 unsigned char sep[1]; 77 unsigned char K[MBEDTLS_MD_MAX_SIZE]; 78 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA; 79 80 for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) 81 { 82 /* Step 1 or 4 */ 83 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) 84 goto exit; 85 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, 86 ctx->V, md_len ) ) != 0 ) 87 goto exit; 88 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, 89 sep, 1 ) ) != 0 ) 90 goto exit; 91 if( rounds == 2 ) 92 { 93 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, 94 additional, add_len ) ) != 0 ) 95 goto exit; 96 } 97 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) 98 goto exit; 99 100 /* Step 2 or 5 */ 101 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) 102 goto exit; 103 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, 104 ctx->V, md_len ) ) != 0 ) 105 goto exit; 106 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) 107 goto exit; 108 } 109 110 exit: 111 mbedtls_platform_zeroize( K, sizeof( K ) ); 112 return( ret ); 113 } 114 115 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 116 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, 117 const unsigned char *additional, 118 size_t add_len ) 119 { 120 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); 121 } 122 #endif /* MBEDTLS_DEPRECATED_REMOVED */ 123 124 /* 125 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) 126 */ 127 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, 128 const mbedtls_md_info_t * md_info, 129 const unsigned char *data, size_t data_len ) 130 { 131 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 132 133 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) 134 return( ret ); 135 136 /* 137 * Set initial working state. 138 * Use the V memory location, which is currently all 0, to initialize the 139 * MD context with an all-zero key. Then set V to its initial value. 140 */ 141 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, 142 mbedtls_md_get_size( md_info ) ) ) != 0 ) 143 return( ret ); 144 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); 145 146 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) 147 return( ret ); 148 149 return( 0 ); 150 } 151 152 /* 153 * Internal function used both for seeding and reseeding the DRBG. 154 * Comments starting with arabic numbers refer to section 10.1.2.4 155 * of SP800-90A, while roman numbers refer to section 9.2. 156 */ 157 static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx, 158 const unsigned char *additional, size_t len, 159 int use_nonce ) 160 { 161 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; 162 size_t seedlen = 0; 163 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 164 165 { 166 size_t total_entropy_len; 167 168 if( use_nonce == 0 ) 169 total_entropy_len = ctx->entropy_len; 170 else 171 total_entropy_len = ctx->entropy_len * 3 / 2; 172 173 /* III. Check input length */ 174 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || 175 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) 176 { 177 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 178 } 179 } 180 181 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); 182 183 /* IV. Gather entropy_len bytes of entropy for the seed */ 184 if( ( ret = ctx->f_entropy( ctx->p_entropy, 185 seed, ctx->entropy_len ) ) != 0 ) 186 { 187 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); 188 } 189 seedlen += ctx->entropy_len; 190 191 /* For initial seeding, allow adding of nonce generated 192 * from the entropy source. See Sect 8.6.7 in SP800-90A. */ 193 if( use_nonce ) 194 { 195 /* Note: We don't merge the two calls to f_entropy() in order 196 * to avoid requesting too much entropy from f_entropy() 197 * at once. Specifically, if the underlying digest is not 198 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which 199 * is larger than the maximum of 32 Bytes that our own 200 * entropy source implementation can emit in a single 201 * call in configurations disabling SHA-512. */ 202 if( ( ret = ctx->f_entropy( ctx->p_entropy, 203 seed + seedlen, 204 ctx->entropy_len / 2 ) ) != 0 ) 205 { 206 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); 207 } 208 209 seedlen += ctx->entropy_len / 2; 210 } 211 212 213 /* 1. Concatenate entropy and additional data if any */ 214 if( additional != NULL && len != 0 ) 215 { 216 memcpy( seed + seedlen, additional, len ); 217 seedlen += len; 218 } 219 220 /* 2. Update state */ 221 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) 222 goto exit; 223 224 /* 3. Reset reseed_counter */ 225 ctx->reseed_counter = 1; 226 227 exit: 228 /* 4. Done */ 229 mbedtls_platform_zeroize( seed, seedlen ); 230 return( ret ); 231 } 232 233 /* 234 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2 235 */ 236 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, 237 const unsigned char *additional, size_t len ) 238 { 239 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) ); 240 } 241 242 /* 243 * HMAC_DRBG initialisation (10.1.2.3 + 9.1) 244 * 245 * The nonce is not passed as a separate parameter but extracted 246 * from the entropy source as suggested in 8.6.7. 247 */ 248 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, 249 const mbedtls_md_info_t * md_info, 250 int (*f_entropy)(void *, unsigned char *, size_t), 251 void *p_entropy, 252 const unsigned char *custom, 253 size_t len ) 254 { 255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 256 size_t md_size; 257 258 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) 259 return( ret ); 260 261 md_size = mbedtls_md_get_size( md_info ); 262 263 /* 264 * Set initial working state. 265 * Use the V memory location, which is currently all 0, to initialize the 266 * MD context with an all-zero key. Then set V to its initial value. 267 */ 268 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) 269 return( ret ); 270 memset( ctx->V, 0x01, md_size ); 271 272 ctx->f_entropy = f_entropy; 273 ctx->p_entropy = p_entropy; 274 275 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; 276 277 if( ctx->entropy_len == 0 ) 278 { 279 /* 280 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by 281 * each hash function, then according to SP800-90A rev1 10.1 table 2, 282 * min_entropy_len (in bits) is security_strength. 283 * 284 * (This also matches the sizes used in the NIST test vectors.) 285 */ 286 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ 287 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ 288 32; /* better (256+) -> 256 bits */ 289 } 290 291 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, 292 1 /* add nonce */ ) ) != 0 ) 293 { 294 return( ret ); 295 } 296 297 return( 0 ); 298 } 299 300 /* 301 * Set prediction resistance 302 */ 303 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, 304 int resistance ) 305 { 306 ctx->prediction_resistance = resistance; 307 } 308 309 /* 310 * Set entropy length grabbed for seeding 311 */ 312 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) 313 { 314 ctx->entropy_len = len; 315 } 316 317 /* 318 * Set reseed interval 319 */ 320 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) 321 { 322 ctx->reseed_interval = interval; 323 } 324 325 /* 326 * HMAC_DRBG random function with optional additional data: 327 * 10.1.2.5 (arabic) + 9.3 (Roman) 328 */ 329 int mbedtls_hmac_drbg_random_with_add( void *p_rng, 330 unsigned char *output, size_t out_len, 331 const unsigned char *additional, size_t add_len ) 332 { 333 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 334 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 335 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); 336 size_t left = out_len; 337 unsigned char *out = output; 338 339 /* II. Check request length */ 340 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) 341 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); 342 343 /* III. Check input length */ 344 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) 345 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 346 347 /* 1. (aka VII and IX) Check reseed counter and PR */ 348 if( ctx->f_entropy != NULL && /* For no-reseeding instances */ 349 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || 350 ctx->reseed_counter > ctx->reseed_interval ) ) 351 { 352 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) 353 return( ret ); 354 355 add_len = 0; /* VII.4 */ 356 } 357 358 /* 2. Use additional data if any */ 359 if( additional != NULL && add_len != 0 ) 360 { 361 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, 362 additional, add_len ) ) != 0 ) 363 goto exit; 364 } 365 366 /* 3, 4, 5. Generate bytes */ 367 while( left != 0 ) 368 { 369 size_t use_len = left > md_len ? md_len : left; 370 371 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) 372 goto exit; 373 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, 374 ctx->V, md_len ) ) != 0 ) 375 goto exit; 376 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) 377 goto exit; 378 379 memcpy( out, ctx->V, use_len ); 380 out += use_len; 381 left -= use_len; 382 } 383 384 /* 6. Update */ 385 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, 386 additional, add_len ) ) != 0 ) 387 goto exit; 388 389 /* 7. Update reseed counter */ 390 ctx->reseed_counter++; 391 392 exit: 393 /* 8. Done */ 394 return( ret ); 395 } 396 397 /* 398 * HMAC_DRBG random function 399 */ 400 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) 401 { 402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 403 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 404 405 #if defined(MBEDTLS_THREADING_C) 406 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 407 return( ret ); 408 #endif 409 410 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); 411 412 #if defined(MBEDTLS_THREADING_C) 413 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 414 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 415 #endif 416 417 return( ret ); 418 } 419 420 /* 421 * Free an HMAC_DRBG context 422 */ 423 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) 424 { 425 if( ctx == NULL ) 426 return; 427 428 #if defined(MBEDTLS_THREADING_C) 429 mbedtls_mutex_free( &ctx->mutex ); 430 #endif 431 mbedtls_md_free( &ctx->md_ctx ); 432 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); 433 } 434 435 #if defined(MBEDTLS_FS_IO) 436 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 437 { 438 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 439 FILE *f; 440 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 441 442 if( ( f = fopen( path, "wb" ) ) == NULL ) 443 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 444 445 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) 446 goto exit; 447 448 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) 449 { 450 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 451 goto exit; 452 } 453 454 ret = 0; 455 456 exit: 457 fclose( f ); 458 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 459 460 return( ret ); 461 } 462 463 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 464 { 465 int ret = 0; 466 FILE *f = NULL; 467 size_t n; 468 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 469 unsigned char c; 470 471 if( ( f = fopen( path, "rb" ) ) == NULL ) 472 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 473 474 n = fread( buf, 1, sizeof( buf ), f ); 475 if( fread( &c, 1, 1, f ) != 0 ) 476 { 477 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; 478 goto exit; 479 } 480 if( n == 0 || ferror( f ) ) 481 { 482 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 483 goto exit; 484 } 485 fclose( f ); 486 f = NULL; 487 488 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); 489 490 exit: 491 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 492 if( f != NULL ) 493 fclose( f ); 494 if( ret != 0 ) 495 return( ret ); 496 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); 497 } 498 #endif /* MBEDTLS_FS_IO */ 499 500 501 #if defined(MBEDTLS_SELF_TEST) 502 503 #if !defined(MBEDTLS_SHA1_C) 504 /* Dummy checkup routine */ 505 int mbedtls_hmac_drbg_self_test( int verbose ) 506 { 507 (void) verbose; 508 return( 0 ); 509 } 510 #else 511 512 #define OUTPUT_LEN 80 513 514 /* From a NIST PR=true test vector */ 515 static const unsigned char entropy_pr[] = { 516 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, 517 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, 518 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, 519 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, 520 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; 521 static const unsigned char result_pr[OUTPUT_LEN] = { 522 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, 523 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, 524 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, 525 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, 526 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, 527 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, 528 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; 529 530 /* From a NIST PR=false test vector */ 531 static const unsigned char entropy_nopr[] = { 532 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, 533 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, 534 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, 535 0xe9, 0x9d, 0xfe, 0xdf }; 536 static const unsigned char result_nopr[OUTPUT_LEN] = { 537 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, 538 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, 539 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, 540 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, 541 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, 542 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, 543 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; 544 545 /* "Entropy" from buffer */ 546 static size_t test_offset; 547 static int hmac_drbg_self_test_entropy( void *data, 548 unsigned char *buf, size_t len ) 549 { 550 const unsigned char *p = data; 551 memcpy( buf, p + test_offset, len ); 552 test_offset += len; 553 return( 0 ); 554 } 555 556 #define CHK( c ) if( (c) != 0 ) \ 557 { \ 558 if( verbose != 0 ) \ 559 mbedtls_printf( "failed\n" ); \ 560 return( 1 ); \ 561 } 562 563 /* 564 * Checkup routine for HMAC_DRBG with SHA-1 565 */ 566 int mbedtls_hmac_drbg_self_test( int verbose ) 567 { 568 mbedtls_hmac_drbg_context ctx; 569 unsigned char buf[OUTPUT_LEN]; 570 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 571 572 mbedtls_hmac_drbg_init( &ctx ); 573 574 /* 575 * PR = True 576 */ 577 if( verbose != 0 ) 578 mbedtls_printf( " HMAC_DRBG (PR = True) : " ); 579 580 test_offset = 0; 581 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 582 hmac_drbg_self_test_entropy, (void *) entropy_pr, 583 NULL, 0 ) ); 584 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); 585 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 586 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 587 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); 588 mbedtls_hmac_drbg_free( &ctx ); 589 590 mbedtls_hmac_drbg_free( &ctx ); 591 592 if( verbose != 0 ) 593 mbedtls_printf( "passed\n" ); 594 595 /* 596 * PR = False 597 */ 598 if( verbose != 0 ) 599 mbedtls_printf( " HMAC_DRBG (PR = False) : " ); 600 601 mbedtls_hmac_drbg_init( &ctx ); 602 603 test_offset = 0; 604 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 605 hmac_drbg_self_test_entropy, (void *) entropy_nopr, 606 NULL, 0 ) ); 607 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); 608 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 609 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 610 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); 611 mbedtls_hmac_drbg_free( &ctx ); 612 613 mbedtls_hmac_drbg_free( &ctx ); 614 615 if( verbose != 0 ) 616 mbedtls_printf( "passed\n" ); 617 618 if( verbose != 0 ) 619 mbedtls_printf( "\n" ); 620 621 return( 0 ); 622 } 623 #endif /* MBEDTLS_SHA1_C */ 624 #endif /* MBEDTLS_SELF_TEST */ 625 626 #endif /* MBEDTLS_HMAC_DRBG_C */ 627