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.
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 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, 00070 const unsigned char *additional, size_t add_len ) 00071 { 00072 size_t md_len = mbedtls_md_get_size( ctx->md_ctx .md_info ); 00073 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; 00074 unsigned char sep[1]; 00075 unsigned char K[MBEDTLS_MD_MAX_SIZE]; 00076 00077 for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) 00078 { 00079 /* Step 1 or 4 */ 00080 mbedtls_md_hmac_reset( &ctx->md_ctx ); 00081 mbedtls_md_hmac_update( &ctx->md_ctx , ctx->V , md_len ); 00082 mbedtls_md_hmac_update( &ctx->md_ctx , sep, 1 ); 00083 if( rounds == 2 ) 00084 mbedtls_md_hmac_update( &ctx->md_ctx , additional, add_len ); 00085 mbedtls_md_hmac_finish( &ctx->md_ctx , K ); 00086 00087 /* Step 2 or 5 */ 00088 mbedtls_md_hmac_starts( &ctx->md_ctx , K, md_len ); 00089 mbedtls_md_hmac_update( &ctx->md_ctx , ctx->V , md_len ); 00090 mbedtls_md_hmac_finish( &ctx->md_ctx , ctx->V ); 00091 } 00092 } 00093 00094 /* 00095 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) 00096 */ 00097 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, 00098 const mbedtls_md_info_t * md_info, 00099 const unsigned char *data, size_t data_len ) 00100 { 00101 int ret; 00102 00103 if( ( ret = mbedtls_md_setup( &ctx->md_ctx , md_info, 1 ) ) != 0 ) 00104 return( ret ); 00105 00106 /* 00107 * Set initial working state. 00108 * Use the V memory location, which is currently all 0, to initialize the 00109 * MD context with an all-zero key. Then set V to its initial value. 00110 */ 00111 mbedtls_md_hmac_starts( &ctx->md_ctx , ctx->V , mbedtls_md_get_size( md_info ) ); 00112 memset( ctx->V , 0x01, mbedtls_md_get_size( md_info ) ); 00113 00114 mbedtls_hmac_drbg_update( ctx, data, data_len ); 00115 00116 return( 0 ); 00117 } 00118 00119 /* 00120 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) 00121 */ 00122 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, 00123 const unsigned char *additional, size_t len ) 00124 { 00125 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; 00126 size_t seedlen; 00127 00128 /* III. Check input length */ 00129 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || 00130 ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) 00131 { 00132 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 00133 } 00134 00135 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); 00136 00137 /* IV. Gather entropy_len bytes of entropy for the seed */ 00138 if( ctx->f_entropy ( ctx->p_entropy , seed, ctx->entropy_len ) != 0 ) 00139 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); 00140 00141 seedlen = ctx->entropy_len ; 00142 00143 /* 1. Concatenate entropy and additional data if any */ 00144 if( additional != NULL && len != 0 ) 00145 { 00146 memcpy( seed + seedlen, additional, len ); 00147 seedlen += len; 00148 } 00149 00150 /* 2. Update state */ 00151 mbedtls_hmac_drbg_update( ctx, seed, seedlen ); 00152 00153 /* 3. Reset reseed_counter */ 00154 ctx->reseed_counter = 1; 00155 00156 /* 4. Done */ 00157 return( 0 ); 00158 } 00159 00160 /* 00161 * HMAC_DRBG initialisation (10.1.2.3 + 9.1) 00162 */ 00163 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, 00164 const mbedtls_md_info_t * md_info, 00165 int (*f_entropy)(void *, unsigned char *, size_t), 00166 void *p_entropy, 00167 const unsigned char *custom, 00168 size_t len ) 00169 { 00170 int ret; 00171 size_t entropy_len, md_size; 00172 00173 if( ( ret = mbedtls_md_setup( &ctx->md_ctx , md_info, 1 ) ) != 0 ) 00174 return( ret ); 00175 00176 md_size = mbedtls_md_get_size( md_info ); 00177 00178 /* 00179 * Set initial working state. 00180 * Use the V memory location, which is currently all 0, to initialize the 00181 * MD context with an all-zero key. Then set V to its initial value. 00182 */ 00183 mbedtls_md_hmac_starts( &ctx->md_ctx , ctx->V , md_size ); 00184 memset( ctx->V , 0x01, md_size ); 00185 00186 ctx->f_entropy = f_entropy; 00187 ctx->p_entropy = p_entropy; 00188 00189 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; 00190 00191 /* 00192 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by 00193 * each hash function, then according to SP800-90A rev1 10.1 table 2, 00194 * min_entropy_len (in bits) is security_strength. 00195 * 00196 * (This also matches the sizes used in the NIST test vectors.) 00197 */ 00198 entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ 00199 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ 00200 32; /* better (256+) -> 256 bits */ 00201 00202 /* 00203 * For initialisation, use more entropy to emulate a nonce 00204 * (Again, matches test vectors.) 00205 */ 00206 ctx->entropy_len = entropy_len * 3 / 2; 00207 00208 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) 00209 return( ret ); 00210 00211 ctx->entropy_len = entropy_len; 00212 00213 return( 0 ); 00214 } 00215 00216 /* 00217 * Set prediction resistance 00218 */ 00219 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, 00220 int resistance ) 00221 { 00222 ctx->prediction_resistance = resistance; 00223 } 00224 00225 /* 00226 * Set entropy length grabbed for reseeds 00227 */ 00228 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) 00229 { 00230 ctx->entropy_len = len; 00231 } 00232 00233 /* 00234 * Set reseed interval 00235 */ 00236 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) 00237 { 00238 ctx->reseed_interval = interval; 00239 } 00240 00241 /* 00242 * HMAC_DRBG random function with optional additional data: 00243 * 10.1.2.5 (arabic) + 9.3 (Roman) 00244 */ 00245 int mbedtls_hmac_drbg_random_with_add( void *p_rng, 00246 unsigned char *output, size_t out_len, 00247 const unsigned char *additional, size_t add_len ) 00248 { 00249 int ret; 00250 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 00251 size_t md_len = mbedtls_md_get_size( ctx->md_ctx .md_info ); 00252 size_t left = out_len; 00253 unsigned char *out = output; 00254 00255 /* II. Check request length */ 00256 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) 00257 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); 00258 00259 /* III. Check input length */ 00260 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) 00261 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 00262 00263 /* 1. (aka VII and IX) Check reseed counter and PR */ 00264 if( ctx->f_entropy != NULL && /* For no-reseeding instances */ 00265 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || 00266 ctx->reseed_counter > ctx->reseed_interval ) ) 00267 { 00268 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) 00269 return( ret ); 00270 00271 add_len = 0; /* VII.4 */ 00272 } 00273 00274 /* 2. Use additional data if any */ 00275 if( additional != NULL && add_len != 0 ) 00276 mbedtls_hmac_drbg_update( ctx, additional, add_len ); 00277 00278 /* 3, 4, 5. Generate bytes */ 00279 while( left != 0 ) 00280 { 00281 size_t use_len = left > md_len ? md_len : left; 00282 00283 mbedtls_md_hmac_reset( &ctx->md_ctx ); 00284 mbedtls_md_hmac_update( &ctx->md_ctx , ctx->V , md_len ); 00285 mbedtls_md_hmac_finish( &ctx->md_ctx , ctx->V ); 00286 00287 memcpy( out, ctx->V , use_len ); 00288 out += use_len; 00289 left -= use_len; 00290 } 00291 00292 /* 6. Update */ 00293 mbedtls_hmac_drbg_update( ctx, additional, add_len ); 00294 00295 /* 7. Update reseed counter */ 00296 ctx->reseed_counter ++; 00297 00298 /* 8. Done */ 00299 return( 0 ); 00300 } 00301 00302 /* 00303 * HMAC_DRBG random function 00304 */ 00305 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) 00306 { 00307 int ret; 00308 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; 00309 00310 #if defined(MBEDTLS_THREADING_C) 00311 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00312 return( ret ); 00313 #endif 00314 00315 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); 00316 00317 #if defined(MBEDTLS_THREADING_C) 00318 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00319 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00320 #endif 00321 00322 return( ret ); 00323 } 00324 00325 /* 00326 * Free an HMAC_DRBG context 00327 */ 00328 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) 00329 { 00330 if( ctx == NULL ) 00331 return; 00332 00333 #if defined(MBEDTLS_THREADING_C) 00334 mbedtls_mutex_free( &ctx->mutex ); 00335 #endif 00336 mbedtls_md_free( &ctx->md_ctx ); 00337 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); 00338 } 00339 00340 #if defined(MBEDTLS_FS_IO) 00341 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 00342 { 00343 int ret; 00344 FILE *f; 00345 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 00346 00347 if( ( f = fopen( path, "wb" ) ) == NULL ) 00348 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 00349 00350 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) 00351 goto exit; 00352 00353 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) 00354 { 00355 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 00356 goto exit; 00357 } 00358 00359 ret = 0; 00360 00361 exit: 00362 fclose( f ); 00363 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 00364 00365 return( ret ); 00366 } 00367 00368 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) 00369 { 00370 int ret = 0; 00371 FILE *f; 00372 size_t n; 00373 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; 00374 00375 if( ( f = fopen( path, "rb" ) ) == NULL ) 00376 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); 00377 00378 fseek( f, 0, SEEK_END ); 00379 n = (size_t) ftell( f ); 00380 fseek( f, 0, SEEK_SET ); 00381 00382 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT ) 00383 { 00384 fclose( f ); 00385 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); 00386 } 00387 00388 if( fread( buf, 1, n, f ) != n ) 00389 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; 00390 else 00391 mbedtls_hmac_drbg_update( ctx, buf, n ); 00392 00393 fclose( f ); 00394 00395 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 00396 00397 if( ret != 0 ) 00398 return( ret ); 00399 00400 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); 00401 } 00402 #endif /* MBEDTLS_FS_IO */ 00403 00404 00405 #if defined(MBEDTLS_SELF_TEST) 00406 00407 #if !defined(MBEDTLS_SHA1_C) 00408 /* Dummy checkup routine */ 00409 int mbedtls_hmac_drbg_self_test( int verbose ) 00410 { 00411 (void) verbose; 00412 return( 0 ); 00413 } 00414 #else 00415 00416 #define OUTPUT_LEN 80 00417 00418 /* From a NIST PR=true test vector */ 00419 static const unsigned char entropy_pr[] = { 00420 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, 00421 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, 00422 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, 00423 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, 00424 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; 00425 static const unsigned char result_pr[OUTPUT_LEN] = { 00426 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, 00427 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, 00428 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, 00429 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, 00430 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, 00431 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, 00432 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; 00433 00434 /* From a NIST PR=false test vector */ 00435 static const unsigned char entropy_nopr[] = { 00436 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, 00437 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, 00438 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, 00439 0xe9, 0x9d, 0xfe, 0xdf }; 00440 static const unsigned char result_nopr[OUTPUT_LEN] = { 00441 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, 00442 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, 00443 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, 00444 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, 00445 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, 00446 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, 00447 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; 00448 00449 /* "Entropy" from buffer */ 00450 static size_t test_offset; 00451 static int hmac_drbg_self_test_entropy( void *data, 00452 unsigned char *buf, size_t len ) 00453 { 00454 const unsigned char *p = data; 00455 memcpy( buf, p + test_offset, len ); 00456 test_offset += len; 00457 return( 0 ); 00458 } 00459 00460 #define CHK( c ) if( (c) != 0 ) \ 00461 { \ 00462 if( verbose != 0 ) \ 00463 mbedtls_printf( "failed\n" ); \ 00464 return( 1 ); \ 00465 } 00466 00467 /* 00468 * Checkup routine for HMAC_DRBG with SHA-1 00469 */ 00470 int mbedtls_hmac_drbg_self_test( int verbose ) 00471 { 00472 mbedtls_hmac_drbg_context ctx; 00473 unsigned char buf[OUTPUT_LEN]; 00474 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 00475 00476 mbedtls_hmac_drbg_init( &ctx ); 00477 00478 /* 00479 * PR = True 00480 */ 00481 if( verbose != 0 ) 00482 mbedtls_printf( " HMAC_DRBG (PR = True) : " ); 00483 00484 test_offset = 0; 00485 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 00486 hmac_drbg_self_test_entropy, (void *) entropy_pr, 00487 NULL, 0 ) ); 00488 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); 00489 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00490 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00491 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); 00492 mbedtls_hmac_drbg_free( &ctx ); 00493 00494 mbedtls_hmac_drbg_free( &ctx ); 00495 00496 if( verbose != 0 ) 00497 mbedtls_printf( "passed\n" ); 00498 00499 /* 00500 * PR = False 00501 */ 00502 if( verbose != 0 ) 00503 mbedtls_printf( " HMAC_DRBG (PR = False) : " ); 00504 00505 mbedtls_hmac_drbg_init( &ctx ); 00506 00507 test_offset = 0; 00508 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 00509 hmac_drbg_self_test_entropy, (void *) entropy_nopr, 00510 NULL, 0 ) ); 00511 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); 00512 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00513 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); 00514 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); 00515 mbedtls_hmac_drbg_free( &ctx ); 00516 00517 mbedtls_hmac_drbg_free( &ctx ); 00518 00519 if( verbose != 0 ) 00520 mbedtls_printf( "passed\n" ); 00521 00522 if( verbose != 0 ) 00523 mbedtls_printf( "\n" ); 00524 00525 return( 0 ); 00526 } 00527 #endif /* MBEDTLS_SHA1_C */ 00528 #endif /* MBEDTLS_SELF_TEST */ 00529 00530 #endif /* MBEDTLS_HMAC_DRBG_C */
Generated on Tue Jul 12 2022 13:53:13 by
1.7.2