feat: provide timer / clock support to mbedtls#108
feat: provide timer / clock support to mbedtls#108ericschaal wants to merge 18 commits intoesp-rs:mainfrom
Conversation
|
(Sit tight this is going to be tricky.) Some thoughts after looking at the MbedTLS timer & wall clock support: First off, the wall clock support in MbedTLS is pretty horrible, in that it binds the notion of a
Where they should have allowed the user to just override (note that by "time" below they really mean "wall clock time"):
... with her own definitions and thus be done with the platform "wall clock" support, they've instead horribly mandated that the user should support a transition from a timer duration to a wall clock instant!! I.e. we need to support Now, the small light at the end of the tunnel is that we might not have to necessarily do this conversion. By looking at So in a way, we can change the implementation semantics of our
This (to some extent) decouples the timer impl from the wall clock impl. Only to some extent though because we cannot define a wall clock provider without defining a timer provider. However a timer provider is trivially easy. Basically Further to that, providing a wall-clock time also becomes trivially easy: And it would all work. ===== I'll do a thorough review of your code shortly, but let me say upfront that using the RTC component of Contrary to its name, this thing is anything but a Real Time Clock:
|
|
Hmmm, on a second thought, we might keep a "default" implementation of the wall clock time based on the RTC clock in But we absolutely need to introduce the "platform-neutral" ==== BTW: sorry for the tons of comments. I know the PR is not ready for review yet, but wanted to provide an early feedback. Hope it is useful. |
|
Hi @ivmarkov feedback is useful thank you, I'll keep working on this PR 👍 |
8898b51 to
89fba5d
Compare
|
Currently we have two opt-in features for mbedtls time support:
Design Rationale: Question on Naming Consistency: I based my opt-in design decision on your comment. However, if you prefer a different approach, we could change it and potentially include at least timer support in the precompiled bindings. Implementations of MbedtlsTimer and MbedtlsWallClock traits:
Let me know your preference on the feature design, and I'm happy to adjust as needed. |
The problem with following an opt-OUT pattern for the date-time functionality is that if we switch to it (i.e. from "hook" to "nohook") then we are forcing the user to provide implementations for the timer and/or for date-time API. Moreover, we cannot easily "enforce" that the user did indeed provide hooks for these before calling the MbedTLS C API. So that would mean we need to panic at runtime if MbedTLS ends up calling our timer/date-time traits and there is no implementation for these. With the timer, this is not such a big deal, as embassy-time is a super-easy provider for a timer. I wonder though with date-time? Asking the user to provide a date-time trait before being able to establish the simplest TLS connection is maybe asking too much. Therefore, let's leave the features for timer and date-time as "hook" for now.
That's fine though the dependencies on the
Up to you. I think you just need to finish it, address all my comments (which are not outdated) and then make sure CI passes. |
b581300 to
1784fa8
Compare
|
Hi @ivmarkov, CI is passing. Could you offer your guidance on the 2 items below:
Sorry in advance if the answer to these questions is trivial. I'm quite new to this esp on rust ecosystem.
Examples with timer/wall-clock need rebuilt bindings (opt-in features not in pre-compiled bindings/libs). Solution implemented:
This deviates from the main purpose of this PR. Should this be a separate PR and is the approach acceptable? Or should use on the fly compilation when building examples (need fetch submodule & setup espressif clang)? I added a simple example: TLS connection to httpbin.org with correct RTC vs. 2x current time to trigger certificate validation failure. Could also be combined with the client example if needed. |
380bf5f to
5097a18
Compare
Yes, exactly. The same is done for the accel hooks.
For std, where std != ESP-IDF we just need to do exactly the same thing we do for no-std -> expose the two traits if the relevant features are enabled. For ESP-IDF mbedtls: we can't re-compile it on the fly so easily as we do for the other platforms here, because its shape is controlled in a completely different manner (using esp-idf kconfig values) that I don't think we want to introduce to this project. The reason why esp-idf - while being "std" - is treated in a special way is that we would like there to re-use the MbedTLS C lib which is coming with the ESP-IDF SDK itself. This version of the C lib already has hardware-accel built-in, and wired timer and date-time. In future we might also - and only for STD where STD != esp-idf - default the timer and date-time functions to their STD equivalents. Not sure we necessarily want to do this right now.
Hmmm, am I missing something? Can't see how that would work? Currently, If you provide two sets, the second set of artefacts will override the first one. For this not to happen, you need to implement something like this. However, given that: ... I don't think keeping more that one artefact per Rust target is a worthy goal anymore.
The latter. Need to fetch submodules and setup espressif clang. But isn't this done anyway? Remember, we also have STD examples. And these - by necessity - use on-the-fly compilation, which means git submodules are initialized. The espressif clang might not be there in the examples CI job, but you can copy it over from the xtask libraries pre-compilation job.
Keeping it separate for now is just fine. |
|
Hi @ivmarkov, I think there is a misunderstanding about the bindings metadata approach. this MR uses the build-mbedtls job (xtask gen) (which already has all build dependencies: espup, clang, initialized submodules) to generate two sets of bindings:
The build-mcu job (which builds & runs examples) downloads the example bindings artifact to build examples. Only the library bindings get committed to the repository. The example bindings are ephemeral CI artifacts with 1-day retention, they're never published. Alternative approach (what you are proposing I believe): Force on-the-fly compilation in the build-mcu job by adding steps to:
Both approaches should work, but the current approach is likely faster since it piggybacks on the already-installed toolchain and fetched submodules from build-mbedtls, avoiding redundant setup in build-mcu. |
I agree both should work. Here are a few:
|
It's the serialized hook Set that was used to generate the bindings. It is read by build.rs to determine if we need on the fly compilation (i.e requested hooks != pregen hooks). It is necessary to avoid on the fly compilation when running the example job (that way build.rs knows the time/wall-clock hooks are part of bindings!)
Yeah that's unexpected, not sure if I compiled everything properly. I'll make sure to clean things up before undrafting. totally fair, I'll make the changes. And maybe submit a separate PR with the CI/builder changes if deemed necessary. |
…::tm doesn't get compiled without the hook-wall-clock feature
|
@ericschaal Thanks! One thing before merge which still worries me slightly: the seconds'-resolution timer of mbedtls requires us to define a global symbol named "time". Literally, and unprefixed by the usual |
|
Yeah, that's probably not great. We could compile out the time definition using This should exclude our Option 2: Add a I don't think using fyi could be a use case of I'm leaning towards option 1, what do you think? EDIT: |
|
Sorry for the late reply - been quite busy these days. A super-simple solution is to just This would effectively force MbedTLS to do almost the same it does for the milliseconds time function - i.e. look for a pre-defined symbol called We can make the solution more complex by also |
|
Good idea! Unfortunately we have to define but yes should work! |
|
@ericschaal I'm sorry - merging #111 got this PR unmergable (merge conflicts). Can you rebase your work on top of newest |
Closes #92
Adds opt-in timer and wall clock support to mbedtls.
Two new features in mbedtls-rs-sys:
hook-timer: enables registration of a custom timer hook via theMbedtlsTimertraithook-wall-clock: enables registration of a custom wall clock hook via theMbedtlsWallClocktraitReady-to-use implementations:
timer-embassy:MbedtlsTimerimpl backed byembassy-timetimer-std:MbedtlsTimerimpl backed by stdwall-clock-esp32xx:MbedtlsWallClockimpl backed by the ESP32 RTC for all ESP32 variants (ESP32, C2/C3/C6, H2, S2/S3)wall-clock-std:MbedtlsWallClockimpl backed by stdDesign decision:
mbedtls_platform_gmtime_rignores thetime_tparameter and instead queries the wall clock directly for the current calendar time. This decouples the timer and wall clock implementations, since mbedtls always calls it with a freshly retrieved mbedtls_time(NULL) anyway.