-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Use system random generator in crypto #5798
Comments
Instead of linking to a blog post, please summarize the pros and cons here. |
Perhaps @joepie91 or @paragonie-scott would be interested to elaborate that here. |
From "a blog post":
Additionally, OpenSSL's userspace PRNG has caused issues in other languages (PHP under Apache for sure) because it's not fork-safe, which caused random numbers to repeat. (Combine this with the consequences of nonce reuse for most stream ciphers and boom your cryptosystem loses all privacy.) A safer bet would be to adopt what PHP 7's |
OpenSSL's PRNG is seeded from /dev/{,s,u}random, can get entropy from entropy-collecting daemons, and forking is not an issue for node.js. So far I'm not seeing a compelling reason to switch. |
@paragonie-scott That's does not look like a good reasoning. Could you please be more calm? ;-) |
@bnoordhuis Trying to find specific reasons to explain away potential issues is not a good approach to security-related matters. The issues exist, and there's no way to predict how Node will evolve - for example, if fork-safety might start to matter due to future changes, at which point people will likely have forgotten about this specific issue. We should be striving for the optimally secure implementation (within technical constraints), instead of attempting to 'defend' the current implementation when there are known edge cases / issues with it. This post addresses that further. |
I do not yet have a strong opinion on this. I called @joepie91 and @paragonie-scott here because they expressed similar considerations as @speakeasypuncture in an IRC chat earlier. @bnoordhuis, as I understand their points, the reasons here are:
Everyone — did I miss anything? |
Again: I do not yet have a strong opinion on this. I would like to hear what would the drawbacks of this change be, and is there something where (or why) OpenSSL PRNG could be better than the system PRNG. |
/cc @nodejs/crypto. |
@mscdex I'm not sure if this is a «feature request», it looks like a proposal to change the implementation of |
@ChALkeR Your summary seems accurate to me. |
Also, random number generators are hot-swappable without compatibility concerns, only security concerns. |
I'm -1 on this, no compelling reasons for me. |
@indutny Please refer back to this comment in particular, plus several others in the thread. There is a lack of reasons not to do this (insofar anybody has stated them, that is), while there are documented reasons to do it. If you feel that there is a reason not to do it, then please share it - but "no compelling reasons for me" really isn't a sufficient argument for a security-related matter. Even a small defect can have disastrous consequences. |
@joepie91 sure, sorry for too short reply. What about systems with "good" PRNG? How many of them are there? Do we have to carry both implementations to support them? |
@indutny Thanks for the elaboration. As I understand it (and please correct me if not), OpenSSL depends on the system PRNG to begin with. I'm not aware of any platforms (of those supported by Node, that is) where OpenSSL can provide a better PRNG than the one that the system offers natively. It should thus be possible to just remove OpenSSL's PRNG from the equation entirely, and rely purely on the system PRNG, as PHP has done. |
@joepie91 do you suggest to use this randomness for TLS protocol as well? I'm not sure if it is possible, though. |
While that would probably be nice (albeit requiring more investigation), I don't think that's doable. As far as I know, OpenSSL's other functionality relies internally on its own PRNG with no ability to change that - unless we want to get rid of OpenSSL entirely, which would be a separate proposal (and likely not viable at this stage, given the lack of well-tested alternatives). So, this specific proposal would concern the "user-facing" |
Ok, considering arguments it probably make more sense now. |
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js. If (generic) you think moving to platform-specific solutions is the way forward, get OpenSSL to adopt your approach and node.js will automatically go along. I believe @paragonie-scott is volunteering? He sure seems to feel strongly about it.
@joepie91 The bucket list of fork-safety issues that would have to be addressed is so long that I think it's safe to say that node.js will never be fork-safe. There are many things that keep me awake at night but this is not one of them. |
I don't believe this argument holds any merit, honestly. ~FreeBSD are not just going to push broken code~~ EDIT: FreeBSD are not going to push broken code to the -STABLE kernel branch, especially when they have a perfectly functional CSPRNG already, and especially as they have a security team of their own who would definitely catch any changes to the CSPRNG which would lead to a vulnerability in the OS. I'm going to be frank, here: Attempting to justify away security issues is downright irresponsible, and possibly dangerous. You need to strive for bulletproof security, or you may as well not implement any security at all (And no, don't twist this to mean "Don't bother with security", because that's just lazy.) I appreciate it's "extra work" to make a change like this, but considering you're using a PRNG which has actually caused security issues in the past, I'd err on the safe side and move to something more provably secure. |
Besides being an appeal to authority, you're asking (generic) me to trust several teams of implementors (the platforms) instead of just one (OpenSSL) to get their implementation right.
Are you saying you feel OpenSSL's PRNG is insecure? If so, why aren't you taking that up with the OpenSSL team? Griping about it here isn't going to do any good. I'll repeat what I've said above: get the upstream project to move over, and we as downstream consumers will automatically move along with it. |
Yet OpenSSL's PRNG relies on these platform-specific PRNGs, and mixing in one broken PRNG can weaken the entire (combined) PRNG. How does relying on OpenSSL fix the issue you've described?
That is a very dangerous assumption to make.
I think the existence of this project should give an indication. At this stage, there's a fairly wide consensus around the security community that OpenSSL is awful software, and the only real reason it is still being recommended is because it's what has been tested in the real world for so long. Not because it is of high quality or well-maintained. |
This is a common argument that people make, but it's ultimately invalid. Even if you avoid depending on the operating system's PRNG, the rest of your system definitely depends on it for security. Node.js will be compromised regardless of what Node.js does. |
Just a bit of FYI for everyone here: http://lwn.net/Articles/633805/rss "FreeBSD random number generator broken for last 4 months" |
@indutny Note that it also affects keys generated by Node.js on FreeBSD (using
|
Any changes to OpenSSL, even if they improve in this space, are going to show up on a new major release, which moves much, much slower than Node. If they made a great release tomorrow, it will take years to hit some distributions at all. I don't feel you want to wait on this. |
Node.js doesn't use the operating system's OpenSSL. Node.js ships with its own copy of OpenSSL. |
I might be open to bundling libsodium in addition to openssl but that should be its own issue because there will be numerous details to hash out. We sure as heck are not going to ship something homegrown and until openssl grows the requisite APIs there isn't anything actionable. I'm closing this again and I'm locking it to prevent this already humongous thread from growing bigger. |
@MylesBorins Re: FIPS compliance — if libsodium |
Note that openssl 1.1 won't be FIPS compliant for quite a while, so FIPS users will need to stick to a node built on 1.0. cf. https://www.openssl.org/blog/blog/2016/07/20/fips/ I'm still hopeful that OpenSSL will deal with this for us, I'm not saying we should be thinking of libsodium for 8.x, but I don't think FIPS would be a blocker if we go looking elsewhere for a PRNG. Also, I'm not sure random seeds are covered by FIPS, anyway, that would take some looking into. |
Note that OpenSSL has just landed a commit to use DRGB with AES-CTR of NIST SP 800-90A as openssl/openssl@75e2c87. We can use it with the os-specific seeding source (e.g. /dev/urandom) by a default define flag of |
[Edited arguments for and against based on feedback] I'm going to attempt to summarize the conversation and arguments that have happened on this issue. Sorry if I missed your post, I can amend. Preliminaries@speakeasypuncture initially opened this issue. Issue statementNode's
I do not believe anyone has claimed that OpenSSL's CSPRNG is currently broken, although @ChALkeR pointed out some reasons why it might not be trustworthy. ProposalNode should consider an alternative implementation for random numbers that is definitely derived securely.
Arguments againstThe major arguments from the Node maintainers (and I may be reading between the lines a little bit) appear to be:
Peer pressure
My impressions
|
There's an upstream proposal to make OpenSSL create the equivalent of libsodium's Swapping out one userspace PRNG for another userspace PRNG is not a fix. Bypassing the userspace and using the OS's CSPRNG is the solution. |
It's not actionable at the moment and won't be for a long time to come. Inactionable items clog up the bug tracker so I'll close this out for now. We can revisit when we upgrade to an openssl version that supports this new API. |
@bnoordhuis How are we going to remember to revisit it, then? Perhaps introducing a separate label for temporary-inactionable items that were closed just because of that is needed so we don't forget to revisit? |
We go over the changelog with a fine-tooth comb whenever we upgrade (at least I do) so it's unlikely that such a change would go unnoticed.
I'm not completely opposed. |
Thanks for summarizing, but I don't think that captures the point. We are not advocating for reimplementing something that's in a library (for whatever reason), but for removing the library entirely. The library implements a user-space CSPRNG on top of kernel entropy, it might be good or bad, doesn't matter, we are arguing for not using one at all. What you say is valid about primitives, which have to be implemented somewhere, but here we are talking about removing a layer from a system, where each layer is an independent point of failure. As for "they are the ones that know about security", OpenSSL is bound by a lot of legacy, BoringSSL and libsodium are widely regarded as secure modern implementations, and those use the kernel CSPRNG. |
@FiloSottile Thanks, I've amended my post. Holler if you're still unhappy with my representations. |
What's the current status with this issue? |
@atoponce I could well have made a mistake somewhere, but tracing randomBytes appears to land here: In which we first call RAND_status and then RAND_byes, these being OpenSSL functions. |
randomBytes uses OpenSSL as its random number generator. It would be wiser and less errorprone to use a system RNG like urandom on Unix platforms, getrandom syscall on Linux and CryptGenRandom on Windows.
The text was updated successfully, but these errors were encountered: