mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hmac_drbg.c Source File

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     return( ret );
00368 }
00369 
00370 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
00371 {
00372     FILE *f;
00373     size_t n;
00374     unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
00375 
00376     if( ( f = fopen( path, "rb" ) ) == NULL )
00377         return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
00378 
00379     fseek( f, 0, SEEK_END );
00380     n = (size_t) ftell( f );
00381     fseek( f, 0, SEEK_SET );
00382 
00383     if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
00384     {
00385         fclose( f );
00386         return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
00387     }
00388 
00389     if( fread( buf, 1, n, f ) != n )
00390     {
00391         fclose( f );
00392         return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
00393     }
00394 
00395     fclose( f );
00396 
00397     mbedtls_hmac_drbg_update( ctx, buf, n );
00398 
00399     return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
00400 }
00401 #endif /* MBEDTLS_FS_IO */
00402 
00403 
00404 #if defined(MBEDTLS_SELF_TEST)
00405 
00406 #if !defined(MBEDTLS_SHA1_C)
00407 /* Dummy checkup routine */
00408 int mbedtls_hmac_drbg_self_test( int verbose )
00409 {
00410     (void) verbose;
00411     return( 0 );
00412 }
00413 #else
00414 
00415 #define OUTPUT_LEN  80
00416 
00417 /* From a NIST PR=true test vector */
00418 static const unsigned char entropy_pr[] = {
00419     0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
00420     0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
00421     0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
00422     0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
00423     0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
00424 static const unsigned char result_pr[OUTPUT_LEN] = {
00425     0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
00426     0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
00427     0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
00428     0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
00429     0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
00430     0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
00431     0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
00432 
00433 /* From a NIST PR=false test vector */
00434 static const unsigned char entropy_nopr[] = {
00435     0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
00436     0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
00437     0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
00438     0xe9, 0x9d, 0xfe, 0xdf };
00439 static const unsigned char result_nopr[OUTPUT_LEN] = {
00440     0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
00441     0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
00442     0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
00443     0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
00444     0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
00445     0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
00446     0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
00447 
00448 /* "Entropy" from buffer */
00449 static size_t test_offset;
00450 static int hmac_drbg_self_test_entropy( void *data,
00451                                         unsigned char *buf, size_t len )
00452 {
00453     const unsigned char *p = data;
00454     memcpy( buf, p + test_offset, len );
00455     test_offset += len;
00456     return( 0 );
00457 }
00458 
00459 #define CHK( c )    if( (c) != 0 )                          \
00460                     {                                       \
00461                         if( verbose != 0 )                  \
00462                             mbedtls_printf( "failed\n" );  \
00463                         return( 1 );                        \
00464                     }
00465 
00466 /*
00467  * Checkup routine for HMAC_DRBG with SHA-1
00468  */
00469 int mbedtls_hmac_drbg_self_test( int verbose )
00470 {
00471     mbedtls_hmac_drbg_context ctx;
00472     unsigned char buf[OUTPUT_LEN];
00473     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
00474 
00475     mbedtls_hmac_drbg_init( &ctx );
00476 
00477     /*
00478      * PR = True
00479      */
00480     if( verbose != 0 )
00481         mbedtls_printf( "  HMAC_DRBG (PR = True) : " );
00482 
00483     test_offset = 0;
00484     CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
00485                          hmac_drbg_self_test_entropy, (void *) entropy_pr,
00486                          NULL, 0 ) );
00487     mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
00488     CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
00489     CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
00490     CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
00491     mbedtls_hmac_drbg_free( &ctx );
00492 
00493     mbedtls_hmac_drbg_free( &ctx );
00494 
00495     if( verbose != 0 )
00496         mbedtls_printf( "passed\n" );
00497 
00498     /*
00499      * PR = False
00500      */
00501     if( verbose != 0 )
00502         mbedtls_printf( "  HMAC_DRBG (PR = False) : " );
00503 
00504     mbedtls_hmac_drbg_init( &ctx );
00505 
00506     test_offset = 0;
00507     CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
00508                          hmac_drbg_self_test_entropy, (void *) entropy_nopr,
00509                          NULL, 0 ) );
00510     CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
00511     CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
00512     CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
00513     CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
00514     mbedtls_hmac_drbg_free( &ctx );
00515 
00516     mbedtls_hmac_drbg_free( &ctx );
00517 
00518     if( verbose != 0 )
00519         mbedtls_printf( "passed\n" );
00520 
00521     if( verbose != 0 )
00522         mbedtls_printf( "\n" );
00523 
00524     return( 0 );
00525 }
00526 #endif /* MBEDTLS_SHA1_C */
00527 #endif /* MBEDTLS_SELF_TEST */
00528 
00529 #endif /* MBEDTLS_HMAC_DRBG_C */