briansmith / ring

Safe, fast, small crypto using Rust
Other
3.7k stars 698 forks source link

Document the (intended/future) design of `ring::rand` #1875

Open briansmith opened 8 months ago

briansmith commented 8 months ago

For the FIPS project, we need to extend the API in a way such that the user can be sure that they are using a FIPS-validated of SecureRandom. What this looks like exactly is TBD. Once the FIPS project is further along we can investigate if/how we can make ring::rand more convenient to use.

The ring::rand API is intended to be used in the way it is used in ring's own APIs: crypto functions that are randomized in some way take a &SecureRandom and otherwise the API is assumed to be deterministic. Thus very few functions in the user's library would reference SystemRandom at all. In practice we haven't yet implemented enough of the planned design to make this practical, but it is still the plan.

The original idea was that an application will be able to call generate() in a single place (or very few places) and pass the randomly-generated bytes around in such a way that they can be safetly consumed at most once. Thus, the user library would not need to keep a reference to a SecureRandom for very long, and it wouldn't impact their API much. So, for example, in a TLS implementation, at the very beginning of the handshake, the TLS implementation would generate() all the random data needed for the handshake. This way we could batch all the randomness generation into a single syscall. The intent was/is that there would be ways of partitioning a ring::rand::Random into multiple parts and also use a ring::rand::Random as a SecureRandom. But we never got around to implementing this design. So, now the expectation is that a TLS implementation (or similar) would thread a SystemRandom through its handshake state machine. (This isn't how Rustls has done it up to now, at least last time I looked; perhaps it is easier to do now after recent refactorings in Rustls.)

Now with the FIPS project we'll have to see if the original intent can/should still be implemented, or whether we will resign ourselves to optimizing the API for a userspace (in-library) implementation, in which case we expect the batching idea to not be necessary.

Summarizing the current situation: