Skip to content

Commit 17ae051

Browse files
committed
mbedtls: Add full platform implementation of timing
When MBEDTLS_TIMING_C and MBEDTLS_TIMING_ALT are enabled, the Arm Compiler generates errors like the following (one for each missing symbol): Error: L6218E: Undefined symbol mbedtls_timing_get_delay Reason: The function `mbedtls_timing_self_test()` in the Mbed TLS default `timing.c` always gets compiled, if MBEDTLS_SELF_TEST is defined. And MBEDTLS_SELF_TEST is always defined, as we have a Greentea test to run some of the Mbed TLS self tests. (In the future we should try not to enable MBEDTLS_SELF_TEST except for tests, but it requires a rework in our test flow.) `mbedtls_timing_self_test()` tests (calls) the full API declared in `timing.h`, and the ARM Compiler requires all symbols referenced by all functions to be defined, even those not used by the final application. This is unlike GCC_ARM which resolves what are required. Solution: To fix the "undefined symbol" errors, we add an implementation of `mbedtls_timing_get_timer()` based on Mbed OS `LowPowerTimer` or `Timer` (depending on which one is available), and copy Mbed TLS's default `mbedtls_timing_set_delay()` and `mbedtls_timing_get_delay()` which are built on top of `mbedtls_timing_get_timer()`. This will also benefit user applications that need to enable timing in Mbed TLS.
1 parent f96f98e commit 17ae051

File tree

1 file changed

+69
-8
lines changed

1 file changed

+69
-8
lines changed

connectivity/mbedtls/platform/src/timing_mbed.cpp

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* timing.cpp
33
*
4+
* Copyright The Mbed TLS Contributors
45
* Copyright (C) 2021, Arm Limited, All Rights Reserved
56
* SPDX-License-Identifier: Apache-2.0
67
*
@@ -46,20 +47,23 @@ extern "C" void mbedtls_set_alarm(int seconds)
4647
t.attach(handle_alarm, std::chrono::seconds(seconds));
4748
}
4849

49-
#if !defined(HAVE_HARDCLOCK)
50-
#define HAVE_HARDCLOCK
51-
static int timer_init = 0;
52-
53-
extern "C" unsigned long mbedtls_timing_hardclock(void)
54-
{
50+
// The static Mbed timer here is initialized once only.
51+
// Mbed TLS can have multiple timers (mbedtls_timing_hr_time) derived
52+
// from the Mbed timer.
5553
#if DEVICE_LPTICKER
56-
static mbed::LowPowerTimer timer;
54+
static mbed::LowPowerTimer timer;
5755
#elif DEVICE_USTICKER
58-
static mbed::Timer timer;
56+
static mbed::Timer timer;
5957
#else
6058
#error "MBEDTLS_TIMING_C requires either LPTICKER or USTICKER"
6159
#endif
60+
static int timer_init = 0;
6261

62+
#if !defined(HAVE_HARDCLOCK)
63+
#define HAVE_HARDCLOCK
64+
65+
extern "C" unsigned long mbedtls_timing_hardclock(void)
66+
{
6367
if (timer_init == 0) {
6468
timer.reset();
6569
timer.start();
@@ -69,3 +73,60 @@ extern "C" unsigned long mbedtls_timing_hardclock(void)
6973
return timer.elapsed_time().count();
7074
}
7175
#endif /* !HAVE_HARDCLOCK */
76+
77+
extern "C" unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset)
78+
{
79+
if (timer_init == 0) {
80+
timer.reset();
81+
timer.start();
82+
timer_init = 1;
83+
}
84+
85+
if (reset) {
86+
val->start = std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count();
87+
return 0;
88+
} else {
89+
return std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count() - val->start;
90+
}
91+
}
92+
93+
/**
94+
* Note: The following implementations come from the default timing.c
95+
* from Mbed TLS. They are disabled in timing.c when MBEDTLS_TIMING_ALT
96+
* is defined, but the implementation is nonetheless applicable to
97+
* Mbed OS, so we copy them over.
98+
*/
99+
100+
extern "C" void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
101+
{
102+
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
103+
104+
ctx->int_ms = int_ms;
105+
ctx->fin_ms = fin_ms;
106+
107+
if (fin_ms != 0) {
108+
(void) mbedtls_timing_get_timer(&ctx->timer, 1);
109+
}
110+
}
111+
112+
extern "C" int mbedtls_timing_get_delay(void *data)
113+
{
114+
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
115+
unsigned long elapsed_ms;
116+
117+
if (ctx->fin_ms == 0) {
118+
return -1;
119+
}
120+
121+
elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0);
122+
123+
if (elapsed_ms >= ctx->fin_ms) {
124+
return 2;
125+
}
126+
127+
if (elapsed_ms >= ctx->int_ms) {
128+
return 1;
129+
}
130+
131+
return 0;
132+
}

0 commit comments

Comments
 (0)