1 /** 2 * \file timing.h 3 * 4 * \brief Portable interface to timeouts and to the CPU cycle counter 5 */ 6 /* 7 * Copyright The Mbed TLS Contributors 8 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 9 */ 10 #ifndef MBEDTLS_TIMING_H 11 #define MBEDTLS_TIMING_H 12 13 #if !defined(MBEDTLS_CONFIG_FILE) 14 #include "mbedtls/config.h" 15 #else 16 #include MBEDTLS_CONFIG_FILE 17 #endif 18 19 #include <stdint.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #if !defined(MBEDTLS_TIMING_ALT) 26 // Regular implementation 27 // 28 29 /** 30 * \brief timer structure 31 */ 32 struct mbedtls_timing_hr_time { 33 unsigned char opaque[32]; 34 }; 35 36 /** 37 * \brief Context for mbedtls_timing_set/get_delay() 38 */ 39 typedef struct mbedtls_timing_delay_context { 40 struct mbedtls_timing_hr_time timer; 41 uint32_t int_ms; 42 uint32_t fin_ms; 43 } mbedtls_timing_delay_context; 44 45 #else /* MBEDTLS_TIMING_ALT */ 46 #include "timing_alt.h" 47 #endif /* MBEDTLS_TIMING_ALT */ 48 49 extern volatile int mbedtls_timing_alarmed; 50 51 /** 52 * \brief Return the CPU cycle counter value 53 * 54 * \warning This is only a best effort! Do not rely on this! 55 * In particular, it is known to be unreliable on virtual 56 * machines. 57 * 58 * \note This value starts at an unspecified origin and 59 * may wrap around. 60 */ 61 unsigned long mbedtls_timing_hardclock(void); 62 63 /** 64 * \brief Return the elapsed time in milliseconds 65 * 66 * \param val points to a timer structure 67 * \param reset If 0, query the elapsed time. Otherwise (re)start the timer. 68 * 69 * \return Elapsed time since the previous reset in ms. When 70 * restarting, this is always 0. 71 * 72 * \note To initialize a timer, call this function with reset=1. 73 * 74 * Determining the elapsed time and resetting the timer is not 75 * atomic on all platforms, so after the sequence 76 * `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 = 77 * get_timer(0) }` the value time1+time2 is only approximately 78 * the delay since the first reset. 79 */ 80 unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset); 81 82 /** 83 * \brief Setup an alarm clock 84 * 85 * \param seconds delay before the "mbedtls_timing_alarmed" flag is set 86 * (must be >=0) 87 * 88 * \warning Only one alarm at a time is supported. In a threaded 89 * context, this means one for the whole process, not one per 90 * thread. 91 */ 92 void mbedtls_set_alarm(int seconds); 93 94 /** 95 * \brief Set a pair of delays to watch 96 * (See \c mbedtls_timing_get_delay().) 97 * 98 * \param data Pointer to timing data. 99 * Must point to a valid \c mbedtls_timing_delay_context struct. 100 * \param int_ms First (intermediate) delay in milliseconds. 101 * The effect if int_ms > fin_ms is unspecified. 102 * \param fin_ms Second (final) delay in milliseconds. 103 * Pass 0 to cancel the current delay. 104 * 105 * \note To set a single delay, either use \c mbedtls_timing_set_timer 106 * directly or use this function with int_ms == fin_ms. 107 */ 108 void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms); 109 110 /** 111 * \brief Get the status of delays 112 * (Memory helper: number of delays passed.) 113 * 114 * \param data Pointer to timing data 115 * Must point to a valid \c mbedtls_timing_delay_context struct. 116 * 117 * \return -1 if cancelled (fin_ms = 0), 118 * 0 if none of the delays are passed, 119 * 1 if only the intermediate delay is passed, 120 * 2 if the final delay is passed. 121 */ 122 int mbedtls_timing_get_delay(void *data); 123 124 #if defined(MBEDTLS_SELF_TEST) 125 /** 126 * \brief Checkup routine 127 * 128 * \return 0 if successful, or 1 if a test failed 129 */ 130 int mbedtls_timing_self_test(int verbose); 131 #endif 132 133 #ifdef __cplusplus 134 } 135 #endif 136 137 #endif /* timing.h */ 138