Make the hardclock test optional
Known to fail on VMs (such as the buildbots), see eg
http://blog.badtrace.com/post/rdtsc-x86-instruction-to-detect-vms/
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index 6598c1a..75b6734 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -62,6 +62,10 @@
/**
* \brief Return the CPU cycle counter value
+ *
+ * \warning This is only a best effort! Do not rely on this!
+ * In particular, it is known to be unreliable on virtual
+ * machines.
*/
unsigned long mbedtls_timing_hardclock( void );
diff --git a/library/timing.c b/library/timing.c
index 96e3b6a..5a36fb7 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -427,52 +427,7 @@
mbedtls_printf( "passed\n" );
if( verbose != 0 )
- mbedtls_printf( " TIMING test #2 (hardclock / get_timer): " );
-
- /*
- * Allow one failure for possible counter wrapping.
- * 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 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
-
- return( 1 );
- }
-
- /* Get a reference ratio cycles/ms */
- millisecs = 1;
- cycles = mbedtls_timing_hardclock();
- busy_msleep( millisecs );
- cycles = mbedtls_timing_hardclock() - cycles;
- ratio = cycles / millisecs;
-
- /* Check that the ratio is mostly constant */
- for( millisecs = 2; millisecs <= 4; millisecs++ )
- {
- cycles = mbedtls_timing_hardclock();
- busy_msleep( millisecs );
- cycles = mbedtls_timing_hardclock() - cycles;
-
- /* Allow variation up to 20% */
- if( cycles / millisecs < ratio - ratio / 5 ||
- cycles / millisecs > ratio + ratio / 5 )
- {
- hardfail++;
- goto hard_test;
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-
- if( verbose != 0 )
- mbedtls_printf( " TIMING test #3 (set/get_delay ): " );
+ mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
for( a = 100; a <= 200; a += 100 )
{
@@ -507,6 +462,53 @@
mbedtls_printf( "passed\n" );
if( verbose != 0 )
+ mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " );
+
+ /*
+ * Allow one failure for possible counter wrapping.
+ * 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 )
+ {
+ if( verbose != 0 )
+ mbedtls_printf( "failed (ignored)\n" );
+
+ goto hard_test_done;
+ }
+
+ /* Get a reference ratio cycles/ms */
+ millisecs = 1;
+ cycles = mbedtls_timing_hardclock();
+ busy_msleep( millisecs );
+ cycles = mbedtls_timing_hardclock() - cycles;
+ ratio = cycles / millisecs;
+
+ /* Check that the ratio is mostly constant */
+ for( millisecs = 2; millisecs <= 4; millisecs++ )
+ {
+ cycles = mbedtls_timing_hardclock();
+ busy_msleep( millisecs );
+ cycles = mbedtls_timing_hardclock() - cycles;
+
+ /* Allow variation up to 20% */
+ if( cycles / millisecs < ratio - ratio / 5 ||
+ cycles / millisecs > ratio + ratio / 5 )
+ {
+ hardfail++;
+ goto hard_test;
+ }
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+hard_test_done:
+
+ if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );