From d854083773d802d117aeaaa8e69aeee699e58dae Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Thu, 10 Jun 2021 15:16:50 +0200 Subject: [PATCH 1/7] Move part of timing module out of the library Signed-off-by: TRodziewicz --- include/mbedtls/config.h | 4 +- include/mbedtls/timing.h | 35 +- library/entropy.c | 5 - library/entropy_poll.c | 18 - library/entropy_poll.h | 9 - library/timing.c | 368 ------------------ programs/test/benchmark.c | 247 ++++++++++++ programs/test/selftest.c | 4 - .../test_suite_psa_crypto_init.function | 6 - tests/suites/test_suite_timing.data | 9 - tests/suites/test_suite_timing.function | 26 -- 11 files changed, 251 insertions(+), 480 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 16f8f8b350..1626efb085 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -268,7 +268,7 @@ /** * \def MBEDTLS_TIMING_ALT * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * Uncomment to provide your own alternate implementation for * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() * * Only works if you have MBEDTLS_TIMING_C enabled. @@ -1015,7 +1015,7 @@ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES * * Do not add default entropy sources. These are the platform specific - * or mbedtls_timing_hardclock poll function. + * poll function. * * This is useful to have more control over the added entropy sources in an * application. diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h index 7669bb9b3e..9ea5c29669 100644 --- a/include/mbedtls/timing.h +++ b/include/mbedtls/timing.h @@ -63,21 +63,11 @@ typedef struct mbedtls_timing_delay_context extern volatile int mbedtls_timing_alarmed; -/** - * \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. - * - * \note This value starts at an unspecified origin and - * may wrap around. - */ -unsigned long mbedtls_timing_hardclock( void ); - /** * \brief Return the elapsed time in milliseconds * + * \warning May change without notice + * * \param val points to a timer structure * \param reset If 0, query the elapsed time. Otherwise (re)start the timer. * @@ -94,18 +84,6 @@ unsigned long mbedtls_timing_hardclock( void ); */ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); -/** - * \brief Setup an alarm clock - * - * \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 - * context, this means one for the whole process, not one per - * thread. - */ -void mbedtls_set_alarm( int seconds ); - /** * \brief Set a pair of delays to watch * (See \c mbedtls_timing_get_delay().) @@ -136,15 +114,6 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); */ int mbedtls_timing_get_delay( void *data ); -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_timing_self_test( int verbose ); -#endif - #ifdef __cplusplus } #endif diff --git a/library/entropy.c b/library/entropy.c index cc686282a6..e652e99a5a 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -73,11 +73,6 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif -#if defined(MBEDTLS_TIMING_C) - mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDCLOCK, - MBEDTLS_ENTROPY_SOURCE_WEAK ); -#endif #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, MBEDTLS_ENTROPY_MIN_HARDWARE, diff --git a/library/entropy_poll.c b/library/entropy_poll.c index e5d75c5b37..bccc03478e 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -211,24 +211,6 @@ int mbedtls_platform_entropy_poll( void *data, #endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ -#if defined(MBEDTLS_TIMING_C) -int mbedtls_hardclock_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - unsigned long timer = mbedtls_timing_hardclock(); - ((void) data); - *olen = 0; - - if( len < sizeof(unsigned long) ) - return( 0 ); - - memcpy( output, &timer, sizeof(unsigned long) ); - *olen = sizeof(unsigned long); - - return( 0 ); -} -#endif /* MBEDTLS_TIMING_C */ - #if defined(MBEDTLS_ENTROPY_NV_SEED) int mbedtls_nv_seed_poll( void *data, unsigned char *output, size_t len, size_t *olen ) diff --git a/library/entropy_poll.h b/library/entropy_poll.h index 9120fe5a0e..bf268892d2 100644 --- a/library/entropy_poll.h +++ b/library/entropy_poll.h @@ -38,7 +38,6 @@ extern "C" { * Default thresholds for built-in sources, in bytes */ #define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ -#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ #if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) #define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ #endif @@ -51,14 +50,6 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen ); #endif -#if defined(MBEDTLS_TIMING_C) -/** - * \brief mbedtls_timing_hardclock-based entropy poll callback - */ -int mbedtls_hardclock_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) /** * \brief Entropy poll callback for a hardware source diff --git a/library/timing.c b/library/timing.c index 664fde0827..764ff7d5d7 100644 --- a/library/timing.c +++ b/library/timing.c @@ -67,172 +67,6 @@ struct _hr_time #endif /* _WIN32 && !EFIX64 && !EFI32 */ -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tsc; - __asm rdtsc - __asm mov [tsc], eax - return( tsc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ - -/* some versions of mingw-64 have 32-bit longs even on x84_64 */ -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__i386__) || ( \ - ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __i386__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo | ( hi << 32 ) ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __amd64__ || __x86_64__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tbl, tbu0, tbu1; - - do - { - asm volatile( "mftbu %0" : "=r" (tbu0) ); - asm volatile( "mftb %0" : "=r" (tbl ) ); - asm volatile( "mftbu %0" : "=r" (tbu1) ); - } - while( tbu0 != tbu1 ); - - return( tbl ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __powerpc__ || __ppc__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc64__) - -#if defined(__OpenBSD__) -#warning OpenBSD does not allow access to tick register using software version instead -#else -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); - return( tick ); -} -#endif /* __OpenBSD__ */ -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); - asm volatile( "mov %%g1, %0" : "=r" (tick) ); - return( tick ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc__ && !__sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__alpha__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long cc; - asm volatile( "rpcc %0" : "=r" (cc) ); - return( cc & 0xFFFFFFFF ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __alpha__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__ia64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long itc; - asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); - return( itc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __ia64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ - !defined(EFIX64) && !defined(EFI32) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - LARGE_INTEGER offset; - - QueryPerformanceCounter( &offset ); - - return( (unsigned long)( offset.QuadPart ) ); -} -#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ - -#if !defined(HAVE_HARDCLOCK) - -#define HAVE_HARDCLOCK - -static int hardclock_init = 0; -static struct timeval tv_init; - -unsigned long mbedtls_timing_hardclock( void ) -{ - struct timeval tv_cur; - - if( hardclock_init == 0 ) - { - gettimeofday( &tv_init, NULL ); - hardclock_init = 1; - } - - gettimeofday( &tv_cur, NULL ); - return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 - + ( tv_cur.tv_usec - tv_init.tv_usec ) ); -} -#endif /* !HAVE_HARDCLOCK */ - volatile int mbedtls_timing_alarmed = 0; #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) @@ -258,33 +92,6 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int } } -/* It's OK to use a global because alarm() is supposed to be global anyway */ -static DWORD alarmMs; - -static void TimerProc( void *TimerContext ) -{ - (void) TimerContext; - Sleep( alarmMs ); - mbedtls_timing_alarmed = 1; - /* _endthread will be called implicitly on return - * That ensures execution of thread funcition's epilogue */ -} - -void mbedtls_set_alarm( int seconds ) -{ - if( seconds == 0 ) - { - /* No need to create a thread for this simple case. - * Also, this shorcut is more reliable at least on MinGW32 */ - mbedtls_timing_alarmed = 1; - return; - } - - mbedtls_timing_alarmed = 0; - alarmMs = seconds * 1000; - (void) _beginthread( TimerProc, 0, NULL ); -} - #else /* _WIN32 && !EFIX64 && !EFI32 */ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) @@ -307,25 +114,6 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int } } -static void sighandler( int signum ) -{ - mbedtls_timing_alarmed = 1; - signal( signum, sighandler ); -} - -void mbedtls_set_alarm( int seconds ) -{ - mbedtls_timing_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. */ - mbedtls_timing_alarmed = 1; - } -} - #endif /* _WIN32 && !EFIX64 && !EFI32 */ /* @@ -368,40 +156,6 @@ int mbedtls_timing_get_delay( void *data ) #if defined(MBEDTLS_SELF_TEST) -/* - * Busy-waits for the given number of milliseconds. - * Used for testing mbedtls_timing_hardclock. - */ -static void busy_msleep( unsigned long msec ) -{ - struct mbedtls_timing_hr_time hires; - unsigned long i = 0; /* for busy-waiting */ - volatile unsigned long j; /* to prevent optimisation */ - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) - i++; - - j = i; - (void) j; -} - -static void print_timers( struct mbedtls_timing_hr_time *hires, - mbedtls_timing_delay_context *ctx ) -{ -#if defined(MBEDTLS_TIMING_ALT) - mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=?? status(ctx)=%d\n", - mbedtls_timing_get_timer( hires, 0 ), - mbedtls_timing_get_delay( ctx ) ); -#else - 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 ) ); -#endif -} - #define FAIL do \ { \ if( verbose != 0 ) \ @@ -415,128 +169,6 @@ static void print_timers( struct mbedtls_timing_hr_time *hires, return( 1 ); \ } while( 0 ) -/* - * Checkup routine - * - * Warning: this is work in progress, some tests may not be reliable enough - * yet! False positives may happen. - */ -int mbedtls_timing_self_test( int verbose ) -{ - unsigned long cycles = 0, ratio = 0; - unsigned long millisecs = 0, secs = 0; - int hardfail = 0; - struct mbedtls_timing_hr_time hires; - uint32_t a = 0, b = 0; - mbedtls_timing_delay_context ctx; - - if( verbose != 0 ) - mbedtls_printf( " TIMING tests note: will take some time!\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); - - { - secs = 1; - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - mbedtls_set_alarm( (int) secs ); - while( !mbedtls_timing_alarmed ) - ; - - millisecs = mbedtls_timing_get_timer( &hires, 0 ); - - /* 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 ) - FAIL; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); - - { - a = 800; - b = 400; - mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */ - - busy_msleep( a - a / 4 ); /* T = a - a/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 0 ) - FAIL; - - busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 1 ) - FAIL; - - busy_msleep( b ); /* T = a + b + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 2 ) - FAIL; - } - - mbedtls_timing_set_delay( &ctx, 0, 0 ); - busy_msleep( 200 ); - if( mbedtls_timing_get_delay( &ctx ) != -1 ) - FAIL; - - if( verbose != 0 ) - 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. - */ - -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 ); -} - #endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_TIMING_C */ diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 148e6da472..2f9a67395d 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -77,10 +77,37 @@ int main( void ) #include "mbedtls/error.h" +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#include +#include + +struct _hr_time +{ + LARGE_INTEGER start; +}; + +#else + +#include +#include +#include +#include +#include + +struct _hr_time +{ + struct timeval start; +}; + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) #include "mbedtls/memory_buffer_alloc.h" #endif +static void mbedtls_set_alarm( int seconds ); + /* * For heap usage estimates, we need an estimate of the overhead per allocated * block. ptmalloc2/3 (used in gnu libc for instance) uses 2 size_t per block, @@ -212,6 +239,226 @@ do { \ } \ } while( 0 ) +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tsc; + __asm rdtsc + __asm mov [tsc], eax + return( tsc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ + +/* some versions of mingw-64 have 32-bit longs even on x84_64 */ +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__i386__) || ( \ + ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __i386__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo | ( hi << 32 ) ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __amd64__ || __x86_64__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tbl, tbu0, tbu1; + + do + { + asm volatile( "mftbu %0" : "=r" (tbu0) ); + asm volatile( "mftb %0" : "=r" (tbl ) ); + asm volatile( "mftbu %0" : "=r" (tbu1) ); + } + while( tbu0 != tbu1 ); + + return( tbl ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __powerpc__ || __ppc__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc64__) + +#if defined(__OpenBSD__) +#warning OpenBSD does not allow access to tick register using software version instead +#else +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); + return( tick ); +} +#endif /* __OpenBSD__ */ +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); + asm volatile( "mov %%g1, %0" : "=r" (tick) ); + return( tick ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc__ && !__sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__alpha__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long cc; + asm volatile( "rpcc %0" : "=r" (cc) ); + return( cc & 0xFFFFFFFF ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __alpha__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__ia64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long itc; + asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); + return( itc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __ia64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ + !defined(EFIX64) && !defined(EFI32) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + LARGE_INTEGER offset; + + QueryPerformanceCounter( &offset ); + + return( (unsigned long)( offset.QuadPart ) ); +} +#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ + +#if !defined(HAVE_HARDCLOCK) + +#define HAVE_HARDCLOCK + +static int hardclock_init = 0; +static struct timeval tv_init; + +unsigned long mbedtls_timing_hardclock( void ) +{ + struct timeval tv_cur; + + if( hardclock_init == 0 ) + { + gettimeofday( &tv_init, NULL ); + hardclock_init = 1; + } + + gettimeofday( &tv_cur, NULL ); + return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + + ( tv_cur.tv_usec - tv_init.tv_usec ) ); +} +#endif /* !HAVE_HARDCLOCK */ + +volatile int mbedtls_timing_alarmed = 0; + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +/* It's OK to use a global because alarm() is supposed to be global anyway */ +static DWORD alarmMs; + +static void TimerProc( void *TimerContext ) +{ + (void) TimerContext; + Sleep( alarmMs ); + mbedtls_timing_alarmed = 1; + /* _endthread will be called implicitly on return + * That ensures execution of thread funcition's epilogue */ +} + +static void mbedtls_set_alarm( int seconds ) +{ + if( seconds == 0 ) + { + /* No need to create a thread for this simple case. + * Also, this shorcut is more reliable at least on MinGW32 */ + mbedtls_timing_alarmed = 1; + return; + } + + mbedtls_timing_alarmed = 0; + alarmMs = seconds * 1000; + (void) _beginthread( TimerProc, 0, NULL ); +} + +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +static void sighandler( int signum ) +{ + mbedtls_timing_alarmed = 1; + signal( signum, sighandler ); +} + +static void mbedtls_set_alarm( int seconds ) +{ + mbedtls_timing_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. */ + mbedtls_timing_alarmed = 1; + } +} + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + static int myrand( void *rng_state, unsigned char *output, size_t len ) { size_t use_len; diff --git a/programs/test/selftest.c b/programs/test/selftest.c index a3e306ce91..5e7eddf596 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -346,10 +346,6 @@ const selftest_t selftests[] = #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}, diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function index d612548d7b..9f72b47a4b 100644 --- a/tests/suites/test_suite_psa_crypto_init.function +++ b/tests/suites/test_suite_psa_crypto_init.function @@ -85,12 +85,6 @@ static void custom_entropy_init( mbedtls_entropy_context *ctx ) MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif -#if defined(MBEDTLS_TIMING_C) - if( custom_entropy_sources_mask & ENTROPY_SOURCE_TIMING ) - mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDCLOCK, - MBEDTLS_ENTROPY_SOURCE_WEAK ); -#endif #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) if( custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE ) mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, diff --git a/tests/suites/test_suite_timing.data b/tests/suites/test_suite_timing.data index 2522da1eaf..de89239e76 100644 --- a/tests/suites/test_suite_timing.data +++ b/tests/suites/test_suite_timing.data @@ -1,15 +1,6 @@ -Timing: hardclock -timing_hardclock: - Timing: get timer timing_get_timer: -Timing: set alarm with no delay -timing_set_alarm:0: - -Timing: set alarm with 1s delay -timing_set_alarm:1: - Timing: delay 0ms timing_delay:0: diff --git a/tests/suites/test_suite_timing.function b/tests/suites/test_suite_timing.function index 74dc823171..3483d85f35 100644 --- a/tests/suites/test_suite_timing.function +++ b/tests/suites/test_suite_timing.function @@ -16,15 +16,6 @@ * END_DEPENDENCIES */ -/* BEGIN_CASE */ -void timing_hardclock( ) -{ - (void) mbedtls_timing_hardclock(); - /* This goto is added to avoid warnings from the generated code. */ - goto exit; -} -/* END_CASE */ - /* BEGIN_CASE */ void timing_get_timer( ) { @@ -36,23 +27,6 @@ void timing_get_timer( ) } /* END_CASE */ -/* BEGIN_CASE */ -void timing_set_alarm( int seconds ) -{ - if( seconds == 0 ) - { - mbedtls_set_alarm( seconds ); - TEST_ASSERT( mbedtls_timing_alarmed == 1 ); - } - else - { - mbedtls_set_alarm( seconds ); - TEST_ASSERT( mbedtls_timing_alarmed == 0 || - mbedtls_timing_alarmed == 1 ); - } -} -/* END_CASE */ - /* BEGIN_CASE */ void timing_delay( int fin_ms ) { From 90f304ff1a2c72bd9949ae665728b6c7bfbf338e Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Fri, 11 Jun 2021 11:56:47 +0200 Subject: [PATCH 2/7] Fixing test_clang_opt (asm not defined) Signed-off-by: TRodziewicz --- include/mbedtls/config.h | 1 - library/timing.c | 4 ---- programs/test/benchmark.c | 4 ++++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 1626efb085..74b82221de 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -47,7 +47,6 @@ * * Used in: * library/aria.c - * library/timing.c * library/bn_mul.h * * Required by: diff --git a/library/timing.c b/library/timing.c index 764ff7d5d7..7964102e65 100644 --- a/library/timing.c +++ b/library/timing.c @@ -38,10 +38,6 @@ #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" #endif -#ifndef asm -#define asm __asm -#endif - #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 2f9a67395d..b4b8c283d4 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -77,6 +77,10 @@ int main( void ) #include "mbedtls/error.h" +#ifndef asm +#define asm __asm +#endif + #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include From 9a9609ee067cce9d9c21124fb3cee9a79f62673a Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Fri, 11 Jun 2021 13:35:10 +0200 Subject: [PATCH 3/7] Make static all the functions moved to bechmark.c Signed-off-by: TRodziewicz --- programs/test/benchmark.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index b4b8c283d4..cbda798666 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -248,7 +248,7 @@ do { \ #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long tsc; __asm rdtsc @@ -265,7 +265,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long lo, hi; asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); @@ -279,7 +279,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long lo, hi; asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); @@ -293,7 +293,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long tbl, tbu0, tbu1; @@ -318,7 +318,7 @@ unsigned long mbedtls_timing_hardclock( void ) #else #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long tick; asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); @@ -333,7 +333,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long tick; asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); @@ -348,7 +348,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long cc; asm volatile( "rpcc %0" : "=r" (cc) ); @@ -362,7 +362,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { unsigned long itc; asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); @@ -376,7 +376,7 @@ unsigned long mbedtls_timing_hardclock( void ) #define HAVE_HARDCLOCK -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { LARGE_INTEGER offset; @@ -393,7 +393,7 @@ unsigned long mbedtls_timing_hardclock( void ) static int hardclock_init = 0; static struct timeval tv_init; -unsigned long mbedtls_timing_hardclock( void ) +static unsigned long mbedtls_timing_hardclock( void ) { struct timeval tv_cur; From 5bbbb5ed28dafd3dde7e7969909a42946b420cb0 Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Fri, 11 Jun 2021 14:02:06 +0200 Subject: [PATCH 4/7] Remove the mbedtls_printf and FAIL macros Signed-off-by: TRodziewicz --- library/timing.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/library/timing.c b/library/timing.c index 7964102e65..d87d8b6cab 100644 --- a/library/timing.c +++ b/library/timing.c @@ -19,13 +19,6 @@ #include "common.h" -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - #if defined(MBEDTLS_TIMING_C) #include "mbedtls/timing.h" @@ -149,22 +142,4 @@ int mbedtls_timing_get_delay( void *data ) } #endif /* !MBEDTLS_TIMING_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#define FAIL do \ - { \ - if( verbose != 0 ) \ - { \ - 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 ); \ - print_timers( &hires, &ctx ); \ - } \ - return( 1 ); \ - } while( 0 ) - -#endif /* MBEDTLS_SELF_TEST */ - #endif /* MBEDTLS_TIMING_C */ From 9c90226df17f1ba39107bb4029a2baf84fc2462b Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Fri, 11 Jun 2021 14:30:01 +0200 Subject: [PATCH 5/7] Addition of the migration guide and change log files Signed-off-by: TRodziewicz --- ChangeLog.d/issue4083.txt | 5 +++++ .../move_part_of_timing_module_out_of_the_library.md | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 ChangeLog.d/issue4083.txt create mode 100644 docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md diff --git a/ChangeLog.d/issue4083.txt b/ChangeLog.d/issue4083.txt new file mode 100644 index 0000000000..f3f7e31b01 --- /dev/null +++ b/ChangeLog.d/issue4083.txt @@ -0,0 +1,5 @@ +Changes + * Remove the following functions: mbedtls_timing_self_test() and + mbedtls_hardclock_poll(). Move the following functions to the benchmark.c + file and make them static: mbedtls_timing_hardclock() and + mbedtls_set_alarm(). Fixes #4083. diff --git a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md new file mode 100644 index 0000000000..f0b539c8f2 --- /dev/null +++ b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md @@ -0,0 +1,12 @@ +Move part of timing module out of the library +-- + +The change affects users who use any of the following functions: +`mbedtls_timing_self_test()`, `mbedtls_hardclock_poll()`, +`mbedtls_timing_hardclock()` and `mbedtls_set_alarm()`. + +This change is the first step of a plan of removal of the `timing.c` from the +library. The plan is to move all the timing functions to the `platform.c` file. + +For users who still need removed functions the migration path is to re-implement +them as a platform support code. From 15a7b737082df748de0aff2d2a3efdd7c8dd1e0c Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Wed, 16 Jun 2021 11:22:53 +0200 Subject: [PATCH 6/7] Documentation rewording Signed-off-by: TRodziewicz --- ChangeLog.d/issue4083.txt | 7 +++---- ...art_of_timing_module_out_of_the_library.md | 7 ++----- include/mbedtls/config.h | 3 +-- include/mbedtls/timing.h | 20 +------------------ library/timing.c | 19 ++++++++++++++++++ 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/ChangeLog.d/issue4083.txt b/ChangeLog.d/issue4083.txt index f3f7e31b01..845733702f 100644 --- a/ChangeLog.d/issue4083.txt +++ b/ChangeLog.d/issue4083.txt @@ -1,5 +1,4 @@ -Changes - * Remove the following functions: mbedtls_timing_self_test() and - mbedtls_hardclock_poll(). Move the following functions to the benchmark.c - file and make them static: mbedtls_timing_hardclock() and +Removals + * Remove the following functions: mbedtls_timing_self_test(), + mbedtls_hardclock_poll(), mbedtls_timing_hardclock() and mbedtls_set_alarm(). Fixes #4083. diff --git a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md index f0b539c8f2..fa61e274bd 100644 --- a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md +++ b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md @@ -5,8 +5,5 @@ The change affects users who use any of the following functions: `mbedtls_timing_self_test()`, `mbedtls_hardclock_poll()`, `mbedtls_timing_hardclock()` and `mbedtls_set_alarm()`. -This change is the first step of a plan of removal of the `timing.c` from the -library. The plan is to move all the timing functions to the `platform.c` file. - -For users who still need removed functions the migration path is to re-implement -them as a platform support code. +If you were relying on these functions, you'll now need to change to using your +platform's corresponding functions directly. diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 74b82221de..4a98c5ddad 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1013,8 +1013,7 @@ /** * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES * - * Do not add default entropy sources. These are the platform specific - * poll function. + * Do not add default entropy sources in mbedtls_entropy_init(). * * This is useful to have more control over the added entropy sources in an * application. diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h index 9ea5c29669..5289889f98 100644 --- a/include/mbedtls/timing.h +++ b/include/mbedtls/timing.h @@ -63,25 +63,7 @@ typedef struct mbedtls_timing_delay_context extern volatile int mbedtls_timing_alarmed; -/** - * \brief Return the elapsed time in milliseconds - * - * \warning May change without notice - * - * \param val points to a timer structure - * \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. - */ +/* Internal use */ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); /** diff --git a/library/timing.c b/library/timing.c index d87d8b6cab..e6dfc72d18 100644 --- a/library/timing.c +++ b/library/timing.c @@ -83,6 +83,25 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int #else /* _WIN32 && !EFIX64 && !EFI32 */ +/** + * \brief Return the elapsed time in milliseconds + * + * \warning May change without notice + * + * \param val points to a timer structure + * \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 ) { struct _hr_time *t = (struct _hr_time *) val; From 963bb810f4116f5ab8ad90cbc1cfb66677a69b52 Mon Sep 17 00:00:00 2001 From: TRodziewicz Date: Fri, 18 Jun 2021 13:22:57 +0200 Subject: [PATCH 7/7] Removing global variable and moving variant function comment block Signed-off-by: TRodziewicz --- include/mbedtls/timing.h | 2 -- library/timing.c | 40 +++++++++++++++++++--------------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h index 5289889f98..6ffc812d8b 100644 --- a/include/mbedtls/timing.h +++ b/include/mbedtls/timing.h @@ -61,8 +61,6 @@ typedef struct mbedtls_timing_delay_context #include "timing_alt.h" #endif /* MBEDTLS_TIMING_ALT */ -extern volatile int mbedtls_timing_alarmed; - /* Internal use */ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); diff --git a/library/timing.c b/library/timing.c index e6dfc72d18..a85ce67b83 100644 --- a/library/timing.c +++ b/library/timing.c @@ -56,8 +56,25 @@ struct _hr_time #endif /* _WIN32 && !EFIX64 && !EFI32 */ -volatile int mbedtls_timing_alarmed = 0; - +/** + * \brief Return the elapsed time in milliseconds + * + * \warning May change without notice + * + * \param val points to a timer structure + * \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. + */ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) @@ -83,25 +100,6 @@ unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int #else /* _WIN32 && !EFIX64 && !EFI32 */ -/** - * \brief Return the elapsed time in milliseconds - * - * \warning May change without notice - * - * \param val points to a timer structure - * \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 ) { struct _hr_time *t = (struct _hr_time *) val;