-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved pure-Rust cryptographic implementations #1
Comments
I know that the stated purpose of the Rust implementations is to be placeholders - but with an eye towards future multi-platform support, keeping the soft implementations available for porting to platforms with different onboard crypto hardware might have longer-term value as well. |
Hello, thanks for the heads up! The current AES implementation is definitely just a textbook placeholder (although with comprehensive correctness unit tests), and If I understood correctly, ECDSA was also implemented recently (so we didn't have it under the radar). Is it still under development or also reaching some usable state? We also had a look at https://github.com/dalek-cryptography, which implements some crypto algorithms in pure Rust (our placeholders use subtle for comparisons), but unfortunately there was no support for P-256 which is mandated by the FIDO2 specs (hence our re-implementation of ECDSA). In general, I'm glad to see that RustCrypto is getting traction as a wide collection of crypto algorithms. It seems that quite a bit of algorithms have been added in the past months :) For embedded use cases at least, it definitely makes sense to focus efforts on one set of high-quality implementations that are easy to compile (self-contained, pure-Rust), with comprehensive testing (leveraging Rust's easy-to-use Speaking of which, in terms of governance, is the RustCrypto project in any way affiliated to (or in scope of) the Rust Secure Code Working Group (or are there any plans towards it once the implementation is mature enough)? |
Glad to hear it! Some specific responses:
That repository doesn't contain an implementation of ECDSA yet, and only provides reusable signature and key types which are generic over elliptic curves. I've definitely been considering adding an ECDSA implementation (generic over Weierstrass curves), especially as the
I'm one of the leads of the Secure Code WG, but beyond that there's no specific direct affiliation between the two. There is, however, an open application for a Cryptography WG. |
Thanks for the clarification on ECDSA. Indeed a Cryptography WG would be relevant to coordinate these efforts, looking forward to having one started! |
FYI, we now have a (newly implemented and at this point low-level) ECDSA/P-256 on top of some fairly nice and modern pure-Rust curve arithmetic (complete Weierstrass formulas based on projective arithmetic): https://github.com/RustCrypto/elliptic-curves/pull/84/files Notably it provides you the choice of using constant time inversions or a faster variable-time inversion with random blinding as a alternative method for accelerating the implementation on embedded targets. I’d call the ECDSA implementation “bleeding edge” at this point but we do hope to both get more eyes on it and improve testing quality relatively soon, as well as implementing things like RFC6979 and extensions to it which incorporate added randomness to mitigate fault attacks. |
Thanks for the heads up!
Having a brief look, I agree that there could be more testing. We took care to have extensive testing in the current OpenSK implementation, for example:
Even with that, I think we could still add even more tests to cover more edge cases, so it's still "research quality" code. |
Just dropping a note here -- over at Xous, we vendored in the OpenSK code and refactored the crypto crate to use the RustCrypto implementations (including the tests, which also includes the Wycheproof suite). Xous is different enough from Tock that I don't think it makes sense to try any sort of pull request, but in case anybody is interested in trying out OpenSK with the RustCrypto versions of all the ciphers, you might want to have a look around this crate for some hints on how to do it: https://github.com/betrusted-io/xous-core/tree/main/apps/vault/libraries/crypto |
Thanks for the notice! Are there commits before and after crypto migration? I'd be interested in binary size. |
Ah, that's a good question. Actually, we never tried it using the native libraries. I just gave it a whirl to see if it'd compile swapping your original libraries back in and fixing up some dependencies -- and it looks like some nightly features are required, which we don't support in our OS as we run on stable only. So the short answer is no, we never built OpenSK for our platform using your version of the cryptography libraries. I think the size comparison might not be fair anyways, because we have hardware accelerators for AES and SHA2 which we shim over the RustCrypto standard APIs (you can toggle the hardware acceleration on or off by either selecting our crate or the standard crate). This is the size of our final "app" based on OpenSK though, which includes some UI/UX functions and USB routines, and a whole bunch of debug still:
This is for a riscv32imac target. I'd guess about...150-180k of the .text is OS overhead, so the actual size of the OpenSK code is around 280-ish kiB. |
I that case, that's hard to compare. At some point in the future, we will peek at hardware crypto and then also take a closer look at other libraries. Thanks! |
@bunnie sidebar, but I'm curious how the traits are working for you in the context of a cryptographic accelerator. We've been interested in looking at alternative designs for embedded devices which would enable parallel pipelining between a cryptographic accelerator and a general-purpose MCU, for the purposes of doing things like encryption and authentication in parallel. This issue discusses potentially using |
Re: code size, I hope |
Maybe this
It gives a hint at least as to the rough size of the "big" functions. |
If I read this correctly, the numbers are still hard to compare. For example, our |
Looking over at the issue...it looks like the question is how do you get your CPU to do something while the crypto runs, especially in an accelerator. I think the short answer is, generally I've only found marginal benefit in adding the async overhead to a single primitive, and so we have lived comfortably within the existing blocking traits. This is for two reasons:
The downside of our cooperative multitasking is that the cost of message passing overhead is non-zero. Here's a benchmark example:
For short hashes (256 bytes), software completes faster than hardware. Above 1k or so, the hardware accelerator starts to see benefits (and it's incredibly beneficial when say, checking the signature on a 6MiB binary blob). The benchmark includes all OS messaging overhead -- so for the hardware accelerator, the data has to be serialized and sent to the hash engine, where as the software implementation runs its code directly in the process space of the caller. So in the end we don't do fine-grained async on the crypto primitives. However, the little I've seen of the Tock implementation you're running, it looks like the multitasking is cooperative?...I noticed from the very top down in your UX flows you're passing timers and having to explicitly call functions to update them, so my guess is you don't have cooperative multitasking? I am not terribly familiar with Tock. In which case I can see a very different design need for the trait implementations... |
Ah yes. good point. Here is the output with
|
fwiw,
in this case |
Small update: We now have a test implementation on the develop branch that runs on RustCrypto, you can try it with
I can experiment with RustCrypto on Nordic after we merge #580 and we can compile the embedded version of OpenSK with a newer nightly. I will come back with speed and binary size numbers then. @bunnie This should also make it easier to have newer OpenSK versions in Xous in the future. |
You can now have an OpenSK with RustCrypto. Add the For speed and binary size tradeoff, there is a discussion in #625. It suggests we can immediately replace AES, while still fittingall boards. Summary: Speed in ms / iter (-Oz -> -O3 (our implementation)):AES and SHA now beats our implementation, but ECDSA is still slower. I wonder why key generation is so slow though.
Binary sizeFull RustCrypto increases the binary size over the 128 kB limit, means you can't have an upgradable OpenSK as of now. Using
|
Hello! I'm one of the leads of https://github.com/RustCrypto
First let me start by saying I've read this:
I am also chasing down a security reference manual for a different chip from a different vendor and encountering bugs in their web site so I totally get it.
All that said, I'm wondering if you'd consider using some slightly better implementations of various algorithms than you are currently using. I was eyeing things like this in particular:
https://github.com/google/OpenSK/blob/f91d2fd/libraries/crypto/src/aes256.rs#L108
I'm aware table-based lookups in SBoxes are less of a sidechannel issue on this chipset owing to what I believe is an absence of data cache, but perhaps it'd generally be better to provide a bitsliced version anyway unless you have reasons not to do so.
I just wanted to note there's one available in the
aes-soft
crate, which may not be the most performant one in the world but is at least Apache 2.0+MIT licensed:https://github.com/RustCrypto/block-ciphers/blob/master/aes/aes-soft/src/bitslice.rs
If you're amenable to this kind of thing, we would love to collaborate on high-quality pure Rust cryptography implementations, particularly ones with a focus on embedded targets, and where there are gaps in Rust as a language today for these purposes, we're also working on addressing them and would love to collaborate on that too.
Anyway, this is a very interesting project and I'm sure you're looking forward to getting the CryptoCell going!
The text was updated successfully, but these errors were encountered: