-
Notifications
You must be signed in to change notification settings - Fork 432
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
OsRng
crate? (or optional PRNG dependencies)
#648
Comments
Just my two cents on this issue: I think a safe default would be for rand to only provide CSPRNGs by default. If you need an insecure PRNG, it should be really explicit. I don't know about the current crate hierarchy, but if it's not secure by default, if it's not blatantly obvious when using an insecure PRNG, we should move in that direction. My opinion, of course, but I have laid out why I feel this way. A crate name like insecure_random would be nice :) Security is one of the many selling points about Rust, so we should try to make it hard to mess up. |
See #643. We may move forward with this but I'd like us to explore moving the There's a lot of history involved and not wanting to break @naftulikay there are so many ways to mess up security. We now have a |
I think we should move forward with
|
I'm 💯 percent behind OsRng being part of std. On my i7 8650U laptop CPU on Linux 4.15 I can read /dev/urandom at around 112MB/s. As you described above, I do imagine that we could build some stream or block cipher based RNG which could be a lot faster; generate a large random key from /dev/urandom, use that with a symmetric cipher, and the upper bound on performance would then be the initialization cost (once) plus the speed that the cipher can run at. I could be misinformed (there are actually cryptographers around these parts @tarcieri), but using a symmetric cipher as a CSPRNG has been done in the past pretty well as long as your input key has a strong randomness guarantee. The only use case that isn't covered here is if you are concerned about renewing randomness. IIRC the kernel is constantly resampling randomness sources and mixing them into the RNG, whereas this contract is dependent on /dev/urandom being secure at the time of key generation. One thing I've always wondered is how fast PRNGs can be if they aren't CSPRNGs. ChaCha20 is pretty damn fast for a stream cipher, the original white paper claims that it's around one CPU clock cycle per byte, and I'm not sure if this is using SIMD. I hope that my comment above didn't come across as accusatory or anything, I'm grateful for all the work the rand team does on this incredibly useful crate. |
@naftulikay run Our |
I'm sorry to say (and perhaps this is a bad forum to say it), but I'm kind of "losing faith" in this crate for the purposes I want it for, which is a thin abstraction over the OS-provided cryptographically secure random number generator. There's an awful lot of complexity and code surface I don't want, which is pretty much anything besides the thinnest possible wrapper over the OS-provided cryptographically secure random number generator. Looking over the comments in #643, and in this thread, I'm confused what plan there is, if any, to get any parts of this crate into If this crate isn't prototyping functionality that is eventually destined for (As I write this, I'm presently investigating a critical RNG-related vulnerability in a project I contribute to, and the extant churn around |
@tarcieri I appreciate the criticism. This project doesn't really get enough input from the security/crypto perspective, so your input is definitely useful. Does #643 meet your requirements? Do you have other expectations? I don't believe there has been any serious effort to get any more random-number functionality into
|
So first, apologies, at the time I wrote my previous post I thought Regarding #643 (and perhaps we should just take the conversation back over there), I'm with @newpavlov on this comment:
I would like for the API to be as straightforward as possible, so abstractions which aren't necessary for purely CSRNG-cases to stay out of the way. #643 mostly accomplishes that but per your first question, and the linked comment:
This is what I want the overwhelming majority of the time personally, and would love to see it in There are a handful of cases where I do want the trait, namely when I'm testing cryptographic primitives which internally rely on randomness (e.g. ECDSA) and need to have something which implements
I would personally prefer no fallback, at least for something called
Ideally I'd like to see the knobs
That would be ideal, yes. I say this having written a |
There is an interface much like what you want internally to Just noticed clicking As an aside, we should probably adopt the |
I wonder if we should cover |
Thanks @tarcieri for the feedback. Sounds like we should proceed with #643 as is, and possibly explore adding a function like But @newpavlov has a point — a correct non-blocking API might partially fill a buffer. IIRC the current internal API may do this, but simply assumes no data was collected and retries? @burdges adding |
Agreed this is not the issue for that question, but.. I said "stream cipher", which is a low level notion. while normally "modes" deal with iv, macs, etc. I mostly wanted to highlight the |
Wouldn't There may still be an issue with using |
We discussed this before, but even PRNGs should lend themselves to specification, meaning if you write typical code using rand then you can easily later write a specification, including any the corner cases of I think We might eventuality use combinators on |
Is there an active RFC or RFCs that suggest moving things into I'd propose putting an
This puts the CSPRNG provided by the OS into the standard library, and traits defining what an As far as the actual methods exposed by
I know that putting things into Again, just thinking out loud. Getting a CSPRNG should be easy and possible from |
@naftulikay One of the questions to solve here is how to handle errors, we probably don't want to use |
I am not aware of an active RFC, but it sounds like we have enough to go on now to start one. Who would like to write it? |
@dhardy I can at least bring up the idea of an RFC for this to the Secure Code WG |
I had a go at writing an RFC: https://github.com/dhardy/rfcs/blob/system-random/text/0000-system-random.md No PR yet; I'll let the readers here make a first pass. Personally I'm not fully convinced this is the best course of action; especially since supporting WASM properly may be hard (and maybe other platforms). |
Actually, WASM shouldn't be too hard, as IIRC there is a JavaScript API to a secure RNG: https://www.w3.org/TR/WebCryptoAPI/ Other embedded contexts may be difficult, but these environments usually don't have std either. If we provide a trait in core and an implementation in std, this would probably be the most flexible approach. |
I, for one, would really like a lang item for this (which is talked about in @dhardy's RFC). In the past I've used Rust in unusual embedded environments (HSMs) where I needed to call out to a hardware RNG through a C library. It'd be nice to be able to leverage the randomness it produces everywhere in a Rust program, including for things in In my observation it's pretty common for embedded SDKs to support some sort of proprietary hardware-based RNG (often one which might require a little work to support a |
That's what both current impls use if used within a browser; otherwise they try Node's equivalent. The issue is simply requirement to use a JS bindings framework. @alexcrichton does Edit: updated the WASM section |
@dhardy unfortunately the standard library itself doesn't have the ability to acquire random numbers, only the ecosystem like wasm-bindgen has the ability to do that |
@alexcrichton I believe the suggestion was to add a new Then each wasm runtime (wasm-bindgen, stdweb, etc.) would provide an implementation of |
I would say a much better example will be a |
I know @alexcrichton. Sorry, I take it your answer means "no". Which is a problem for this PR — we don't have a solution to support WASM properly, unless Yes and no @newpavlov — the difference is that having an allocator is one of the defining features of |
Sorry I didn't mean to answer the wrong question, this is a long thread and I just got back from holidays... In any case we don't really have a process or way right now for |
Thanks Alex. I guess that gives me enough to write an RFC at least. |
@dhardy keep us posted, happy to contribute to that 👍 |
Would using a new lang item for a system CSRNG address this issue? (while also providing e.g. embedded platforms a way to leverage proprietary vendor-specific RNGs, possibly through closed-source SDKs) |
Good question — can lang items be specified multiple times (with placeholder and full implementations) or do they need to be specified exactly once? I don't fully understand how they work; it looks like they need hooks within the compiler, which isn't ideal just for a library function (though this was also part of the motivation for this RFC, since external linkage is only available for C FFI functions and all other options are run-time). |
@naftulikay I updated the RFC text but am still not happy with the |
@dhardy love it! I don't really have much to add, all of this seems perfectly reasonable, only to ask for some clarifications. Before I dump this wall of text, would it be helpful for us to all get together on IRC or something so we can discuss in real time? I'm not sure what the process is around previous RFCs which are much bigger than this, and long issue comment histories on GitHub are hard to weed through. We could produce our findings after the meeting in a summary comment here or on the RFC. Just a thought. API interfaceAs far as API naming is concerned, I'm ambivalent about the different options.
Both Error handlingThe error enum is a great idea, returning
I'll be speaking to Linux because it's the system CSPRNG that I'm most familiar with.
So here's the race condition. Implementors, as noted above, should always choose a non-blocking randomness source, but if they don't, there's a problem. If for some reason, Let's say that we want to read two bytes of randomness: let mut a = [0u8; 2];
let result = std::random::secure_random(&mut a); What happens here if there is only one byte available of randomness? It returns Of course, the goal is to not have blocking implementations. If we put it in Also, I hope I'm understanding properly, this is about This whole thing could be a non-issue, but it should at least be considered. Core vs StdThe RFC does a great job of handling @dhardy excellent work on the RFC, seriously A+. Again, if it'd be beneficial to get all of us in the same room (virtually of course, hangouts or IRC or something), it might save a lot of discussion time 👍 |
I think this is clearly the better name because it emphasizes that if you swap out the PRNG for a different one, it better be secure.
Neither of these names really make sense in the case of having a lang item that allows one to swap in a non-system allocator. |
It would be nice to guarantee that one can only swap in a new implementation in the top-level crate, not in a library. Also it would be nice to guarantee that the built-in implementation for a given target will always be used when it is available, so that only platforms that don't have any system PRNG would be able to use the lang item. |
@naftulikay please check the linux source: we use As for other systems — I don't know; there are a lot and also embedded devices with some type of RNG. We already have a Gitter room but don't use it much. Potentially we could piggyback https://rust-lang.zulipchat.com/# or make our own, or IRC....
Stuff I'm not sure we can do with lang items... perhaps we should go back to @pitdicker's original idea of an |
How about creating an issue for it in the |
I don't see any point prioritising this until after As for |
I still believe having But I guess this discussion could indeed wait until the crate gets published and used a bit. |
There is a lot of good discussion here, but this isn't the right place to continue it, and long GitHub threads are a pain to read. Lets move future discussion to rust-random/getrandom#21 for now. |
rand
0.6 seems to have split all of the PRNGs into their own separate crates.However, these crates are mandatory dependencies of the
rand
crate, which is still home toOsRng
.I think it'd be great if one of two things happened:
OsRng
were split into its own crate which is only dependent onrand_core
rand
crate provided cargo features for the numerous PRNGs so I don't need to pull them into my project when all I want isOsRng
.Sidebar: I'm a little confused why
rand
andrand_core
both exist. It would personally make more sense to me ifrand
contained the core traits, and anyone wanting an RNG can pick a crate with the one they want which only depends onrand
. It seems like right nowrand
is both a facade and the sole home ofOsRng
The text was updated successfully, but these errors were encountered: