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

various improvements to the packet number generator #2905

Merged
merged 3 commits into from
Dec 15, 2020

Conversation

marten-seemann
Copy link
Member

@marten-seemann marten-seemann commented Nov 26, 2020

Fixes #398.

We skip packet numbers to defend against the Optimistic ACK attack.

  1. Reduce calls to crypto/rand.Read. Instead, use a math/rand.Rand, initialized with cryptographic random.
  2. Only skip packet numbers in the application data packet number space. Initial and Handshake packets are only used for very few packets during the connection, so there was only a small chance we'd skip a PN there anyway.
  3. Implement an exponential backoff for skipping packet numbers, starting at an expected frequency of once per 256 packets, going up to once per 128*1024 packets.

A good way to think about this is by looking at the packet numbers skipped per max congestion windows (10000 packets). The current algorithm skips (on average) one PN in 500, which leads to 20 skipped packet numbers per cwnd (and therefore, per RTT). As a consequence, the ACK frames will have roughly 20 ACK ranges (assuming no packet loss). Clearly, this is a waste.

@codecov
Copy link

codecov bot commented Nov 26, 2020

Codecov Report

Merging #2905 (431dff2) into master (325bc16) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2905      +/-   ##
==========================================
+ Coverage   86.22%   86.23%   +0.01%     
==========================================
  Files         132      132              
  Lines        9141     9150       +9     
==========================================
+ Hits         7881     7890       +9     
  Misses        910      910              
  Partials      350      350              
Impacted Files Coverage Δ
internal/ackhandler/packet_number_generator.go 100.00% <100.00%> (ø)
internal/ackhandler/sent_packet_handler.go 78.00% <100.00%> (+0.28%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 325bc16...431dff2. Read the comment docs.

Copy link
Member

@lucas-clemente lucas-clemente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but two questions:

  • Why isn't the optimistic ack attack an issue for long-lived connections? Sure, it requires more upfront investment from an attacker, but then they can still max out the server's connection "for free"?
  • Using a mathematical PRNG seeded with cryptographic random means an attacker could (in principle) reconstruct the seed, and avoid the defense. Not an issue if we don't worry about long-lived connections.

@marten-seemann
Copy link
Member Author

Why isn't the optimistic ack attack an issue for long-lived connections? Sure, it requires more upfront investment from an attacker, but then they can still max out the server's connection "for free"?

It is, but we don't need a check every n packets. Note that we never stop skipping packet numbers, we just do it less and less frequently. By using exponential backoff, we make sure that the peer received about as many packets as it can expect to receive before the next skip as it has already successfully acknowledged. I believe that this is "good enough" defense against an attack that is not that costly on our side.

Using a mathematical PRNG seeded with cryptographic random means an attacker could (in principle) reconstruct the seed, and avoid the defense. Not an issue if we don't worry about long-lived connections.

Unfortunately, I don't have precise numbers here how many numbers you can receive from math/rand.Rand before it becomes feasible to reconstruct the internal state. My intuition is many, and I'm assuming that's good enough to make this attack impractical in practice.

@marten-seemann marten-seemann merged commit 4867389 into master Dec 15, 2020
@marten-seemann marten-seemann deleted the improve-packet-number-generator branch December 15, 2020 03:35
@aschmahmann aschmahmann mentioned this pull request May 14, 2021
71 tasks
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.

reduce frequency of skipped packets on long-lived connections
2 participants