For Thread key maintenance (Section 7.1.4, Key Generation), we need HMAC-SHA256 in Tock. I've done a little bit of Googling and the predominant Rust crypto library seems to be rust-crypto. Unfortunately, we can't just pull it in, because std, Box and Vec, but their SHA256 primitive is mostly vanilla Rust. Also, I'm not sure it's suited for our memory-constrained embedded setting: pub const K32: [u32; 64] = [ ... ];. I'm probably also completely clueless about licensing and stuff like that.
So, we have the following options. What do you suggest?
(1) seems like the best way forward, but I don't know of a good way to pull in their crate for only the part that implements the primitive without modifying it not to use std. Maybe a fork or something? (2) would be good too, and would probably take just as much time as (1). I am strongly strongly against (3) and am desperately hoping for (4).
Another option is ring which I believe is intentionally suited for bare metal and is also very well written. The author has also expressed some interest in supporting embedded stuff. I haven't been able to tell though which hashes are supported for the hmac implementation.
ring seems to be super-fast for SHA-256, but is assembly generated from perl?
cifra seems to be a very solid C library with no licensing issues.
rust-crypto seems like the best bet, despite K32 and K32X4. 512 bytes of ROM is significant, but implementations seem to be 1.5-2k it's not a terrible.
rust-crypto is effectively an abandoned project. Most devs in the Rust crypto community would reccomend sha2 from https://github.com/RustCrypto/hashes. RustCrypto/hashes is a maintained project and if you pull request assembly for supported architectures, it will likely be merged. https://github.com/RustCrypto/asm-hashes
Oh, great! From RustCrypto/hashes we can depend specifically on the sha2 crate and it looks like that doesn't even have any uses of unsafe, if we use the pure Rust implementation, which is a big plus. Implementing hmac on top of it should be fairly straightforward.
I haven't benchmarked, but the performance is gonna be a bummer (some googling makes me guess dozens of microseconds for a block-sized key) of blocking code in the kernel, but it doesn't seem we have an option.
@bbbert does that seem like a reasonable crate?
@alevy @zmanian That's a great option, thanks! It appears that they have x86 and x64 hashes. What would it take to get their asm hashes running on ARM?
Specifically, ARM thumb (CortexM)?
Isn't there a pure Rust imementation and then assembly optionally for optimization? If not probably porting an implementation from something like cifra. Will take a look.
ringseems to be super-fast for SHA-256, but is assembly generated from perl?
Yeah, that's lifted from openssl, so I wouldn't be as worried about it. My roommate (cc @dadrian) has met the ring author a few times and said he can ask around on some crypto slacks for the best rust nostd sha256 implementation (thanks David)
sha2 crate is no-std/ works fine in no-std. @tarcieri is using it in a no-std environment.
Indeed, David just confirmed that this is the consensus best implementation to use. Sorry I was late to the thread / making some noise -- do we need to keep this issue open for anything at this point?
Well I got my recommendation from @zmanian anyway, so SGTM.
My point of view is use Sha2 and if sha2 is broken for you, fix sha2
An experiment with integrating crate sha2 is at PR #683.
Feel free to contact me or open issue in RustCrypto repositories if you'll have any problems or requests! I will be happy to help!
I don't think anyone is still looking at this. So far we have opted to avoid introducing dependencies to Tock because cargo doesn't provide a method for ensuring those dependencies and their dependencies do not use unsafe.
Most helpful comment
Feel free to contact me or open issue in RustCrypto repositories if you'll have any problems or requests! I will be happy to help!