Skip to content
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 RdSeed when available, and reduce RdRand load #15250

Merged
merged 1 commit into from Feb 18, 2019

Conversation

Projects
None yet
9 participants
@sipa
Copy link
Member

commented Jan 25, 2019

This introduces support for autodetecting and using the RdSeed instruction on x86/x86_64 systems.

In addition:

  • In SeedFast, only 64 bits of entropy are generated through RdRand (256 was relatively slow).
  • In SeedStartup, 256 bits of entropy are generated, using RdSeed (preferably) or RdRand (otherwise).

@sipa sipa force-pushed the sipa:201901_rdseed branch 2 times, most recently from 4dddd07 to 83ebab1 Jan 25, 2019

@practicalswift

This comment has been minimized.

Copy link
Member

commented Jan 25, 2019

While you're changing random.cpp: isn't the std::move on L562 without any effect? Could be removed?

@sipa

This comment has been minimized.

Copy link
Member Author

commented Jan 25, 2019

@practicalswift MixExtract intentionally takes an rvalue reference, so that callers must either pass in a temporary, or use std::move explicitly (as the hasher object becomes useless after the call).

Show resolved Hide resolved src/random.cpp Outdated
Show resolved Hide resolved src/random.cpp Outdated
Show resolved Hide resolved src/random.cpp Outdated

@sipa sipa force-pushed the sipa:201901_rdseed branch from 83ebab1 to 6739643 Jan 26, 2019

@sipa

This comment has been minimized.

Copy link
Member Author

commented Jan 26, 2019

@gmaxwell Wow, I didn't know about those failure modes of RdRand and RdSeed. Rewrote things a bit to take that into account. RdRand is now retried up to 10 times (and ignored after that). RdSeed is retried indefinitely (with a pause in between). When using RdRand for 256-bit seeding, it's invoked 1024 times and XORed to produce each 64 bit group.

@gmaxwell

This comment has been minimized.

Copy link
Member

commented Jan 28, 2019

utACK

@Empact
Copy link
Member

left a comment

Concept ACK. Apologies if any of the above is particularly naive. :P

Show resolved Hide resolved src/random.cpp Outdated
Show resolved Hide resolved src/random.cpp
Show resolved Hide resolved src/random.cpp
Show resolved Hide resolved src/random.cpp Outdated
Show resolved Hide resolved src/random.cpp
Show resolved Hide resolved src/random.cpp
Show resolved Hide resolved src/random.cpp Outdated
Show resolved Hide resolved src/random.cpp Outdated

@sipa sipa force-pushed the sipa:201901_rdseed branch from 6739643 to eab3817 Feb 3, 2019

Use RdSeed when available, and reduce RdRand load
This introduces support for autodetecting and using the RdSeed instruction.

In addition:
* In SeedFast, only 64 bits of entropy are generated through RdRand (256 was relatively slow).
* In SeedStartup, 256 bits of entropy are generated, using RdSeed (preferably) or RdRand (otherwise).

@sipa sipa force-pushed the sipa:201901_rdseed branch from eab3817 to 1435fab Feb 4, 2019

@gmaxwell

This comment has been minimized.

Copy link
Member

commented Feb 7, 2019

ACK

@gmaxwell

This comment has been minimized.

Copy link
Member

commented Feb 7, 2019

Aside, we might want to consider this one a bug fix, since technically we weren't using rdrand quite correctly before. OTOH, the use of rdrand was entirely non-critical... sooo...

@MarcoFalke MarcoFalke added this to the 0.18.0 milestone Feb 7, 2019

@laanwj

This comment has been minimized.

Copy link
Member

commented Feb 12, 2019

So to be clear: this doesn't result in a CPU with broken and/or backdoored RDRAND or RDSEED instruction to generate vulberable private keys?

@sipa

This comment has been minimized.

Copy link
Member Author

commented Feb 12, 2019

@laanwj Not trivially, at least. The output of the rdrand/rdseed is mixed with other entropy using SHA512 to produce output and the new state.

In theory a backdoored CPU could try to infer what variable is going to store entropy, and try to control that directly.

@laanwj

This comment has been minimized.

Copy link
Member

commented Feb 12, 2019

Thanks!

In theory a backdoored CPU could try to infer what variable is going to store entropy, and try to control that directly.

Sure—I meant when say, only those instructions were made to return a fixed value, not anything more advanced/complex. Like a bugdoor with plausible deniability.

@laanwj

This comment has been minimized.

Copy link
Member

commented Feb 13, 2019

Code review utACK 1435fab
I have no hardware to be able to test this on.
(if you do, /proc/cpuinfo will show the rdrand and/or rdseed under flags)

@JustinTArthur

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2019

ACK 1435fab on macOS x86_64 on Intel Core i7-7920HQ CPU @ 3.10GHz (has RDRAND & RDSEED).

2019-02-13T19:22:30Z Using the 'sse4(1way),sse41(4way),avx2(8way)' SHA256 implementation
2019-02-13T19:22:30Z Using RdSeed as additional entropy source
2019-02-13T19:22:30Z Using RdRand as an additional entropy source

Functional and unit tests pass.

@sipa

This comment has been minimized.

Copy link
Member Author

commented Feb 13, 2019

Tested on a system with RdRand but no RdSeed; tests pass, bitcoind runs fine, and reports only "Using RdRand as an additional entropy source".

@gmaxwell

This comment has been minimized.

Copy link
Member

commented Feb 14, 2019

Tested on a system with no rdrand/rdseed, and it didn't catch fire. does @luke-jr maybe have a 32-bit system with rdrand/rdseed?

@gmaxwell

This comment has been minimized.

Copy link
Member

commented Feb 14, 2019

@laanwj To expand on Pieter's response. Our mixing construction is designed to be secure against adversarial inputs generated by an attacker that can also inspect the entire process state unless the attacker can attack SHA512 in a very serious way (e.g. construct a suffix to a message being hashed that causes a specific hash value).

There are various standards for combining entropy sources that just xor the sources. The construction we're using is obviously stronger than those. If we had just xored the state then a malicious rdrand could inspect and return the current state (perhaps xored with a constant) in order to override it, and even plausibly do so as a bugdoor (e.g. oops we accidentally failed to update the register). I just mention this to point out that what we're doing is stronger than something other people think is acceptable...

@pstratem

This comment has been minimized.

Copy link
Contributor

commented Feb 14, 2019

@gmaxwell
Linux debian 4.9.0-8-686-pae #1 SMP Debian 4.9.130-2 (2018-10-27) i686 GNU/Linux 2019-02-14T21:30:29Z Using RdSeed as additional entropy source 2019-02-14T21:30:29Z Using RdRand as an additional entropy source

@laanwj laanwj merged commit 1435fab into bitcoin:master Feb 18, 2019

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

laanwj added a commit that referenced this pull request Feb 18, 2019

Merge #15250: Use RdSeed when available, and reduce RdRand load
1435fab Use RdSeed when available, and reduce RdRand load (Pieter Wuille)

Pull request description:

  This introduces support for autodetecting and using the RdSeed instruction on x86/x86_64 systems.

  In addition:
  * In SeedFast, only 64 bits of entropy are generated through RdRand (256 was relatively slow).
  * In SeedStartup, 256 bits of entropy are generated, using RdSeed (preferably) or RdRand (otherwise).

Tree-SHA512: fb7d3e22e93e14592f4b07282aa79d7c3cc4e9debdd9978580b8d2562bbad345e289bf3f80de2c50c9b50b8bac2aa9b838f9f272f7f8d43f1efc0913aa8acce3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.