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

Handle decoy packets in handshake #65

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nyonson
Copy link
Collaborator

@nyonson nyonson commented Sep 17, 2024

This adds support for receiving (and ignoring) decoy packets in the handshake before the final version packet is sent.

Without this patch, our handshake fails if any decoy packets are sent in the handshake because it currently assumes that only a version packet is sent. This hasn't bitten us yet because Core doesn't send decoys, but it is definitely not meeting the spec. The spec has the specifics on the decoy packets.

Encrypted packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point from here on. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document.

They can be sent immediately after the garbage terminator in the handshake ("here" in the above quote is right after the materials are generated, before the version packet). The only requirement is that the first packet sent, which can be a decoy or the version packet, has the garbage authentication in the AAD. Other than that there are actually very little requirements for the decoy packets which makes them a bit of burden.

Closes #28

Core Support

As of v28.0rc2, Core does not support sending decoys in the handshake. In V2Transport::ProcessReceivedKeyBytes, the version packet is sent right after the garbage terminator. This has been Core's behavior since BIP324 was implemented in v26. This begs the question, should this complexity of decoy packets in the handshake even exist?

Handshake Tweaks

The Handshake is attempting to do a lot under the hood for the caller before handing off responsibilities with the PacketHandler. The PacketHandler is able to pretty easily expose the allocation responsibilities to the caller, they either need the 3 bytes for length or the length of the message. In the Handshake however there might be a variable amount of decoy packets right in the middle. This flexibility is tough to handle without allocation.

Attempting to find a middle ground between robustness and usability, I initially went with a new const MAX_HANDSHAKE_PACKET_BYTES to keep the whole process sans-io. The trade off is that a large decoy package will blow the whole thing up. Ideally, decoy messages look like real communication so I don't believe there is much incentive to send super large packets, but this still felt pretty fragile so went back to the drawing board.

I added a new error variant to the module, BufferTooSmall, which is returned by the handshake function if it is unable to decrypt the decoy and version packets. A authenticate_garbage_and_version_with_alloc wrapper function which requires alloc also shows a nice pattern for callers to expand their buffers when necessary.

Error Variants

I added the BufferTooSmall variant and noticed we had been abusing MessageLengthTooSmall in a few spots. We may want to consider renaming that one for its remaining use cases.

Next Up

Plan is to add decoy sending support, along with more unit tests, in a follow up patch. The sending functions will make it way easier to add tests. All existing tests are covering the pre-decoy paths which is all we support at the moment so feel pretty good about this one for now.

@nyonson nyonson force-pushed the support-decoy-packets branch 5 times, most recently from e3abcfd to 08de18a Compare September 17, 2024 21:07
@nyonson nyonson marked this pull request as ready for review September 17, 2024 21:35
@nyonson nyonson force-pushed the support-decoy-packets branch 4 times, most recently from d95feb3 to 00ee4b4 Compare September 20, 2024 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle decoy packets in handshake
1 participant