-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Add p2p layer encryption with ECDH/ChaCha20Poly1305 #14032
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
Conversation
src/net.cpp
Outdated
CNetMessage& msg = vRecvMsg.back(); | ||
if (vRecvMsg.empty() || vRecvMsg.back()->complete()) { | ||
if (m_encryption_handler && m_encryption_handler->shouldCryptMsg()) { | ||
vRecvMsg.emplace_back(std::make_shared<NetCryptedMessageEnvelop>(m_encryption_handler, Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Should this be ”envelope” instead of ”envelop”? If so, change applies throughout this PR and also the BIP.
src/init.cpp
Outdated
@@ -477,6 +478,7 @@ void SetupServerArgs() | |||
gArgs.AddArg("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE), true, OptionsCategory::DEBUG_TEST); | |||
gArgs.AddArg("-maxtxfee=<amt>", strprintf("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)", | |||
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), false, OptionsCategory::DEBUG_TEST); | |||
gArgs.AddArg("-netencryptionfastrekey", "Rekeys every 10 seconds and after 10kb of data", true, OptionsCategory::DEBUG_TEST); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I’m reading the logic correct then this should be ”every 10 seconds or after 10kb of data”?
src/net.cpp
Outdated
msg->nTime = nTimeMicros; | ||
if (msg->m_type == NetMessageType::PLAINTEXT_ENCRYPTION_HANDSHAKE && !msg->verifyHeader()) { | ||
// message contains expected network magic and "version" message command | ||
// threat as version message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: “treat”
src/net_encryption.cpp
Outdated
LOCK(cs); | ||
if (m_bytes_decrypted + vsize > ABORT_LIMIT_BYTES || GetTime() - m_time_last_rekey_send > ABORT_LIMIT_TIME || | ||
(gArgs.GetBoolArg("-netencryptionfastrekey", false) && m_bytes_decrypted + vsize > 12 * 1024)) { | ||
// don't further decrypt and therefor abort connection when counterparty failed to respect rekey limits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: “therefore”?
src/net_message.h
Outdated
} | ||
|
||
virtual bool complete() const = 0; | ||
virtual uint32_t getMessageSize() const = 0; //returns 0 when message hat not yet been parsed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: “has”?
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
e654fd6
to
4e4aedd
Compare
Fixed @practicalswift points. |
Great work! Although optimized crypto is certainly out of scope, we do want to be mindful of making any protocol decisions that would preclude using them. :) |
4e4aedd
to
603490f
Compare
Note to reviewers: please review...
|
603490f
to
c9b3c58
Compare
What is the point of |
This has now been discussed on IRC: |
c9b3c58
to
93f64ad
Compare
src/net_encryption.cpp
Outdated
{ | ||
// first 3 bytes are the LE uint32 message length the most significant bit | ||
// indicates to the counterparty that the next message will be using the next | ||
// key (rekey) with resetted nonce |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be “reset”?
bdc9b75
to
39bf10f
Compare
Needs rebase |
…ate key 8794a4b QA: add test for HKDF HMAC_SHA256 L32 (Jonas Schnelli) 551d489 Add HKDF HMAC_SHA256 L=32 implementations (Jonas Schnelli) 3b64f85 QA: add test for CKey::Negate() (Jonas Schnelli) 463921b CKey: add method to negate the key (Jonas Schnelli) Pull request description: This adds a limited implementation of `HKDF` (defined by rfc5869) that supports only HMAC-SHA256 and length output of 32 bytes (will be required for v2 transport protocol). This PR also includes a method to negate a private key which is useful to enforce public keys starting with 0x02 (or 0x03) (a requirement for the v2 transport protocol). The new `CKey::Negate()` method is pretty much a wrapper around `secp256k1_ec_privkey_negate()`. Including tests. This is a subset of bitcoin#14032 and a pre-requirement for the v2 transport protocol. ACKs for commit 8794a4: Tree-SHA512: 5341929dfa29f5da766ec3612784baec6a3ad69972f08b5a985a8aafdae4dae36f104a2b888d1f5d1f33561456bd111f960d7e32c2cc4fd18e48358468f26c1a
…ate key 8794a4b QA: add test for HKDF HMAC_SHA256 L32 (Jonas Schnelli) 551d489 Add HKDF HMAC_SHA256 L=32 implementations (Jonas Schnelli) 3b64f85 QA: add test for CKey::Negate() (Jonas Schnelli) 463921b CKey: add method to negate the key (Jonas Schnelli) Pull request description: This adds a limited implementation of `HKDF` (defined by rfc5869) that supports only HMAC-SHA256 and length output of 32 bytes (will be required for v2 transport protocol). This PR also includes a method to negate a private key which is useful to enforce public keys starting with 0x02 (or 0x03) (a requirement for the v2 transport protocol). The new `CKey::Negate()` method is pretty much a wrapper around `secp256k1_ec_privkey_negate()`. Including tests. This is a subset of bitcoin#14032 and a pre-requirement for the v2 transport protocol. ACKs for commit 8794a4: Tree-SHA512: 5341929dfa29f5da766ec3612784baec6a3ad69972f08b5a985a8aafdae4dae36f104a2b888d1f5d1f33561456bd111f960d7e32c2cc4fd18e48358468f26c1a Signed-off-by: Pasta <pasta@dashboost.org>
CNetMessage& msg = vRecvMsg.back(); | ||
if (vRecvMsg.empty() || vRecvMsg.back()->Complete()) { | ||
if (m_encryption_handler && m_encryption_handler->ShouldCryptMsg()) { | ||
vRecvMsg.emplace_back(MakeUnique<NetV2Message>(m_encryption_handler, Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use std::make_unique
in new code.
…ate key 8794a4b QA: add test for HKDF HMAC_SHA256 L32 (Jonas Schnelli) 551d489 Add HKDF HMAC_SHA256 L=32 implementations (Jonas Schnelli) 3b64f85 QA: add test for CKey::Negate() (Jonas Schnelli) 463921b CKey: add method to negate the key (Jonas Schnelli) Pull request description: This adds a limited implementation of `HKDF` (defined by rfc5869) that supports only HMAC-SHA256 and length output of 32 bytes (will be required for v2 transport protocol). This PR also includes a method to negate a private key which is useful to enforce public keys starting with 0x02 (or 0x03) (a requirement for the v2 transport protocol). The new `CKey::Negate()` method is pretty much a wrapper around `secp256k1_ec_privkey_negate()`. Including tests. This is a subset of bitcoin#14032 and a pre-requirement for the v2 transport protocol. ACKs for commit 8794a4: Tree-SHA512: 5341929dfa29f5da766ec3612784baec6a3ad69972f08b5a985a8aafdae4dae36f104a2b888d1f5d1f33561456bd111f960d7e32c2cc4fd18e48358468f26c1a
…ate key 8794a4b QA: add test for HKDF HMAC_SHA256 L32 (Jonas Schnelli) 551d489 Add HKDF HMAC_SHA256 L=32 implementations (Jonas Schnelli) 3b64f85 QA: add test for CKey::Negate() (Jonas Schnelli) 463921b CKey: add method to negate the key (Jonas Schnelli) Pull request description: This adds a limited implementation of `HKDF` (defined by rfc5869) that supports only HMAC-SHA256 and length output of 32 bytes (will be required for v2 transport protocol). This PR also includes a method to negate a private key which is useful to enforce public keys starting with 0x02 (or 0x03) (a requirement for the v2 transport protocol). The new `CKey::Negate()` method is pretty much a wrapper around `secp256k1_ec_privkey_negate()`. Including tests. This is a subset of bitcoin#14032 and a pre-requirement for the v2 transport protocol. ACKs for commit 8794a4: Tree-SHA512: 5341929dfa29f5da766ec3612784baec6a3ad69972f08b5a985a8aafdae4dae36f104a2b888d1f5d1f33561456bd111f960d7e32c2cc4fd18e48358468f26c1a
My understanding is that someone else is helping with / taking over these changes, and that the BIP is still being overhauled. |
…ate key 8794a4b QA: add test for HKDF HMAC_SHA256 L32 (Jonas Schnelli) 551d489 Add HKDF HMAC_SHA256 L=32 implementations (Jonas Schnelli) 3b64f85 QA: add test for CKey::Negate() (Jonas Schnelli) 463921b CKey: add method to negate the key (Jonas Schnelli) Pull request description: This adds a limited implementation of `HKDF` (defined by rfc5869) that supports only HMAC-SHA256 and length output of 32 bytes (will be required for v2 transport protocol). This PR also includes a method to negate a private key which is useful to enforce public keys starting with 0x02 (or 0x03) (a requirement for the v2 transport protocol). The new `CKey::Negate()` method is pretty much a wrapper around `secp256k1_ec_privkey_negate()`. Including tests. This is a subset of bitcoin#14032 and a pre-requirement for the v2 transport protocol. ACKs for commit 8794a4: Tree-SHA512: 5341929dfa29f5da766ec3612784baec6a3ad69972f08b5a985a8aafdae4dae36f104a2b888d1f5d1f33561456bd111f960d7e32c2cc4fd18e48358468f26c1a
This PR adds encryption to the p2p communication after a slightly overhauled version of BIP151 defined here (there is the plan to change BIP151 or to propose this protocol in a new BIP)
The encryption is optional and by default disabled (
-netencryption
).If enabled, a peer connecting to another peer signalling
NODE_ENCRYPTED
(or added via-connect=
) will try to do the proposed key handshake and continue with encrypted communication.If enabled, peers can request (and perform) encrypted communications by sending a handshake request.
Peers not supporting encryption are still accepted (no option to enforce encrypted communication).
There is a plan to make the handshake quantum resistance by adding NewHope to the key handshake (https://newhopecrypto.org). But since this PR is already very large, it's unclear wether this should be an independent patch (probably another ~600 lines of code).
Out of scope:
TODO:
-connect=
RPCaddnode
where it is possible to specify the expected service flags (currently-connect=
will always try for encrypted coms).