-
Notifications
You must be signed in to change notification settings - Fork 720
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
If RdRand is supported, it is fully trusted #390
Comments
I believe this was known behavior at the time of the PR (See: #248 (comment)) @SalusaSecondus can you comment on this? |
urandom is used in all cases for instantiation and generation, and then we pivot to rdrand() for reseeding. We could do a XOR construction, and the latest NIST NRBG constructions do define those ... but here we're confirming to the DRBG spec which is to reseed. We do want to conform to a published specification, as we are formally verifying our implementations. One of the interesting things about a simple XOR construction is that it's the construction that's easiest to attack if the hardware isn't trusted ( https://blog.cr.yp.to/20140205-entropy.html ). It requires the attacker to no extra work, they can fully control the output bit-for-bit. With the DRBG reseed construction, an attacker who controls entropy is forced to do at least as much as work as AES_CTR to control or predict the final output. That said, the difference is only quantitative not qualitative; any attacker who controls your source of entropy essentially controls the whole stack. |
@colmmacc beat me to much of this, but to provide my independently reasoned response :-) I disagree with the statement that RDRAND is fully trusted and believe that we take reasonable precautions against issues with it.
So, absolute worse case, we lose prediction resistance, but maintain a DRBG based on 384 bits of entropy. Personally, I think this scenario is so unlikely as to be essentially impossible. (Not that I fully trust RDRAND, but the various ways in which it might be untrustworthy are still likely to introduce entropy with the weaknesses mitigated by this construction.) That's not too bad. Have you actually measured the time difference to ensure that it would be negligible? |
I was wrong in my analysis, you first seed it with data from urandom then change the entropy source to RdRand, so you do get 256 bits of entropy first (32B * 8b=256b, I can't seem to find the 384b):
However, this 256b is collected at the "worst" time: at startup, which for an isolated system (e.g. virtual machine just spinned up with minimal interfaces) may not have much entorpy. Which begs the question... in case RdRand is not available, do you only add new entropy after 34359738368 bytes have been produced? That's kinda scary, I'd think. Again, this 256b of urandom data could be right after startup that you use for so long. |
I was also wrong, it is 256b, not 384b. (I've been reading the specs for the AES-CTR-DRBG based on AES-256, which uses 384b of entropy, unlike the 256b of entropy used by the AES-128 form used in s2n.) As for lack of prediction resistance when RDRAND isn't present, you are correct. We originally had it however it was removed in 0819910 due to performance issues. |
So would adding support for the From the link:
We already have an open issue for adding the syscall here: #17 |
@alexw91 I would be very weary of blocking calls. You'll have plenty of entries with "system hangs on s2e call" in the issue tracker. That's not the solution, I think. Instead, entropy pools (a la Fortuna https://www.schneier.com/academic/fortuna/ ) is I think the right solution. It should call urandom (i.e. non-blocking), but Fortuna has pools that are used to re-seed at different (exponentially different) intervals. That fixes the issue of "when to reseed" -- because too soon means not enough entropy has been accumulated, and too late means too much randomness has been used already that leaked information/was insecure. Take a look at its design, it's really very well-done (and designed by one of the best in the field). PS: an advantage to having a blocking call would be that we'd get feedback on how many times it blocks on virtual or embedded systems. I'm afraid it won't be too glorious a feedback, but it would be a very good data point. |
To boot, getrandom() is only available on the the most bleeding-edge glibc :/ |
I think we're in a place where we can close this issue. As noted earlier #17 moves As noted, Finally, both Colm and I addressed why we believe that the current design properly handles varying levels of trust in Unless significant objections are raised, I will close this issue next week. |
The system reseeds every time from RdRand in case RdRand is available, and does not use urandom at all, which typically uses multiple sources of randomness. This means that the RdRand by Intel is fully trusted, /dev/urandom will not play a part. It would be possible to use urandom for seeding&generation and then XOR in RdRand, whitening the output. The security should only improve, and time spent would be essentially the same. Affected code:
Instantiate will always set
entropy_generator
if RdRand is available:The text was updated successfully, but these errors were encountered: