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