1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Portable interface to the CPU cycle counter 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander 207901324dSJerome Forissier #include "common.h" 21817466cbSJens Wiklander 22817466cbSJens Wiklander #if defined(MBEDTLS_TIMING_C) 23817466cbSJens Wiklander 24817466cbSJens Wiklander #include "mbedtls/timing.h" 25817466cbSJens Wiklander 26817466cbSJens Wiklander #if !defined(MBEDTLS_TIMING_ALT) 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ 293d3b0591SJens Wiklander !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ 307901324dSJerome Forissier !defined(__HAIKU__) && !defined(__midipix__) 31*32b31808SJens Wiklander #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h" 32817466cbSJens Wiklander #endif 33817466cbSJens Wiklander 34817466cbSJens Wiklander #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 35817466cbSJens Wiklander 36817466cbSJens Wiklander #include <windows.h> 373d3b0591SJens Wiklander #include <process.h> 38817466cbSJens Wiklander 39*32b31808SJens Wiklander struct _hr_time { 40817466cbSJens Wiklander LARGE_INTEGER start; 41817466cbSJens Wiklander }; 42817466cbSJens Wiklander 43817466cbSJens Wiklander #else 44817466cbSJens Wiklander 45817466cbSJens Wiklander #include <unistd.h> 46817466cbSJens Wiklander #include <sys/types.h> 47817466cbSJens Wiklander #include <signal.h> 48039e02dfSJerome Forissier /* time.h should be included independently of MBEDTLS_HAVE_TIME. If the 49039e02dfSJerome Forissier * platform matches the ifdefs above, it will be used. */ 50817466cbSJens Wiklander #include <time.h> 51039e02dfSJerome Forissier #include <sys/time.h> 52*32b31808SJens Wiklander struct _hr_time { 53817466cbSJens Wiklander struct timeval start; 54817466cbSJens Wiklander }; 55817466cbSJens Wiklander #endif /* _WIN32 && !EFIX64 && !EFI32 */ 56817466cbSJens Wiklander 57*32b31808SJens Wiklander /** 58*32b31808SJens Wiklander * \brief Return the elapsed time in milliseconds 59*32b31808SJens Wiklander * 60*32b31808SJens Wiklander * \warning May change without notice 61*32b31808SJens Wiklander * 62*32b31808SJens Wiklander * \param val points to a timer structure 63*32b31808SJens Wiklander * \param reset If 0, query the elapsed time. Otherwise (re)start the timer. 64*32b31808SJens Wiklander * 65*32b31808SJens Wiklander * \return Elapsed time since the previous reset in ms. When 66*32b31808SJens Wiklander * restarting, this is always 0. 67*32b31808SJens Wiklander * 68*32b31808SJens Wiklander * \note To initialize a timer, call this function with reset=1. 69*32b31808SJens Wiklander * 70*32b31808SJens Wiklander * Determining the elapsed time and resetting the timer is not 71*32b31808SJens Wiklander * atomic on all platforms, so after the sequence 72*32b31808SJens Wiklander * `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 = 73*32b31808SJens Wiklander * get_timer(0) }` the value time1+time2 is only approximately 74*32b31808SJens Wiklander * the delay since the first reset. 75*32b31808SJens Wiklander */ 76817466cbSJens Wiklander #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 77817466cbSJens Wiklander 78817466cbSJens Wiklander unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) 79817466cbSJens Wiklander { 80817466cbSJens Wiklander struct _hr_time *t = (struct _hr_time *) val; 81817466cbSJens Wiklander 82*32b31808SJens Wiklander if (reset) { 83817466cbSJens Wiklander QueryPerformanceCounter(&t->start); 84*32b31808SJens Wiklander return 0; 85*32b31808SJens Wiklander } else { 863d3b0591SJens Wiklander unsigned long delta; 873d3b0591SJens Wiklander LARGE_INTEGER now, hfreq; 883d3b0591SJens Wiklander QueryPerformanceCounter(&now); 893d3b0591SJens Wiklander QueryPerformanceFrequency(&hfreq); 903d3b0591SJens Wiklander delta = (unsigned long) ((now.QuadPart - t->start.QuadPart) * 1000ul 913d3b0591SJens Wiklander / hfreq.QuadPart); 92*32b31808SJens Wiklander return delta; 93817466cbSJens Wiklander } 943d3b0591SJens Wiklander } 95817466cbSJens Wiklander 96817466cbSJens Wiklander #else /* _WIN32 && !EFIX64 && !EFI32 */ 97817466cbSJens Wiklander 98817466cbSJens Wiklander unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) 99817466cbSJens Wiklander { 100817466cbSJens Wiklander struct _hr_time *t = (struct _hr_time *) val; 101817466cbSJens Wiklander 102*32b31808SJens Wiklander if (reset) { 1033d3b0591SJens Wiklander gettimeofday(&t->start, NULL); 104*32b31808SJens Wiklander return 0; 105*32b31808SJens Wiklander } else { 1063d3b0591SJens Wiklander unsigned long delta; 1073d3b0591SJens Wiklander struct timeval now; 1083d3b0591SJens Wiklander gettimeofday(&now, NULL); 1093d3b0591SJens Wiklander delta = (now.tv_sec - t->start.tv_sec) * 1000ul 1103d3b0591SJens Wiklander + (now.tv_usec - t->start.tv_usec) / 1000; 111*32b31808SJens Wiklander return delta; 1123d3b0591SJens Wiklander } 113817466cbSJens Wiklander } 114817466cbSJens Wiklander 115817466cbSJens Wiklander #endif /* _WIN32 && !EFIX64 && !EFI32 */ 116817466cbSJens Wiklander 117817466cbSJens Wiklander /* 118817466cbSJens Wiklander * Set delays to watch 119817466cbSJens Wiklander */ 120817466cbSJens Wiklander void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms) 121817466cbSJens Wiklander { 122817466cbSJens Wiklander mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; 123817466cbSJens Wiklander 124817466cbSJens Wiklander ctx->int_ms = int_ms; 125817466cbSJens Wiklander ctx->fin_ms = fin_ms; 126817466cbSJens Wiklander 127*32b31808SJens Wiklander if (fin_ms != 0) { 128817466cbSJens Wiklander (void) mbedtls_timing_get_timer(&ctx->timer, 1); 129817466cbSJens Wiklander } 130*32b31808SJens Wiklander } 131817466cbSJens Wiklander 132817466cbSJens Wiklander /* 133817466cbSJens Wiklander * Get number of delays expired 134817466cbSJens Wiklander */ 135817466cbSJens Wiklander int mbedtls_timing_get_delay(void *data) 136817466cbSJens Wiklander { 137817466cbSJens Wiklander mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; 138817466cbSJens Wiklander unsigned long elapsed_ms; 139817466cbSJens Wiklander 140*32b31808SJens Wiklander if (ctx->fin_ms == 0) { 141*32b31808SJens Wiklander return -1; 142*32b31808SJens Wiklander } 143817466cbSJens Wiklander 144817466cbSJens Wiklander elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0); 145817466cbSJens Wiklander 146*32b31808SJens Wiklander if (elapsed_ms >= ctx->fin_ms) { 147*32b31808SJens Wiklander return 2; 148817466cbSJens Wiklander } 149817466cbSJens Wiklander 150*32b31808SJens Wiklander if (elapsed_ms >= ctx->int_ms) { 151*32b31808SJens Wiklander return 1; 152*32b31808SJens Wiklander } 153817466cbSJens Wiklander 154*32b31808SJens Wiklander return 0; 155*32b31808SJens Wiklander } 156817466cbSJens Wiklander 157817466cbSJens Wiklander /* 158*32b31808SJens Wiklander * Get the final delay. 159817466cbSJens Wiklander */ 160*32b31808SJens Wiklander uint32_t mbedtls_timing_get_final_delay( 161*32b31808SJens Wiklander const mbedtls_timing_delay_context *data) 162817466cbSJens Wiklander { 163*32b31808SJens Wiklander return data->fin_ms; 164817466cbSJens Wiklander } 165039e02dfSJerome Forissier #endif /* !MBEDTLS_TIMING_ALT */ 166817466cbSJens Wiklander #endif /* MBEDTLS_TIMING_C */ 167