Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
hmac_drbg.c
00001 /* 00002 * HMAC_DRBG implementation (NIST SP 800-90) 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 /* 00023 * The NIST SP 800-90A DRBGs are described in the following publication. 00024 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf 00025 * References below are based on rev. 1 (January 2012). 00026 */ 00027 00028 #if !defined(MBEDTLS_CONFIG_FILE) 00029 #include "mbedtls/config.h" 00030 #else 00031 #include MBEDTLS_CONFIG_FILE 00032 #endif 00033 00034 #if defined(MBEDTLS_HMAC_DRBG_C) 00035 00036 #include "mbedtls/hmac_drbg.h" 00037 #include "mbedtls/platform_util.h" 00038 00039 #include <string.h> 00040 00041 #if defined(MBEDTLS_FS_IO) 00042 #include <stdio.h> 00043 #endif 00044 00045 #if defined(MBEDTLS_SELF_TEST) 00046 #if defined(MBEDTLS_PLATFORM_C) 00047 #include "mbedtls/platform.h" 00048 #else 00049 #include <stdio.h> 00050 #define mbedtls_printf printf 00051 #endif /* MBEDTLS_SELF_TEST */ 00052 #endif /* MBEDTLS_PLATFORM_C */ 00053 00054 /* 00055 * HMAC_DRBG context initialization 00056 */ 00057 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) 00058 { 00059 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); 00060 00061 #if defined(MBEDTLS_THREADING_C) 00062 mbedtls_mutex_init( &ctx->mutex ); 00063 #endif 00064 } 00065 00066 /* 00067 * HMAC_DRBG update, using optional additional data (10.1.2.2) 00068 */ 00069 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, 00070 const unsigned char *additional, 00071 size_t add_len ) 00072 { 00073 size_t md_len = mbedtls_md_get_size( ctx->md_ctx .md_info ); 00074 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; 00075 unsigned char sep[1]; 00076 unsigned char K[MBEDTLS_MD_MAX_SIZE]; 00077 int ret; 00078 00079 for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) 00080 { 00081 /* Step 1 or 4 */ 00082 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) 00083 goto exit; 00084 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx , 00085 ctx->V , md_len ) ) != 0 ) 00086 goto exit; 00087 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx , 00088 sep, 1 ) ) != 0 ) 00089 goto exit; 00090 if( rounds == 2 ) 00091 { 00092 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx , 00093 additional, add_len ) ) != 0 ) 00094 goto exit; 00095 } 00096 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx , K ) ) != 0 ) 00097 goto exit; 00098 00099 /* Step 2 or 5 */ 00100 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx , K, md_len ) ) != 0 ) 00101 goto exit; 00102 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx , 00103 ctx->V , md_len ) ) != 0 ) 00104 goto exit; 00105 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx , ctx->V ) ) != 0 ) 00106 goto exit; 00107 } 00108 00109 exit: 00110 mbedtls_platform_zeroize( K, sizeof( K ) ); 00111 return( ret ); 00112 } 00113 00114 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00115 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, 00116 const unsigned char *additional, 00117 size_t add_len ) 00118 { 00119 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); 00120 } 00121 #endif /* MBEDTLS_DEPRECATED_REMOVED */ 00122 00123 /* 00124 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) 00125 */ 00126 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, 00127 const mbedtls_md_info_t * md_info, 00128 const unsigned char *data, size_t data_len ) 00129 { 00130 int ret; 00131 00132 if( ( ret = mbedtls_md_setup( &ctx->md_ctx , md_info, 1 ) ) != 0 ) 00133 return( ret ); 00134 00135 /* 00136 * Set initial working state. 00137 * Use the V memory location, which is currently all 0, to initialize the 00138 * MD context with an all-zero key. Then set V to its initial value. 00139 */ 00140 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx , ctx->V , 00141 mbedtls_md_get_size( md_info ) ) ) != 0 ) 00142 return( ret ); 00143 memset( ctx->V , 0x01, mbedtls_md_get_size( md_info ) ); 00144 00145 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) 00146 return( ret ); 00147 00148 return( 0 ); 00149 } 00150 00151 /* 00152 * Internal function used both for seeding and reseeding the DRBG. 00153 * Comments starting with arabic numbers refer to section 10.1.2.4 00154 * of SP800-90A, while roman numbers refer to section 9.2. 00155 */ 00156 static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx, 00157 const unsigned char *additional, size_t len, 00158 int use_nonce ) 00159 { 00160 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; 00161 size_t seedlen = 0; 00162 int ret; 00163 00164 { 00165 size_t total_entropy_len; 00166 00167 if( use_nonce == 0 ) 00168 total_entropy_len = ctx->entropy_len ; 00169 else 00170 total_entropy_len = ctx->entropy_len * 3 / 2; 00171 00172 /* III. Check input length */ 00173 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || 00174 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) 00175 { 00176 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 00177 } 00178 } 00179 00180 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); 00181 00182 /* IV. Gather entropy_len bytes of entropy for the seed */ 00183 if( ( ret = ctx->f_entropy ( ctx->p_entropy , 00184 seed, ctx->entropy_len ) ) != 0 ) 00185 { 00186 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); 00187 } 00188 seedlen += ctx->entropy_len ; 00189 00190 /* For initial seeding, allow adding of nonce generated 00191 * from the entropy source. See Sect 8.6.7 in SP800-90A. */ 00192 if( use_nonce ) 00193 { 00194 /* Note: We don't merge the two calls to f_entropy() in order 00195 * to avoid requesting too much entropy from f_entropy() 00196 * at once. Specifically, if the underlying digest is not 00197 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which 00198 * is larger than the maximum of 32 Bytes that our own 00199 * entropy source implementation can emit in a single 00200 * call in configurations disabling SHA-512. */ 00201 if( ( ret = ctx->f_entropy ( ctx->p_entropy , 00202 seed + seedlen, 00203 ctx->entropy_len / 2 ) ) != 0 ) 00204 { 00205 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); 00206 } 00207 00208 seedlen += ctx->entropy_len / 2; 00209 } 00210 00211 00212 /* 1. Concatenate entropy and additional data if any */ 00213 if( additional != NULL && len != 0 ) 00214 { 00215 memcpy( seed + seedlen, additional, len ); 00216 seedlen += len; 00217 } 00218 00219 /* 2. Update state */ 00220 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) 00221 goto exit; 00222 00223 /* 3. Reset reseed_counter */ 00224 ctx->reseed_counter = 1; 00225 00226 exit: 00227 /* 4. Done */ 00228 mbedtls_platform_zeroize( seed, seedlen ); 00229 return( ret ); 00230 } 00231 00232 /* 00233 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2 00234 */ 00235 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, 00236 const unsigned char *additional, size_t len ) 00237 { 00238 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) ); 00239 } 00240 00241 /* 00242 * HMAC_DRBG initialisation (10.1.2.3 + 9.1) 00243 * 00244 * The nonce is not passed as a separate parameter but extracted 00245 * from the entropy source as suggested in 8.6.7. 00246 */ 00247 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, 00248 const mbedtls_md_info_t * md_info, 00249 int (*f_entropy)(void *, unsigned char *, size_t), 00250 void *p_entropy, 00251 const unsigned char *custom, 00252 size_t len ) 00253 { 00254 int ret; 00255 size_t md_size; 00256 00257 if( ( ret = mbedtls_md_setup( &ctx->md_ctx , md_info, 1 ) ) != 0 ) 00258 return( ret ); 00259 00260 md_size = mbedtls_md_get_size( md_info ); 00261 00262 /* 00263 * Set initial working state. 00264 * Use the V memory location, which is currently all 0, to initialize the 00265 * MD context with an all-zero key. Then set V to its initial value. 00266 */ 00267 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx , ctx->V , md_size ) ) != 0 ) 00268 return( ret ); 00269 memset( ctx->V , 0x01, md_size ); 00270 00271 ctx->f_entropy = f_entropy; 00272 ctx->p_entropy = p_entropy; 00273 00274 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; 00275 00276 /* 00277 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by 00278 * each hash function, then according to SP800-90A rev1 10.1 table 2, 00279 * min_entropy_len (in bits) is security_strength. 00280 * 00281 * (This also matches the sizes used in the NIST test vectors.) 00282 */ 00283 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ 00284 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ 00285 32; /* better (256+) -> 256 bits */ 00286 00287 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, 00288 1 /* add nonce */ ) ) != 0 ) 00289 { 00290 return( ret ); 00291 } 00292 00293 return( 0 ); 00294 } 00295 00296 /* 00297 * Set prediction resistance 00298 */ 00299 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, 00300 int resistance ) 00301 { 00302 ctx->prediction_resistance = resistance; 00303 } 00304 00305 /* 00306 * Set entropy length grabbed for reseeds 00307 */ 00308 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) 00309 { 00310 ctx->entropy_len = len; 00311 } 00312 00313 /* 00314 * Set reseed interval 00315 */ 00316 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) 00317 { 00318 ctx->reseed_interval = interval; 00319 } 00320 00321 /* 00322 * HMAC_DRBG random function with optional additional data: 00323 * 10.1.2.5 (arabic) + 9.3 (Roman) 00324 */ 00325 int mbedtls_hmac_drbg_random_with_add( void *p_rng, 00326 unsigned char *output, size_t out_len, 00327 const unsigned char *additional, size_t add_len ) 00328 { 00329 int ret; 00330 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 00331 size_t md_len = mbedtls_md_get_size( ctx->md_ctx .md_info ); 00332 size_t left = out_len; 00333 unsigned char *out = output; 00334 00335 /* II. Check request length */ 00336 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) 00337 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); 00338 00339 /* III. Check input length */ 00340 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) 00341 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 00342 00343 /* 1. (aka VII and IX) Check reseed counter and PR */ 00344 if( ctx->f_entropy != NULL && /* For no-reseeding instances */ 00345 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || 00346 ctx->reseed_counter > ctx->reseed_interval ) ) 00347 { 00348 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) 00349 return( ret ); 00350 00351 add_len = 0; /* VII.4 */ 00352 } 00353 00354 /* 2. Use additional data if any */ 00355 if( additional != NULL && add_len != 0 ) 00356 { 00357 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, 00358 additional, add_len ) ) != 0 ) 00359 goto exit; 00360 } 00361 00362 /* 3, 4, 5. Generate bytes */ 00363 while( left != 0 ) 00364 { 00365 size_t use_len = left > md_len ? md_len : left; 00366 00367 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) 00368 goto exit; 00369 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx , 00370 ctx->V , md_len ) ) != 0 ) 00371 goto exit; 00372 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx , ctx->V ) ) != 0 ) 00373 goto exit; 00374 00375 memcpy( out, ctx->V , use_len ); 00376 out += use_len; 00377 left -= use_len; 00378 } 00379 00380 /* 6. Update */ 00381 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, 00382 additional, add_len ) ) != 0 ) 00383 goto exit; 00384 00385 /* 7. Update reseed counter */ 00386 ctx->reseed_counter ++; 00387 00388 exit: 00389 /* 8. Done */ 00390 return( ret ); 00391 } 00392 00393 /* 00394 * HMAC_DRBG random function 00395 */ 00396 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) 00397 { 00398 int ret; 00399 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 00400 00401 #if defined(MBEDTLS_THREADING_C) 00402 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00403 return( ret ); 00404 #endif 00405 00406 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); 00407 00408 #if defined(MBEDTLS_THREADING_C) 00409 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00410 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00411 #endif 00412 00413 return( ret ); 00414 } 00415 00416 /* 00417 * Free an HMAC_DRBG context 00418 */ 00419 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) 00420 { 00421 if( ctx == NULL ) 00422 return; 00423 00424 #if defined(MBEDTLS_THREADING_C) 00425 mbedtls_mutex_free( &ctx->mutex ); 00426 #endif 00427 mbedtls_md_free( &ctx->md_ctx ); 00428 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); 00429 } 00430 00431 #if defined(MBEDTLS_FS_IO) 00432 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 00433 { 00434 int ret; 00435 FILE *f; 00436 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 00437 00438 if( ( f = fopen( path, "wb" ) ) == NULL ) 00439 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 00440 00441 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) 00442 goto exit; 00443 00444 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) 00445 { 00446 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 00447 goto exit; 00448 } 00449 00450 ret = 0; 00451 00452 exit: 00453 fclose( f ); 00454 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 00455 00456 return( ret ); 00457 } 00458 00459 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 00460 { 00461 int ret = 0; 00462 FILE *f = NULL; 00463 size_t n; 00464 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 00465 unsigned char c; 00466 00467 if( ( f = fopen( path, "rb" ) ) == NULL ) 00468 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 00469 00470 n = fread( buf, 1, sizeof( buf ), f ); 00471 if( fread( &c, 1, 1, f ) != 0 ) 00472 { 00473 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; 00474 goto exit; 00475 } 00476 if( n == 0 || ferror( f ) ) 00477 { 00478 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 00479 goto exit; 00480 } 00481 fclose( f ); 00482 f = NULL; 00483 00484 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); 00485 00486 exit: 00487 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 00488 if( f != NULL ) 00489 fclose( f ); 00490 if( ret != 0 ) 00491 return( ret ); 00492 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); 00493 } 00494 #endif /* MBEDTLS_FS_IO */ 00495 00496 00497 #if defined(MBEDTLS_SELF_TEST) 00498 00499 #if !defined(MBEDTLS_SHA1_C) 00500 /* Dummy checkup routine */ 00501 int mbedtls_hmac_drbg_self_test( int verbose ) 00502 { 00503 (void) verbose; 00504 return( 0 ); 00505 } 00506 #else 00507 00508 #define OUTPUT_LEN 80 00509 00510 /* From a NIST PR=true test vector */ 00511 static const unsigned char entropy_pr[] = { 00512 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, 00513 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, 00514 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, 00515 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, 00516 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; 00517 static const unsigned char result_pr[OUTPUT_LEN] = { 00518 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, 00519 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, 00520 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, 00521 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, 00522 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, 00523 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, 00524 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; 00525 00526 /* From a NIST PR=false test vector */ 00527 static const unsigned char entropy_nopr[] = { 00528 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, 00529 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, 00530 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, 00531 0xe9, 0x9d, 0xfe, 0xdf }; 00532 static const unsigned char result_nopr[OUTPUT_LEN] = { 00533 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, 00534 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, 00535 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, 00536 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, 00537 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, 00538 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, 00539 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; 00540 00541 /* "Entropy" from buffer */ 00542 static size_t test_offset; 00543 static int hmac_drbg_self_test_entropy( void *data, 00544 unsigned char *buf, size_t len ) 00545 { 00546 const unsigned char *p = data; 00547 memcpy( buf, p + test_offset, len ); 00548 test_offset += len; 00549 return( 0 ); 00550 } 00551 00552 #define CHK( c ) if( (c) != 0 ) \ 00553 { \ 00554 if( verbose != 0 ) \ 00555 mbedtls_printf( "failed\n" ); \ 00556 return( 1 ); \ 00557 } 00558 00559 /* 00560 * Checkup routine for HMAC_DRBG with SHA-1 00561 */ 00562 int mbedtls_hmac_drbg_self_test( int verbose ) 00563 { 00564 mbedtls_hmac_drbg_context ctx; 00565 unsigned char buf[OUTPUT_LEN]; 00566 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 00567 00568 mbedtls_hmac_drbg_init( &ctx ); 00569 00570 /* 00571 * PR = True 00572 */ 00573 if( verbose != 0 ) 00574 mbedtls_printf( " HMAC_DRBG (PR = True) : " ); 00575 00576 test_offset = 0; 00577 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 00578 hmac_drbg_self_test_entropy, (void *) entropy_pr, 00579 NULL, 0 ) ); 00580 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); 00581 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00582 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00583 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); 00584 mbedtls_hmac_drbg_free( &ctx ); 00585 00586 mbedtls_hmac_drbg_free( &ctx ); 00587 00588 if( verbose != 0 ) 00589 mbedtls_printf( "passed\n" ); 00590 00591 /* 00592 * PR = False 00593 */ 00594 if( verbose != 0 ) 00595 mbedtls_printf( " HMAC_DRBG (PR = False) : " ); 00596 00597 mbedtls_hmac_drbg_init( &ctx ); 00598 00599 test_offset = 0; 00600 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 00601 hmac_drbg_self_test_entropy, (void *) entropy_nopr, 00602 NULL, 0 ) ); 00603 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); 00604 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00605 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00606 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); 00607 mbedtls_hmac_drbg_free( &ctx ); 00608 00609 mbedtls_hmac_drbg_free( &ctx ); 00610 00611 if( verbose != 0 ) 00612 mbedtls_printf( "passed\n" ); 00613 00614 if( verbose != 0 ) 00615 mbedtls_printf( "\n" ); 00616 00617 return( 0 ); 00618 } 00619 #endif /* MBEDTLS_SHA1_C */ 00620 #endif /* MBEDTLS_SELF_TEST */ 00621 00622 #endif /* MBEDTLS_HMAC_DRBG_C */
Generated on Tue Jul 12 2022 13:54:24 by
