Merge branch 'mbedtls-2.1' into mbedtls-2.1-restricted

* mbedtls-2.1:
  selftest: fix build error in some configurations
  Timing self test: shorten redundant tests
  Timing self test: increased duration
  Timing self test: increased tolerance
  selftest: allow excluding a subset of the tests
  selftest: allow running a subset of the tests
  selftest: fixed an erroneous return code
  selftest: refactor to separate the list of tests from the logic
  Timing self test: print some diagnosis information
  mbedtls_timing_get_timer: don't use uninitialized memory
  timing interface documentation: minor clarifications
  Timing: fix mbedtls_set_alarm(0) on Unix/POSIX
This commit is contained in:
Manuel Pégourié-Gonnard 2017-12-26 10:43:51 +01:00
commit c313e7e679
4 changed files with 294 additions and 217 deletions

View file

@ -39,6 +39,13 @@ Security
remote code execution. This can be triggered remotely from either remote code execution. This can be triggered remotely from either
side in both TLS and DTLS. side in both TLS and DTLS.
Features
* Allow comments in test data files.
* The selftest program can execute a subset of the tests based on command
line arguments.
* Improve the timing self-tests to be more robust when run on a
heavily-loaded machine.
Bugfix Bugfix
* Fix some invalid RSA-PSS signatures with keys of size 8N+1 that were * Fix some invalid RSA-PSS signatures with keys of size 8N+1 that were
accepted. Generating these signatures required the private key. accepted. Generating these signatures required the private key.
@ -81,15 +88,14 @@ Bugfix
fragile yet non-exploitable code-paths. fragile yet non-exploitable code-paths.
* Fix crash when calling mbedtls_ssl_cache_free() twice. Found by * Fix crash when calling mbedtls_ssl_cache_free() twice. Found by
MilenkoMitrovic, #1104 MilenkoMitrovic, #1104
* Fix mbedtls_timing_alarm(0) on Unix.
* Fix use of uninitialized memory in mbedtls_timing_get_timer when reset=1.
Changes Changes
* Extend cert_write example program by options to set the CRT version * Extend cert_write example program by options to set the CRT version
and the message digest. Further, allow enabling/disabling of authority and the message digest. Further, allow enabling/disabling of authority
identifier, subject identifier and basic constraints extensions. identifier, subject identifier and basic constraints extensions.
Features
* Allow comments in test data files.
= mbed TLS 2.1.9 branch released 2017-08-10 = mbed TLS 2.1.9 branch released 2017-08-10
Security Security

View file

@ -1,7 +1,7 @@
/** /**
* \file timing.h * \file timing.h
* *
* \brief Portable interface to the CPU cycle counter * \brief Portable interface to timeouts and to the CPU cycle counter
* *
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
@ -65,6 +65,9 @@ extern volatile int mbedtls_timing_alarmed;
* \warning This is only a best effort! Do not rely on this! * \warning This is only a best effort! Do not rely on this!
* In particular, it is known to be unreliable on virtual * In particular, it is known to be unreliable on virtual
* machines. * machines.
*
* \note This value starts at an unspecified origin and
* may wrap around.
*/ */
unsigned long mbedtls_timing_hardclock( void ); unsigned long mbedtls_timing_hardclock( void );
@ -72,7 +75,18 @@ unsigned long mbedtls_timing_hardclock( void );
* \brief Return the elapsed time in milliseconds * \brief Return the elapsed time in milliseconds
* *
* \param val points to a timer structure * \param val points to a timer structure
* \param reset if set to 1, the timer is restarted * \param reset If 0, query the elapsed time. Otherwise (re)start the timer.
*
* \return Elapsed time since the previous reset in ms. When
* restarting, this is always 0.
*
* \note To initialize a timer, call this function with reset=1.
*
* Determining the elapsed time and resetting the timer is not
* atomic on all platforms, so after the sequence
* `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
* get_timer(0) }` the value time1+time2 is only approximately
* the delay since the first reset.
*/ */
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
@ -80,6 +94,7 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int
* \brief Setup an alarm clock * \brief Setup an alarm clock
* *
* \param seconds delay before the "mbedtls_timing_alarmed" flag is set * \param seconds delay before the "mbedtls_timing_alarmed" flag is set
* (must be >=0)
* *
* \warning Only one alarm at a time is supported. In a threaded * \warning Only one alarm at a time is supported. In a threaded
* context, this means one for the whole process, not one per * context, this means one for the whole process, not one per
@ -91,11 +106,15 @@ void mbedtls_set_alarm( int seconds );
* \brief Set a pair of delays to watch * \brief Set a pair of delays to watch
* (See \c mbedtls_timing_get_delay().) * (See \c mbedtls_timing_get_delay().)
* *
* \param data Pointer to timing data * \param data Pointer to timing data.
* Must point to a valid \c mbedtls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* \param int_ms First (intermediate) delay in milliseconds. * \param int_ms First (intermediate) delay in milliseconds.
* The effect if int_ms > fin_ms is unspecified.
* \param fin_ms Second (final) delay in milliseconds. * \param fin_ms Second (final) delay in milliseconds.
* Pass 0 to cancel the current delay. * Pass 0 to cancel the current delay.
*
* \note To set a single delay, either use \c mbedtls_timing_set_timer
* directly or use this function with int_ms == fin_ms.
*/ */
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
@ -106,7 +125,7 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
* \param data Pointer to timing data * \param data Pointer to timing data
* Must point to a valid \c mbedtls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* *
* \return -1 if cancelled (fin_ms = 0) * \return -1 if cancelled (fin_ms = 0),
* 0 if none of the delays are passed, * 0 if none of the delays are passed,
* 1 if only the intermediate delay is passed, * 1 if only the intermediate delay is passed,
* 2 if the final delay is passed. * 2 if the final delay is passed.

