Subject: [quicwg/base-drafts] Padding handshake packets (#164)

From: Martin Thomson <[email-masked]>
Date: Mon, 16 Jan 2017 18:08:50 -0800

@martinduke raised this in #106.  What should we say about the size of handshake packets.

1. All handshake packets to be padded to maximum size.
2. Pad at least one packet per handshake (in each direction) that is successfully acknowledged
3. More specifically, the first client packet (CHLO) and retransmissions, and last server packet [SHLO] and retransmissions. In many cases this will be the same as #2, but is a bit more prescriptive.

I think that we have agreed that the first packet from the client will be *at most* one packet.  The question is for the server where to pad.

I believe that option 3 and option 1 amount to the same thing.  Option 2 looks a bit like option 4 (pad the first packet).

This relates to (and may subsume) #38.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164

---

From: Brian Trammell <[email-masked]>
Date: Mon, 16 Jan 2017 23:41:22 -0800

This interaction pattern (or any interaction pattern in its place in terms of observable packer properties) can (i.e., will) be used by stateful firewalls to recognize QUIC session establishment. If this is the case, it may be useful to note that an established flow that detects it has lost its connection due to state drop or timeout can simulate the pattern to "re-handshake", without losing any end-to-end (crypto, stream) state.

Having this contract be explicit is IMO useful.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273043105

---

From: martinduke <[email-masked]>
Date: Tue, 17 Jan 2017 08:43:28 -0800

Since the transport document should be handshake-agnostic, I think it's
important to craft the requirement precisely rather than using inferences
about what the handshake packets actually are.

Option 2 is *not *the same as padding the first packet on the serverside,
as it's the difference between potentially padding a REJ instead of a SHLO
(forgive the legacy-QUIC terms).

So the pros and cons, in my opinion, are as follows:
(1) is very simple but wasteful, and would increase server load during DoS.
(2) is relatively complicated to verify compliance (implementers could
easily make a mistake where they "assume" there is another handshake
message to come and then there isn't), but it is the most agnostic to the
handshake form
(3) Is very prescriptive, and preserves one main objective (maximize
initial load on the client, minimize initial load on the server). But it
can lead to perverse results, where (for instance) the server has already
sent a full-size packet when delivering a certificate, and then is forced
to send a second-full size packet using PADDING due to the requirement.

On Mon, Jan 16, 2017 at 11:41 PM, Brian Trammell <[email-masked]>
wrote:

> This interaction pattern (or any interaction pattern in its place in terms
> of observable packer properties) can (i.e., will) be used by stateful
> firewalls to recognize QUIC session establishment. If this is the case, it
> may be useful to note that an established flow that detects it has lost its
> connection due to state drop or timeout can simulate the pattern to
> "re-handshake", without losing any end-to-end (crypto, stream) state.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/quicwg/base-drafts/issues/164#issuecomment-273043105>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AXRMEYs9uG0TZMV_OpgK3R8nx8VmPOaNks5rTHCigaJpZM4LlJzD>
> .
>

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273224503

---

From: martinduke <[email-masked]>
Date: Tue, 17 Jan 2017 08:48:11 -0800

For reference, the text that was in the PR for #106 before being removed is as follows. It codifies option (2) as described at the top of this thread:

"Both the QUIC client and server MUST send at least one handshake packet of size
 equal to the estimated PMTU, and receive an acknowledgment for that packet. This
could require a PADDING frame to increase the packet size. PMTU-size, IPv4
handshake packets SHOULD have the DF bit set."

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273225989

---

From: martinduke <[email-masked]>
Date: Tue, 17 Jan 2017 08:52:24 -0800

While we're looking at this subject, I believe am in the minority in believing that the DF bit "SHOULD" condition and ought to be a "MUST".  Although it's true that some OSes may not allow full user-space control of DF, I'm not sure about the point of this whole exercise if we pad a packet only to have it silently fragment in the network.

Do the OSes that people care about not allow sysctl-equivalent control of DF? It would be entirely sufficient to simply turn on PMTU/DF and mark more packets that necessary. The important thing is that at least the full-size packet is marked.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273227356

---

From: Martin Thomson <[email-masked]>
Date: Tue, 17 Jan 2017 13:20:46 -0800

I confess that I'm not following [this comment](#issuecomment-273224503) very well.  Maybe it's because I don't follow your point about requiring acknowledgment on option 2.

Two things that I didn't explictly say, but assumed:

* We should not require padding for a stateless reject.

* If the server is required to send multiple handshake packets, it would be because the crypto had provided a blob larger than would fit in a single packet.  I had assumed that it would fill the first up to the requisite size.   You could fill from the last packet backwards, but that's not going to fit well when you add 0-RTT and want to fill all the packets.

All of these packets are required to make progress, so the specific packetization we use for those initial packets is fairly open to whatever strategy we think is best.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273303376

---

From: martinduke <[email-masked]>
Date: Tue, 17 Jan 2017 14:48:17 -0800

By "requiring acknowledgment", I am saying that it is insufficient to send a full-size packet, have it lost due to being too large, and then retransmit that payload without padding. The language may not be clear enough here, but retransmission of the ClientHello, for example, should be padded to whatever the fallback PMTU is. There are some dependencies here with some other open issues.

I agree we should not pad a stateless reject.

Having re-read the TLS 1.3 spec, I also agree that the server wording is probably not correct. To be honest, I was thinking of the current Google spec, where the certificate is in the REJ message. I'd be happier if we just said the server MUST send at least one MTU-size packet, and receive an acknowledgment for it, before the handshake is over. This is also completely robust to some future handshake protocol where the Certificate is in the HelloRetryRequest, or whatever.

On the clientside, there might be value in waiting for the message that has the ClientCertificate in it, but as we won't know if that's required it's best to just require padding the first message.

So, to summarize, I'm proposing:
(1) The client MUST pad the first handshake message, and pad any retransmissions of that data.
(2) The server MUST pad at least one handshake message, and pad any retransmissions of that data.

If you think that's about right I'll create a PR.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273325645

---

From: ianswett <[email-masked]>
Date: Tue, 17 Jan 2017 15:45:01 -0800

I think that's correct and sufficient for all the cases I can think of.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273337637

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Jan 2017 12:48:26 -0800

Thanks for the explanation.  I will observe that you don't need an explicit acknowledgment for the handshake messages.  If the handshake completes, then the other side definitely received the packet.  That means that you should always send at an octet (any octet) in a fully-padded packet.

To that end, I would suggest the relatively obvious solution here: the first octet of the crypto handshake MUST be in a fully-padded packet, including retransmissions of that octet.  That's going to happen by default for the server anyway.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273597152

---

From: martinduke <[email-masked]>
Date: Wed, 18 Jan 2017 13:34:49 -0800

Without some sort of acknowledgment/retransmission requirement, it is entirely possible to send one padded packet, lose it, and then have much smaller packets to successfully complete the handshake. But I believe your alternative formulation about octets is OK.

The server will not send an MTU-size packet for the HelloRetryRequest, if it uses one. If I understand TLS1.3 integration correctly, a HelloRetryRequest might or might not be stateless for the server. I think it is a challenge to choose a specific server octet in a handshake-agnostic way.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273608835

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Jan 2017 13:41:12 -0800

There's a necessary interaction between the crypto and the transport here.  If the server doesn't perform a stateless reject using HelloRetryRequest, then it might as well pad that packet.  Thus, the only case where you need special handling is in a stateless reject.  I think that's workable.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-273610489

---

From: martinduke <[email-masked]>
Date: Fri, 20 Jan 2017 08:09:24 -0800

In the server case, just saying "at least one handshake packet" frees us from having to second-guess the crypto. Given TLS 1.3, I imagine most servers will pad the ServerHello if it's not large enough already.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-274110283

---

From: Mark Nottingham <[email-masked]>
Date: Wed, 25 Jan 2017 18:31:23 -0800

As discussed in Tokyo, client MUST pad initial packet to at least 1280, and MAY pad up to the PMTU, if known. No requirement put on server.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/164#issuecomment-275293865