blob: d87f71e6bfa2fcb3f034aec3110aabbcd92b6972 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Portable interface to the CPU cycle counter
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000021
Manuel Pégourié-Gonnard8903fe02015-05-12 19:30:45 +020022#if defined(MBEDTLS_TIMING_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000023
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020024# include "mbedtls/timing.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000025
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020026# if !defined(MBEDTLS_TIMING_ALT)
Manuel Pégourié-Gonnard8903fe02015-05-12 19:30:45 +020027
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020028# if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
29 !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
30 !defined(__HAIKU__) && !defined(__midipix__)
31# error \
32 "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h"
33# endif
Manuel Pégourié-Gonnard325ce092016-02-22 10:33:34 +010034
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020035# if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020037# include <windows.h>
38# include <process.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040struct _hr_time {
Paul Bakker5121ce52009-01-03 21:22:43 +000041 LARGE_INTEGER start;
42};
43
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020044# else
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020046# include <unistd.h>
47# include <sys/types.h>
48# include <sys/time.h>
49# include <signal.h>
50# include <time.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000051
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020052struct _hr_time {
Paul Bakker5121ce52009-01-03 21:22:43 +000053 struct timeval start;
54};
55
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020056# endif /* _WIN32 && !EFIX64 && !EFI32 */
Paul Bakker5121ce52009-01-03 21:22:43 +000057
TRodziewicz963bb812021-06-18 13:22:57 +020058/**
59 * \brief Return the elapsed time in milliseconds
60 *
61 * \warning May change without notice
62 *
63 * \param val points to a timer structure
64 * \param reset If 0, query the elapsed time. Otherwise (re)start the timer.
65 *
66 * \return Elapsed time since the previous reset in ms. When
67 * restarting, this is always 0.
68 *
69 * \note To initialize a timer, call this function with reset=1.
70 *
71 * Determining the elapsed time and resetting the timer is not
72 * atomic on all platforms, so after the sequence
73 * `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
74 * get_timer(0) }` the value time1+time2 is only approximately
75 * the delay since the first reset.
76 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020077# if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker5121ce52009-01-03 21:22:43 +000078
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020079unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val,
80 int reset)
Paul Bakker5121ce52009-01-03 21:22:43 +000081{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020082 struct _hr_time *t = (struct _hr_time *)val;
Paul Bakker5121ce52009-01-03 21:22:43 +000083
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020084 if (reset) {
85 QueryPerformanceCounter(&t->start);
86 return 0;
87 } else {
Gilles Peskined92f0aa2017-10-16 19:33:06 +020088 unsigned long delta;
89 LARGE_INTEGER now, hfreq;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090 QueryPerformanceCounter(&now);
91 QueryPerformanceFrequency(&hfreq);
92 delta = (unsigned long)((now.QuadPart - t->start.QuadPart) * 1000ul /
93 hfreq.QuadPart);
94 return delta;
Gilles Peskined92f0aa2017-10-16 19:33:06 +020095 }
Paul Bakker5121ce52009-01-03 21:22:43 +000096}
97
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020098# else /* _WIN32 && !EFIX64 && !EFI32 */
Paul Bakker5121ce52009-01-03 21:22:43 +000099
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200100unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val,
101 int reset)
Paul Bakker5121ce52009-01-03 21:22:43 +0000102{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103 struct _hr_time *t = (struct _hr_time *)val;
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105 if (reset) {
106 gettimeofday(&t->start, NULL);
107 return 0;
108 } else {
Gilles Peskined92f0aa2017-10-16 19:33:06 +0200109 unsigned long delta;
110 struct timeval now;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200111 gettimeofday(&now, NULL);
112 delta = (now.tv_sec - t->start.tv_sec) * 1000ul +
113 (now.tv_usec - t->start.tv_usec) / 1000;
114 return delta;
Gilles Peskined92f0aa2017-10-16 19:33:06 +0200115 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000116}
117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200118# endif /* _WIN32 && !EFIX64 && !EFI32 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200120/*
121 * Set delays to watch
122 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200123void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200124{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200125 mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *)data;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200126
127 ctx->int_ms = int_ms;
128 ctx->fin_ms = fin_ms;
129
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200130 if (fin_ms != 0)
131 (void)mbedtls_timing_get_timer(&ctx->timer, 1);
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200132}
133
134/*
135 * Get number of delays expired
136 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200137int mbedtls_timing_get_delay(void *data)
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200138{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200139 mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *)data;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200140 unsigned long elapsed_ms;
141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200142 if (ctx->fin_ms == 0)
143 return -1;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145 elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0);
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147 if (elapsed_ms >= ctx->fin_ms)
148 return 2;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200149
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200150 if (elapsed_ms >= ctx->int_ms)
151 return 1;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200152
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200153 return 0;
Manuel Pégourié-Gonnardca3bdc52015-05-12 20:17:06 +0200154}
155
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200156# endif /* !MBEDTLS_TIMING_ALT */
Manuel Pégourié-Gonnard8903fe02015-05-12 19:30:45 +0200157#endif /* MBEDTLS_TIMING_C */