diff --git a/library/timing.c b/library/timing.c index 47e34f922768..94b55b3715df 100644 --- a/library/timing.c +++ b/library/timing.c @@ -17,6 +17,8 @@ * limitations under the License. */ +#include + #include "common.h" #include "mbedtls/platform.h" @@ -231,17 +233,20 @@ volatile int mbedtls_timing_alarmed = 0; unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) { - struct _hr_time *t = (struct _hr_time *) val; + struct _hr_time t; if (reset) { - QueryPerformanceCounter(&t->start); + QueryPerformanceCounter(&t.start); + memcpy(val, &t, sizeof(struct _hr_time)); return 0; } else { unsigned long delta; LARGE_INTEGER now, hfreq; + /* We can't safely cast val because it may not be aligned, so use memcpy */ + memcpy(&t, val, sizeof(struct _hr_time)); QueryPerformanceCounter(&now); QueryPerformanceFrequency(&hfreq); - delta = (unsigned long) ((now.QuadPart - t->start.QuadPart) * 1000ul + delta = (unsigned long) ((now.QuadPart - t.start.QuadPart) * 1000ul / hfreq.QuadPart); return delta; } @@ -277,17 +282,20 @@ void mbedtls_set_alarm(int seconds) unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) { - struct _hr_time *t = (struct _hr_time *) val; + struct _hr_time t; if (reset) { - gettimeofday(&t->start, NULL); + gettimeofday(&t.start, NULL); + memcpy(val, &t, sizeof(struct _hr_time)); return 0; } else { unsigned long delta; struct timeval now; + /* We can't safely cast val because it may not be aligned, so use memcpy */ + memcpy(&t, val, sizeof(struct _hr_time)); gettimeofday(&now, NULL); - delta = (now.tv_sec - t->start.tv_sec) * 1000ul - + (now.tv_usec - t->start.tv_usec) / 1000; + delta = (now.tv_sec - t.start.tv_sec) * 1000ul + + (now.tv_usec - t.start.tv_usec) / 1000; return delta; } } diff --git a/tests/suites/test_suite_timing.function b/tests/suites/test_suite_timing.function index 59c1207994c9..269922d975ee 100644 --- a/tests/suites/test_suite_timing.function +++ b/tests/suites/test_suite_timing.function @@ -29,8 +29,20 @@ void timing_hardclock() void timing_get_timer() { struct mbedtls_timing_hr_time time; + + memset(&time, 0, sizeof(time)); + (void) mbedtls_timing_get_timer(&time, 1); + + /* Check that a non-zero time was written back */ + int all_zero = 1; + for (size_t i = 0; i < sizeof(time); i++) { + all_zero &= ((unsigned char *) &time)[i] == 0; + } + TEST_ASSERT(!all_zero); + (void) mbedtls_timing_get_timer(&time, 0); + /* This goto is added to avoid warnings from the generated code. */ goto exit; }