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