Unix timestamps from Xous and the RTC #122
Replies: 9 comments 39 replies
-
Wow. #TIL there is a discussions tab in github. RTC is literally one of the things on the plate right now between me and @xobs. Tonight I am going to take a whack at figuring out what it takes to integrate our hardware into the As far as time zones, this has weighed on my mind quite a bit. The key problems in my mind are:
So, in a nutshell, I think Xous should have TZ handling, but I don't understand enough about who uses it to make an informed decision about how to architect this. Some questions I actually have for your TOTP / MFA application:
If it's the case that you basically just need your local time zone (or maybe two or three other TZs that you travel to), one viable method might be to store the TZ data in the PDDB. If it's the case that really you need to be able to look up offsets to a server that might happen to be located anywhere in the world, then, we would need to store the entire TZ database inside Xous. In which case, I would advocate to integrate it into the loader image. The loader has a block of memory that is signed but unencrypted and meant for large, static datastructures that change infrequently. For example, the font data is in the loader, not the kernel. This is important in part because for now the kernel is 100% running out of RAM, so every bit of static data we load into RAM is less RAM for applications; and it also takes pressure off the RAM L2 cache because the loader region is uncached but actually quite fast to access for sequential reads due to a quirk of our architecture. The main downside of putting TZ data into the loader is it reduces the space available for future fonts. We have 4.3MiB allocated for fonts, of which 1.06MiB are used right now to hold Emoji, Chinese, Japanese, Korean, Bold, mono, regular, and small typefaces. This means we're missing things like Cyrillic, Arabic, Tamil, Hindi, Hebrew, Thai, Mongolian, etc. etc. We reserve a huge amount of space becauses some of the languages, such as Arabic and Tamil, have complicated rules to compose characters could be eased by storing large tables of pre-composed letters, but I haven't researched this enough to really have a grasp of exactly how much space we'd need and what the best practices are to support these. However, "burning" about 1MiB on a time zone table would mean we still have about 2MiB free, which given the density of our Chinese and Japanese encodings I'm optimistic it could be enough to support quite a few more languages before we run out of space. So I'm not against the idea of putting a full TZ table into Xous, but if there were a binary encoding that was more compact than CSV that could reduce its footprint to a few hundred kiB that would make it a done deal. Again, a lot of open questions, and something I really don't understand well enough to answer. Another question I haven't figured out yet but soon well is if Anyways, sorry this isn't so conclusive, but if you can share any insight with me or thoughts about what is the right direction to take this, I am optimistic we can find the right trade-off between code size, usability, and sustainability. Oh finally, from the security side, I'm assuming that so long as the TZ formats are signed for distribution (but not encrypted) we're good. However, if there are security protocols that are irreparably broken if someone can shift a TZ definition without us noticing, then actually we need to rethink a lot of this, because it's not just about code distribution, we have to question the actual source TZ databases themselves. From a cursory inspection, a lot of the source TZ databases are community maintained and they could be a vector for a supply chain attack, where someone poisons the TZ definition at the source. |
Beta Was this translation helpful? Give feedback.
-
Thanks @bunnie. Responses inline.
Glad to hear you're thinking about the time interfaces!
For my specific use-case, I actually just need a stable unix timestamp. So, in pure Rust form, with the standard library on another OS, it'd be as basic as: use std::time::{SystemTime, UNIX_EPOCH};
fn get_timestamp() -> Result<u64, Error> {
SystemTime::now().duration_since(UNIX_EPOCH).map(|duration| duration.as_millis())
} My (perhaps incorrect) assumption was that in order to calculate a Unix timestamp, the OS would at a minimum need to know the user's Timezone (since they'll be setting their Betrusted system RTC time in their 'local zone'), and then be able to shift it to GMT, since Unix timestamps are always calculated from GMT. I haven't read through Linux or any other OS's implementation of how it calculates a unix epoch yet to know if there are tricks or implementation methods that I'm missing.
In my case, most implementations assume there's an OS that can give you a stable timestamp. Here's a very basic totp library I've used to implement a TOTP client as a desktop application before, if you want to take a look at the details. I wonder if most hardware TOTP token generators (RSA keys, for example) use a GPS sync'd clock or something. Not sure what techniques other hardware-implementations of TOTP use.
+1 on finding some binary encoded format of tzdata: This feels like it must be a solved problem with some prior art, but I'm not sure about specifics. There has to be other embedded targets that don't want to store a plaintext CSV. I wonder how small this could get down to?
I dove through the Rust std implementation for std::time, and it's pretty minimal. You'll have to double check me in some of your research, but my understanding is that the stdlib punts most timezone handling to the operating system via libc calls. For example, |
Beta Was this translation helpful? Give feedback.
-
@blakesmith I'm trying to think through the initial time setting process while reading through this RTC chip's datasheet in more detail. Something I'm realizing and slightly regretting is that this RTC chip is kind of the worst of all worlds. What I really want is just a counter that counts seconds, but what I have is a chip that does some bookkeeping on seconds to convert them into hours, minutes, seconds, days, weeks, years, with some dodgy leap year algorithm that just does divisible-by-4 plus '00 but not accounting for the divsible-by-400 rule (I guess in practice it's probably fine but I would have preferred just a count of seconds). Cut to the chase, how do you feel about this policy for Precursor:
In this scheme, you can start using your TOTP app before you have set your "real time offset" from the hardware RTC, as long as you use use std::time::{Instant};
fn get_timestamp() -> Result<u64, Error> {
Instant::now().duration_since(Instant::zero()).map(|duration| duration.as_millis())
}
Does this jive with what you're thinking? I think the TL;DR is:
|
Beta Was this translation helpful? Give feedback.
-
The concept of The situation you're describing with Since then, most platforms have opted to store an epoch of some sort in the RTC and do adjustment in the OS, which would be ideal if we could get timezones right. It could just be as simple as having a setting to set the timezone offset that the user has to manually adjust. The RTC time would always be in terms of UTC, but the time presented to the user would be adjusted by the timezone offset. They'd have to manually adjust it twice per year in the case of daylight saving, but perhaps that could work? Looking at events in the past would be weird though, since they'd be off by an hour. But looking at events in other timezones is always weird anyway, so I'm not sure if that's a problem or not. |
Beta Was this translation helpful? Give feedback.
-
The RTC retrofit is bigger than I had expected, so I am turning it into a check list of things such that I don't forget something.
Valid is false under the following conditions:
Summary of PDDB keys:
Expected user experience:
|
Beta Was this translation helpful? Give feedback.
-
There's a rather disheartening message about std::timeTimekeeping in secure enclaves is an unsolved problem. The following functions use the current time as reported by the Operating System, which may or may not be the actual current time:
Security warningDo not use the time obtained from these functions as the sole time source for making security decisions such as credential expiry. |
Beta Was this translation helpful? Give feedback.
-
After @bunnie's I'll continue to test the
Super hacky / rough code is up: https://github.com/blakesmith/xous-core/blob/xtotp-time/apps/xtotp/src/main.rs. I'll continue to push and work off this branch as I go and share feedback / updates! |
Beta Was this translation helpful? Give feedback.
-
Ok -- I have pushed time to the main and it seems reasonably solid under hosted mode and on real hardware (have not checked on renode (@xobs) but I don't think i did anything that would break renode). If you find any bugs with time, can you please open a new issue, instead of placing it in this discussion thread? I think we're basically done with the architecture/implementation phase and now in testing, and I find issues to be an easier way to manage my workflow for tactical problems like bugs. |
Beta Was this translation helpful? Give feedback.
-
I've absorbed your code into xous-core directly, hope that's OK: xous-core/apps/vault/src/totp.rs Lines 1 to 16 in 5d8b85c It's now part of the Just passed the first trivial test of things working, so this is looking good so far.... |
Beta Was this translation helpful? Give feedback.
-
Hi all,
I'm interested in porting a TOTP / MFA RFC6328 one-time password generator to Xous & Betrusted. My current plan is:
The one thing I need to figure out is how to get a Unix timestamp from Xous / the RTC to compute the one-time password. A few things I've researched:
I'd like to have Xous handle timezones, but haven't dove deep enough into things like a tz database yet to understand the implications of bringing something like this into scope for Xous. I'd also want to think through any more attack surface area of timezone manipulation. I'm also not sure which Xous service would be responsible for TZ relevant operations.
Before I go too deep down the rabbit hole, I'm looking for some high level feedback on direction:
Curious to hear any feedback or thoughts. Thanks!
Beta Was this translation helpful? Give feedback.
All reactions