View file

@ -239,22 +239,24 @@ volatile int mbedtls_timing_alarmed = 0;
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
{ {
unsigned long delta;
LARGE_INTEGER offset, hfreq;
struct _hr_time *t = (struct _hr_time *) val; struct _hr_time *t = (struct _hr_time *) val;
QueryPerformanceCounter( &offset );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( 1000 *
( offset.QuadPart - t->start.QuadPart ) ) /
hfreq.QuadPart );
if( reset ) if( reset )
{
QueryPerformanceCounter( &t->start ); QueryPerformanceCounter( &t->start );
return( 0 );
}
else
{
unsigned long delta;
LARGE_INTEGER now, hfreq;
QueryPerformanceCounter( &now );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul
/ hfreq.QuadPart );
return( delta ); return( delta );
} }
}
/* It's OK to use a global because alarm() is supposed to be global anyway */ /* It's OK to use a global because alarm() is supposed to be global anyway */
static DWORD alarmMs; static DWORD alarmMs;
@ -280,24 +282,23 @@ void mbedtls_set_alarm( int seconds )
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
{ {
unsigned long delta;
struct timeval offset;
struct _hr_time *t = (struct _hr_time *) val; struct _hr_time *t = (struct _hr_time *) val;
gettimeofday( &offset, NULL );
if( reset ) if( reset )
{ {
t->start.tv_sec = offset.tv_sec; gettimeofday( &t->start, NULL );
t->start.tv_usec = offset.tv_usec;
return( 0 ); return( 0 );
} }
else
delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 {
+ ( offset.tv_usec - t->start.tv_usec ) / 1000; unsigned long delta;
struct timeval now;
gettimeofday( &now, NULL );
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul
+ ( now.tv_usec - t->start.tv_usec ) / 1000;
return( delta ); return( delta );
} }
}
static void sighandler( int signum ) static void sighandler( int signum )
{ {
@ -310,6 +311,12 @@ void mbedtls_set_alarm( int seconds )
mbedtls_timing_alarmed = 0; mbedtls_timing_alarmed = 0;
signal( SIGALRM, sighandler ); signal( SIGALRM, sighandler );
alarm( seconds ); alarm( seconds );
if( seconds == 0 )
{
/* alarm(0) cancelled any previous pending alarm, but the
handler won't fire, so raise the flag straight away. */
mbedtls_timing_alarmed = 1;
}
} }
#endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* _WIN32 && !EFIX64 && !EFI32 */
@ -376,8 +383,16 @@ static void busy_msleep( unsigned long msec )
#define FAIL do \ #define FAIL do \
{ \ { \
if( verbose != 0 ) \ if( verbose != 0 ) \
mbedtls_printf( "failed\n" ); \ { \
\ mbedtls_printf( "failed at line %d\n", __LINE__ ); \
mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
cycles, ratio, millisecs, secs, hardfail, \
(unsigned long) a, (unsigned long) b ); \
mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \
mbedtls_timing_get_timer( &hires, 0 ), \
mbedtls_timing_get_timer( &ctx.timer, 0 ), \
mbedtls_timing_get_delay( &ctx ) ); \
} \
return( 1 ); \ return( 1 ); \
} while( 0 ) } while( 0 )
@ -389,22 +404,21 @@ static void busy_msleep( unsigned long msec )
*/ */
int mbedtls_timing_self_test( int verbose ) int mbedtls_timing_self_test( int verbose )
{ {
unsigned long cycles, ratio; unsigned long cycles = 0, ratio = 0;
unsigned long millisecs, secs; unsigned long millisecs = 0, secs = 0;
int hardfail; int hardfail = 0;
struct mbedtls_timing_hr_time hires; struct mbedtls_timing_hr_time hires;
uint32_t a, b; uint32_t a = 0, b = 0;
mbedtls_timing_delay_context ctx; mbedtls_timing_delay_context ctx;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING tests note: will take some time!\n" ); mbedtls_printf( " TIMING tests note: will take some time!\n" );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " );
for( secs = 1; secs <= 3; secs++ )
{ {
secs = 1;
(void) mbedtls_timing_get_timer( &hires, 1 ); (void) mbedtls_timing_get_timer( &hires, 1 );
mbedtls_set_alarm( (int) secs ); mbedtls_set_alarm( (int) secs );
@ -416,12 +430,7 @@ int mbedtls_timing_self_test( int verbose )
/* For some reason on Windows it looks like alarm has an extra delay /* For some reason on Windows it looks like alarm has an extra delay
* (maybe related to creating a new thread). Allow some room here. */ * (maybe related to creating a new thread). Allow some room here. */
if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
{ FAIL;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
if( verbose != 0 ) if( verbose != 0 )
@ -430,29 +439,23 @@ int mbedtls_timing_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
for( a = 200; a <= 400; a += 200 )
{ {
for( b = 200; b <= 400; b += 200 ) a = 800;
{ b = 400;
mbedtls_timing_set_delay( &ctx, a, a + b ); mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */
busy_msleep( a - a / 8 ); busy_msleep( a - a / 4 ); /* T = a - a/4 */
if( mbedtls_timing_get_delay( &ctx ) != 0 ) if( mbedtls_timing_get_delay( &ctx ) != 0 )
FAIL; FAIL;
busy_msleep( a / 4 ); busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 ) if( mbedtls_timing_get_delay( &ctx ) != 1 )
FAIL; FAIL;
busy_msleep( b - a / 8 - b / 8 ); busy_msleep( b ); /* T = a + b + b/4 */
if( mbedtls_timing_get_delay( &ctx ) != 1 )
FAIL;
busy_msleep( b / 4 );
if( mbedtls_timing_get_delay( &ctx ) != 2 ) if( mbedtls_timing_get_delay( &ctx ) != 2 )
FAIL; FAIL;
} }
}
mbedtls_timing_set_delay( &ctx, 0, 0 ); mbedtls_timing_set_delay( &ctx, 0, 0 );
busy_msleep( 200 ); busy_msleep( 200 );
@ -470,7 +473,6 @@ int mbedtls_timing_self_test( int verbose )
* On a 4Ghz 32-bit machine the cycle counter wraps about once per second; * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
* since the whole test is about 10ms, it shouldn't happen twice in a row. * since the whole test is about 10ms, it shouldn't happen twice in a row.
*/ */
hardfail = 0;
hard_test: hard_test:
if( hardfail > 1 ) if( hardfail > 1 )

View file

@ -51,6 +51,7 @@
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#include "mbedtls/timing.h" #include "mbedtls/timing.h"
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -96,10 +97,123 @@ static int run_test_snprintf( void )
test_snprintf( 5, "123", 3 ) != 0 ); test_snprintf( 5, "123", 3 ) != 0 );
} }
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
int mbedtls_memory_buffer_alloc_free_and_self_test( int verbose )
{
if( verbose != 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_status( );
#endif
}
mbedtls_memory_buffer_alloc_free( );
return( mbedtls_memory_buffer_alloc_self_test( verbose ) );
}
#endif
typedef struct
{
const char *name;
int ( *function )( int );
} selftest_t;
const selftest_t selftests[] =
{
#if defined(MBEDTLS_MD2_C)
{"md2", mbedtls_md2_self_test},
#endif
#if defined(MBEDTLS_MD4_C)
{"md4", mbedtls_md4_self_test},
#endif
#if defined(MBEDTLS_MD5_C)
{"md5", mbedtls_md5_self_test},
#endif
#if defined(MBEDTLS_RIPEMD160_C)
{"ripemd160", mbedtls_ripemd160_self_test},
#endif
#if defined(MBEDTLS_SHA1_C)
{"sha1", mbedtls_sha1_self_test},
#endif
#if defined(MBEDTLS_SHA256_C)
{"sha256", mbedtls_sha256_self_test},
#endif
#if defined(MBEDTLS_SHA512_C)
{"sha512", mbedtls_sha512_self_test},
#endif
#if defined(MBEDTLS_ARC4_C)
{"arc4", mbedtls_arc4_self_test},
#endif
#if defined(MBEDTLS_DES_C)
{"des", mbedtls_des_self_test},
#endif
#if defined(MBEDTLS_AES_C)
{"aes", mbedtls_aes_self_test},
#endif
#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C)
{"gcm", mbedtls_gcm_self_test},
#endif
#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)
{"ccm", mbedtls_ccm_self_test},
#endif
#if defined(MBEDTLS_BASE64_C)
{"base64", mbedtls_base64_self_test},
#endif
#if defined(MBEDTLS_BIGNUM_C)
{"mpi", mbedtls_mpi_self_test},
#endif
#if defined(MBEDTLS_RSA_C)
{"rsa", mbedtls_rsa_self_test},
#endif
#if defined(MBEDTLS_X509_USE_C)
{"x509", mbedtls_x509_self_test},
#endif
#if defined(MBEDTLS_XTEA_C)
{"xtea", mbedtls_xtea_self_test},
#endif
#if defined(MBEDTLS_CAMELLIA_C)
{"camellia", mbedtls_camellia_self_test},
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
{"ctr_drbg", mbedtls_ctr_drbg_self_test},
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
{"hmac_drbg", mbedtls_hmac_drbg_self_test},
#endif
#if defined(MBEDTLS_ECP_C)
{"ecp", mbedtls_ecp_self_test},
#endif
#if defined(MBEDTLS_DHM_C)
{"dhm", mbedtls_dhm_self_test},
#endif
#if defined(MBEDTLS_ENTROPY_C)
{"entropy", mbedtls_entropy_self_test},
#endif
#if defined(MBEDTLS_PKCS5_C)
{"pkcs5", mbedtls_pkcs5_self_test},
#endif
/* Slower test after the faster ones */
#if defined(MBEDTLS_TIMING_C)
{"timing", mbedtls_timing_self_test},
#endif
/* Heap test comes last */
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
{"memory_buffer_alloc", mbedtls_memory_buffer_alloc_free_and_self_test},
#endif
{NULL, NULL}
};
#endif /* MBEDTLS_SELF_TEST */
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
int ret = 0, v; #if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) const selftest_t *test;
#endif /* MBEDTLS_SELF_TEST */
char **argp;
int v = 1; /* v=1 for verbose mode */
int exclude_mode = 0;
int suites_tested = 0, suites_failed = 0;
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_SELF_TEST)
unsigned char buf[1000000]; unsigned char buf[1000000];
#endif #endif
void *pointer; void *pointer;
@ -113,7 +227,7 @@ int main( int argc, char *argv[] )
if( pointer != NULL ) if( pointer != NULL )
{ {
mbedtls_printf( "all-bits-zero is not a NULL pointer\n" ); mbedtls_printf( "all-bits-zero is not a NULL pointer\n" );
return( 1 ); return( EXIT_FAILURE );
} }
/* /*
@ -122,16 +236,28 @@ int main( int argc, char *argv[] )
if( run_test_snprintf() != 0 ) if( run_test_snprintf() != 0 )
{ {
mbedtls_printf( "the snprintf implementation is broken\n" ); mbedtls_printf( "the snprintf implementation is broken\n" );
return( 0 ); return( EXIT_FAILURE );
} }
if( argc == 2 && strcmp( argv[1], "-quiet" ) == 0 ) for( argp = argv + ( argc >= 1 ? 1 : argc ); *argp != NULL; ++argp )
v = 0;
else
{ {
v = 1; if( strcmp( *argp, "--quiet" ) == 0 ||
mbedtls_printf( "\n" ); strcmp( *argp, "-quiet" ) == 0 ||
strcmp( *argp, "-q" ) == 0 )
{
v = 0;
} }
else if( strcmp( *argp, "--exclude" ) == 0 ||
strcmp( *argp, "-x" ) == 0 )
{
exclude_mode = 1;
}
else
break;
}
if( v != 0 )
mbedtls_printf( "\n" );
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
@ -139,159 +265,83 @@ int main( int argc, char *argv[] )
mbedtls_memory_buffer_alloc_init( buf, sizeof(buf) ); mbedtls_memory_buffer_alloc_init( buf, sizeof(buf) );
#endif #endif
#if defined(MBEDTLS_MD2_C) if( *argp != NULL && exclude_mode == 0 )
if( ( ret = mbedtls_md2_self_test( v ) ) != 0 ) {
return( ret ); /* Run the specified tests */
#endif for( ; *argp != NULL; argp++ )
{
#if defined(MBEDTLS_MD4_C) for( test = selftests; test->name != NULL; test++ )
if( ( ret = mbedtls_md4_self_test( v ) ) != 0 ) {
return( ret ); if( !strcmp( *argp, test->name ) )
#endif {
if( test->function( v ) != 0 )
#if defined(MBEDTLS_MD5_C) {
if( ( ret = mbedtls_md5_self_test( v ) ) != 0 ) suites_failed++;
return( ret ); }
#endif suites_tested++;
break;
#if defined(MBEDTLS_RIPEMD160_C) }
if( ( ret = mbedtls_ripemd160_self_test( v ) ) != 0 ) }
return( ret ); if( test->name == NULL )
#endif {
mbedtls_printf( " Test suite %s not available -> failed\n\n", *argp );
#if defined(MBEDTLS_SHA1_C) suites_failed++;
if( ( ret = mbedtls_sha1_self_test( v ) ) != 0 ) }
return( ret ); }
#endif }
else
#if defined(MBEDTLS_SHA256_C) {
if( ( ret = mbedtls_sha256_self_test( v ) ) != 0 ) /* Run all the tests except excluded ones */
return( ret ); for( test = selftests; test->name != NULL; test++ )
#endif {
if( exclude_mode )
#if defined(MBEDTLS_SHA512_C) {
if( ( ret = mbedtls_sha512_self_test( v ) ) != 0 ) char **excluded;
return( ret ); for( excluded = argp; *excluded != NULL; ++excluded )
#endif {
if( !strcmp( *excluded, test->name ) )
#if defined(MBEDTLS_ARC4_C) break;
if( ( ret = mbedtls_arc4_self_test( v ) ) != 0 ) }
return( ret ); if( *excluded )
#endif {
if( v )
#if defined(MBEDTLS_DES_C) mbedtls_printf( " Skip: %s\n", test->name );
if( ( ret = mbedtls_des_self_test( v ) ) != 0 ) continue;
return( ret ); }
#endif }
if( test->function( v ) != 0 )
#if defined(MBEDTLS_AES_C) {
if( ( ret = mbedtls_aes_self_test( v ) ) != 0 ) suites_failed++;
return( ret ); }
#endif suites_tested++;
}
#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C) }
if( ( ret = mbedtls_gcm_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)
if( ( ret = mbedtls_ccm_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_BASE64_C)
if( ( ret = mbedtls_base64_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_BIGNUM_C)
if( ( ret = mbedtls_mpi_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_RSA_C)
if( ( ret = mbedtls_rsa_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_X509_USE_C)
if( ( ret = mbedtls_x509_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_XTEA_C)
if( ( ret = mbedtls_xtea_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_CAMELLIA_C)
if( ( ret = mbedtls_camellia_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_CTR_DRBG_C)
if( ( ret = mbedtls_ctr_drbg_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
if( ( ret = mbedtls_hmac_drbg_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_ECP_C)
if( ( ret = mbedtls_ecp_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_DHM_C)
if( ( ret = mbedtls_dhm_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_ENTROPY_C)
if( ( ret = mbedtls_entropy_self_test( v ) ) != 0 )
return( ret );
#endif
#if defined(MBEDTLS_PKCS5_C)
if( ( ret = mbedtls_pkcs5_self_test( v ) ) != 0 )
return( ret );
#endif
/* Slow tests last */
#if defined(MBEDTLS_TIMING_C)
if( ( ret = mbedtls_timing_self_test( v ) ) != 0 )
return( ret );
#endif
#else #else
(void) exclude_mode;
mbedtls_printf( " MBEDTLS_SELF_TEST not defined.\n" ); mbedtls_printf( " MBEDTLS_SELF_TEST not defined.\n" );
#endif #endif
if( v != 0 ) if( v != 0 )
{ {
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG) mbedtls_printf( " Executed %d test suites\n\n", suites_tested );
mbedtls_memory_buffer_alloc_status();
#endif if( suites_failed > 0)
{
mbedtls_printf( " [ %d tests FAILED ]\n\n", suites_failed );
} }
else
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_free();
if( ( ret = mbedtls_memory_buffer_alloc_self_test( v ) ) != 0 )
return( ret );
#endif
if( v != 0 )
{ {
mbedtls_printf( " [ All tests passed ]\n\n" ); mbedtls_printf( " [ All tests passed ]\n\n" );
}
#if defined(_WIN32) #if defined(_WIN32)
mbedtls_printf( " Press Enter to exit this program.\n" ); mbedtls_printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar(); fflush( stdout ); getchar();
#endif #endif
} }
return( ret ); if( suites_failed > 0)
return( EXIT_FAILURE );
return( EXIT_SUCCESS );
} }