Initial packet number need not be zero
We should investigate using a random non-zero small integer as the initial packet number for a connection, to increase entropy a bit.
I can work on this. Can you point me to the rough code location where one would implement this? I've just had a look around for ~30mins but haven't found an obvious spot yet.
https://github.com/mozilla/neqo/blob/main/neqo-transport/src/crypto.rs#L430 and the code that is using it.
After experimenting with this a bit and looking at the relevant QUIC RFC section I've got some questions for clarification:
- Do I understand correctly that the intended behavior for this would be to randomize the starting packet number for the initial space of a new connection? Not the starting (e.g. initial) packet number of any packet number space. Meaning around "initial" can be a bit unclear here, thus the question.
- The RFC explicitly states
Packet numbers in each space start at packet number 0.in the section linked above. Is this still something we'd want to investigate? I'd imagine this could lead to a bunch of breakage if servers make assumptions that we'd be starting from 0 when we're really not. This tracks with what I've seen so far. When implementing the change outlined in (1) I get a bunch of test failures, presumably because server and client have a differentmin_pn. Those go away when I set server and client to the same non-zeromin_pn. My thought is that even making the random generation be higher up in the logic so server and client share amin_pnand therefore making the tests pass wouldn't mean much, because usually we're not in control of the server.
- Do I understand correctly that the intended behavior for this would be to randomize the starting packet number for the initial space of a new connection?
Yes. Only the initial space.
- The RFC explicitly states
Packet numbers in each space start at packet number 0.in the section linked above. Is this still something we'd want to investigate? I'd imagine this could lead to a bunch of breakage if servers make assumptions that we'd be starting from 0 when we're really not.
Huh. I can't remember why this was added. Servers will need to support CI packets with numbers > 0, because if the CI with number 0 is lost, the first packet a server sees will have a higher number.
The model that most implementation use is that the packets are effectively "lost". That's totally possible, if unlikely, so a receiver has to be able to deal with it. For Initial packets, that will push the receiver to ACK immediately, because it notes a gap, but receivers are required to ACK Initial packets immediately anyway.
In other words, this is totally fine. It's unnecessary (an adversary needs to observe a random connection ID to be able to spoof something), but it might lead to catching of injected packets if an attacker injects a packet 0 that was never sent. Part of this change therefore needs to be able to handle receipt of an ACK for a packet that was never sent and break the connection.