Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport 1.3: More robust timing tests #1224

Merged
merged 4 commits into from
Dec 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Bugfix
* Fix word size check in in pk.c to not depend on MBEDTLS_HAVE_INT64.
* Fix crash when calling mbedtls_ssl_cache_free() twice. Found by
MilenkoMitrovic, #1104
* Fix mbedtls_timing_alarm(0) on Unix.
* Fix use of uninitialized memory in mbedtls_timing_get_timer when reset=1.

Changes
* Extend cert_write example program by options to set the CRT version
Expand Down
96 changes: 50 additions & 46 deletions library/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,21 +234,23 @@ volatile int alarmed = 0;

unsigned long get_timer( struct hr_time *val, int reset )
{
unsigned long delta;
LARGE_INTEGER offset, hfreq;
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 )
{
QueryPerformanceCounter( &t->start );

return( delta );
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 );
}
}

/* It's OK to use a global because alarm() is supposed to be global anyway */
Expand Down Expand Up @@ -280,23 +282,22 @@ void m_sleep( int milliseconds )

unsigned long get_timer( struct hr_time *val, int reset )
{
unsigned long delta;
struct timeval offset;
struct _hr_time *t = (struct _hr_time *) val;

gettimeofday( &offset, NULL );

if( reset )
{
t->start.tv_sec = offset.tv_sec;
t->start.tv_usec = offset.tv_usec;
gettimeofday( &t->start, NULL );
return( 0 );
}

delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
+ ( offset.tv_usec - t->start.tv_usec ) / 1000;

return( delta );
else
{
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 );
}
}

#if defined(INTEGRITY)
Expand All @@ -318,6 +319,12 @@ void set_alarm( int seconds )
alarmed = 0;
signal( SIGALRM, sighandler );
alarm( seconds );
if( seconds == 0 )
{
/* alarm(0) cancelled any previous pending alarm, but the
handler won't fire, so raise the flag straight away. */
alarmed = 1;
}
}

void m_sleep( int milliseconds )
Expand Down Expand Up @@ -359,6 +366,19 @@ static void busy_msleep( unsigned long msec )
(void) j;
}

#define FAIL do \
{ \
if( verbose != 0 ) \
{ \
polarssl_printf( "failed at line %d\n", __LINE__ ); \
polarssl_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d\n", \
cycles, ratio, millisecs, secs, hardfail ); \
polarssl_printf( " elapsed(hires)=%lu\n", \
get_timer( &hires, 0 ) ); \
} \
return( 1 ); \
} while( 0 )

/*
* Checkup routine
*
Expand All @@ -367,9 +387,9 @@ static void busy_msleep( unsigned long msec )
*/
int timing_self_test( int verbose )
{
unsigned long cycles, ratio;
unsigned long millisecs, secs;
int hardfail;
unsigned long cycles = 0, ratio = 0;
unsigned long millisecs = 0, secs = 0;
int hardfail = 0;
struct hr_time hires;

if( verbose != 0 )
Expand All @@ -378,21 +398,16 @@ int timing_self_test( int verbose )
if( verbose != 0 )
polarssl_printf( " TIMING test #1 (m_sleep / get_timer): " );

for( secs = 1; secs <= 3; secs++ )
{
secs = 1;
(void) get_timer( &hires, 1 );

m_sleep( (int)( 500 * secs ) );

millisecs = get_timer( &hires, 0 );

if( millisecs < 400 * secs || millisecs > 600 * secs )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );

return( 1 );
}
FAIL;
}

if( verbose != 0 )
Expand All @@ -401,8 +416,8 @@ int timing_self_test( int verbose )
if( verbose != 0 )
polarssl_printf( " TIMING test #2 (set_alarm / get_timer): " );

for( secs = 1; secs <= 3; secs++ )
{
secs = 1;
(void) get_timer( &hires, 1 );

set_alarm( (int) secs );
Expand All @@ -414,12 +429,7 @@ int timing_self_test( int verbose )
/* For some reason on Windows it looks like alarm has an extra delay
* (maybe related to creating a new thread). Allow some room here. */
if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );

return( 1 );
}
FAIL;
}

if( verbose != 0 )
Expand All @@ -433,7 +443,6 @@ int timing_self_test( int verbose )
* 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.
*/
hardfail = 0;

hard_test:
if( hardfail > 1 )
Expand Down Expand Up @@ -485,12 +494,7 @@ int timing_self_test( int verbose )
millisecs = get_timer( &hires, 0 );

if( millisecs < 400 * secs || millisecs > 600 * secs )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );

return( 1 );
}
FAIL;
}

if( verbose != 0 )
Expand Down