Subject: [quicwg/base-drafts] handshake and 0rtt data should go into single packet (#630)

From: Kazuho Oku <[email-masked]>
Date: Tue, 13 Jun 2017 12:01:19 -0700

Current packet layout requires the handshake (which is conveyed in a Cleartext packet) and 0-RTT data to be sent as separate packets. In other words, you need to send at least two packets to establish a connection and send a request (e.g. HTTP request, DNS query).

To me this seems like a regression when compared to TFO+TLS 1.3, in which you can convey SYN, TLS handshake and 0-RTT data in a single packet.

I'd argue that this might have real-world impact. Having the need to send two packets (instead of one) is not only costly but also has a higher chance of suffering from packet loss (especially in a lossy network), since the request cannot be processed on the server unless both of the two packets reach the server.

Therefore I think that we should find a way to send both the handshake and 0-RTT data in a single packet.

There could be several ways to accomplish this.

One way that might be worth considering would be to do the following.
* unify Cleartext type and 0-RTT encrypted type into one type
* at the beginning of the payload of the unified type include the amount of cleartext data. Cleartext data of the specified amount should immediately follow that. Rest of the payload would be 0-RTT data.

Since we would only send data of stream 0 in cleartext and we need to give precedence to the stream, storing cleartext before 0-RTT data makes sense.

-- 
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/630

---

From: ianswett <[email-masked]>
Date: Tue, 13 Jun 2017 12:23:45 -0700

Excellent suggestion. I was just thinking about thinking about this this weekend, particularly for cases like DNS over QUIC.

I can see three framing options:
1) Create a new packet type which is cleartext + 0RTT data
2) Add two bytes at the beginning of cleartext packets to indicate a cleartext length that precedes the 0RTT data.
3) Require that all frames after a Stream 0 frame be encrypted with 0RTT data.

Option 3 seems overly clever, and 1 adds one or two more packet types.  Option 2 burns 2 bytes on every unencrypted packet, which I think may be the best option, but I may be wrong.

Any other framing suggestions?

-- 
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/630#issuecomment-308221603

---

From: MikkelFJ <[email-masked]>
Date: Tue, 13 Jun 2017 12:37:12 -0700

> Any other framing suggestions?

Just encrypt cleartext with 0RTT key and don't mind double encryption.

-- 
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/630#issuecomment-308225107

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 13 Jun 2017 13:41:18 -0700

> Any other framing suggestions?

My preference is 2. But any of the three would work.

And I will like to point out that we'd need to do the same for the first packets that the server sends. We need a packet format that contains both the payloads of current Server Cleartext and 1-RTT Encrypted (key phase 0). Otherwise, a server cannot respond with just sending _one_ packet.

The fact that a server might send multiple Cleartext packets (when doing a full handshake) might be considered a point against option 2 (i.e. burn 2 octets in every packet that includes Cleartext to indicate where Cleartext ends).

-- 
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/630#issuecomment-308242042

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 13 Jun 2017 13:43:36 -0700

> Just encrypt cleartext with 0RTT key and don't mind double encryption.

I am not sure if this approach works. A server might not know the 0RTT key, in which case it needs to fall back to doing a full handshake. For the purpose, handshake messages need to be sent unencrypted.

-- 
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/630#issuecomment-308242645

---

From: ekr <[email-masked]>
Date: Tue, 13 Jun 2017 14:44:36 -0700

As @kazuho says, it does not work. The identification for the 0-RTT key is in the unencrypted portion, namely the ClientHello

-- 
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/630#issuecomment-308257787

---

From: MikkelFJ <[email-masked]>
Date: Tue, 13 Jun 2017 15:33:25 -0700

So encryption won't (always) work without extra retry fallback and roundtrip. I'd say option 2 sounds reasonable. The packet might be padded anyway to hide length of a HTTP request.

-- 
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/630#issuecomment-308267982

---

From: ekr <[email-masked]>
Date: Wed, 14 Jun 2017 01:30:35 -0700

@kazuho: I agree it's annoying to have to send two packets.

I have a fourth option: Add a length field to the long header and allow multiple long headers to be packed into a single UDP datagram. Note that this will require adjusting the padding rules, but that should be possible.

-- 
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/630#issuecomment-308361033

---

From: ianswett <[email-masked]>
Date: Wed, 14 Jun 2017 07:14:43 -0700

@ekr, conceptually I like option 4, but it introduces a bunch of weird options, such as the ability to specify two different connection IDs and packet numbers in the same packet.

If we did include 0RTT data in the same packet with a CHLO, we could make the plaintext the associated data, which would give it some extra protection from tampering, but we may want a hash as well, in case the 0RTT data can't be decrypted?

-- 
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/630#issuecomment-308444561

---

From: ekr <[email-masked]>
Date: Wed, 14 Jun 2017 08:21:15 -0700

On Wed, Jun 14, 2017 at 4:14 PM, ianswett <[email-masked]> wrote:

> @ekr <https://github.com/ekr>, conceptually I like option 4, but it
> introduces a bunch of weird options, such as the ability to specify two
> different connection IDs and packet numbers in the same packet.
>

What of it? Just handle the two packets as if they came in separate
datagrams.

> If we did include 0RTT data in the same packet with a CHLO, we could make
> the plaintext the associated data, which would give it some extra
> protection from tampering, but we may want a hash as well, in case the 0RTT
> data can't be decrypted?
>

This is starting to sound like a loot of hoop-jumping to avoid two calls to
send()

> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308444561>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABD1ob2SoISHtv3nnxQauvivGTvTZdifks5sD-rRgaJpZM4N47uf>
> .
>

-- 
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/630#issuecomment-308465652

---

From: janaiyengar <[email-masked]>
Date: Wed, 14 Jun 2017 11:23:29 -0700

I think this is a good idea in general. This will be particularly useful
for small requests, such as for DNS.

I think we can pull this off without any framing changes. The current
packet types (post-Paris) have the Client Initial packet always carrying
the initial handshake data. Since this packet will contain only a STREAM
frame with handshake material, we can make this packet a bit more special.
Since STREAM frames have a size field, any bytes beyond the cleartext
STREAM frame can be treated as 0-RTT encrypted data.

On Wed, Jun 14, 2017 at 4:21 PM, ekr <[email-masked]> wrote:

> > <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308444561
> >,
> > or mute the thread
> > <https://github.com/notifications/unsubscribe-auth/
> ABD1ob2SoISHtv3nnxQauvivGTvTZdifks5sD-rRgaJpZM4N47uf>
>
> > .
> >
>
> —
> <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308465652>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AKjg1JvRAFuR6GG7MZkh-y2oZa8e548rks5sD_prgaJpZM4N47uf>
> .
>

-- 
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/630#issuecomment-308517105

---

From: janaiyengar <[email-masked]>
Date: Wed, 14 Jun 2017 11:26:30 -0700

Thoughts?

-- 
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/630#issuecomment-308517942

---

From: ekr <[email-masked]>
Date: Wed, 14 Jun 2017 11:35:53 -0700

> STREAM frame can be treated as 0-RTT encrypted data.

And what if you need to pad to get up to 1280?

On Wed, Jun 14, 2017 at 4:21 PM, ekr <[email-masked]> wrote:
> > <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308465652
> >,
> > or mute the thread
> <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308517105>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABD1oSqm5oH1YEN-EQP-V5uRN2EhgYSGks5sECUggaJpZM4N47uf>
> .
>

-- 
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/630#issuecomment-308520516

---

From: janaiyengar <[email-masked]>
Date: Wed, 14 Jun 2017 11:38:08 -0700

Encrypt the padding. 0-RTT encrypted data can contain STREAM frame followed
by PADDING frames.

On Wed, Jun 14, 2017 at 7:35 PM, ekr <[email-masked]> wrote:

> > > > protection from tampering, but we may want a hash as well, in case
> the
> > > 0RTT
> > > > data can't be decrypted?
> > > >
> > >
> > > This is starting to sound like a loot of hoop-jumping to avoid two
> calls
> > to
> > > send()
> > >
> > > > —
> > > <https://github.com/notifications/unsubscribe-
> auth/AKjg1JvRAFuR6GG7MZkh-
> > y2oZa8e548rks5sD_prgaJpZM4N47uf>
> > > .
> > >
> >
> > —
> > <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308517105
> >,
> > or mute the thread
> You are receiving this because you commented.
> <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308520516>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AKjg1KBTM7dw2Ot6reRagXlJGYC8ZFcEks5sECgJgaJpZM4N47uf>
> .
>

-- 
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/630#issuecomment-308521132

---

From: Lucas Clemente <[email-masked]>
Date: Wed, 14 Jun 2017 12:25:22 -0700

I think it's a nice property of QUIC that right now packetization (header & encryption) is separate from framing, which simplifies layering in implementations. If we do this, I think we should keep it on the public header level, so that it conceptually works like two packets in one.

-- 
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/630#issuecomment-308533033

---

From: janaiyengar <[email-masked]>
Date: Wed, 14 Jun 2017 13:08:11 -0700

Yeah, that's a good point. So, then I'm leaning towards ekr's 4th option,
but not for all long header packets but only Client Initial packets. We can
add a 2-byte length field inside the payload of the Client Initial packet.

On Wed, Jun 14, 2017 at 8:25 PM, Lucas Clemente <[email-masked]>
wrote:

> I think it's a nice property of QUIC that right now packetization (header
> & encryption) is separate from framing, which simplifies layering in
> implementations. If we do this, I think we should keep it on the public
> header level, so that it conceptually works like two packets in one.
>
> —
> <https://github.com/quicwg/base-drafts/issues/630#issuecomment-308533033>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AKjg1PHkh36aY-A_MkTPledzDD_SL9zZks5sEDOhgaJpZM4N47uf>
> .
>

-- 
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/630#issuecomment-308543508

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 15 Jun 2017 01:35:55 -0700

> @ekr, conceptually I like option 4, but it introduces a bunch of weird options, such as the ability to specify two different connection IDs and packet numbers in the same packet.

I share the same concern as @ianswett.

If we go for option 4, the server would be required to check that the connection IDs included in the single packet, or that the types of succeeding packet headers are not Client Cleartext. Otherwise, it could be used as an attack vector to cause the server send multiple ServerHellos (of different conenction IDs) to a single machine.

So if we are to go for option 4 I would prefer omitting connection ID and type (which can be implied to be 0-RTT Encrypted) for the succeeding packet headers.

-- 
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/630#issuecomment-308666546

---

From: ekr <[email-masked]>
Date: Thu, 15 Jun 2017 03:55:59 -0700

Why wouldn't it be enough to simply not allow two ClientInitials in the same packet?

-- 
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/630#issuecomment-308698360

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 15 Jun 2017 07:30:19 -0700

> Why wouldn't it be enough to simply not allow two ClientInitials in the same packet?

Unless there is a guarantee that a single packet does not contain information about more than one connection (i.e. either only one connection ID is included in a packet or all the connection IDs included in a packet are identical), it would be very difficult for a load balancer to route the packet to the correct backend.

That is why I believe that we need to have a requirement that all the connection IDs are identical if we choose option 4.

-- 
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/630#issuecomment-308751045

---

From: Patrick McManus <[email-masked]>
Date: Thu, 15 Jun 2017 09:42:25 -0700

I think it makes sense to worry about smuggling-attack-bugs here... so the clear semantics of Ian's option 1 (new type) is the most attractive to me.

-- 
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/630#issuecomment-308798493

---

From: MikkelFJ <[email-masked]>
Date: Thu, 15 Jun 2017 10:24:17 -0700

> I think it makes sense to worry about smuggling-attack-bugs here... so the clear semantics of Ian's option 1 (new type) is the most attractive to me.

It also has the benefit of simplifing routing and optimizatoins for 0RTT logic to dedicated software / thread or even dedicated hosts while at the same time allowing an implementation to completely ignore 0RTT or 1RTT if so inclined. Also, it falls in line with the idea that the packet type is sufficient to know what keys are involved in packet.

-- 
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/630#issuecomment-308811830

---

From: ekr <[email-masked]>
Date: Thu, 15 Jun 2017 10:27:37 -0700

proposal #1 actually seems extremely different from all other packet types. For instance, does it have an FNV1a authentication tag? If so, does that go *after* the 0-RTT ciphertext?

-- 
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/630#issuecomment-308812712

---

From: Patrick McManus <[email-masked]>
Date: Thu, 15 Jun 2017 10:47:19 -0700

On Thu, Jun 15, 2017 at 1:27 PM, ekr <[email-masked]> wrote:

> proposal #1 <https://github.com/quicwg/base-drafts/pull/1> actually seems
> extremely different from all other packet types.
>

indeed. but having 2 quic packets bundled under one recv() (via 2 long
headers) seems even more different to me - losing the transport 1:1
message-ness is surprising.

For instance, does it have an FNV1a authentication tag?

seems so

> If so, does that go *after* the 0-RTT ciphertext?
>

where is it critical (as long as its defined)?

-- 
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/630#issuecomment-308817757

---

From: ekr <[email-masked]>
Date: Thu, 15 Jun 2017 11:01:04 -0700

OK, I guess I don't find it that surprising. That's a feature of DTLS, so it feels familiar to me.

And if we decide to AEAD-encrypt everything under a null key, we'll double-AEAD. ugh...

-- 
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/630#issuecomment-308821453

---

From: Subodh Iyengar <[email-masked]>
Date: Thu, 15 Jun 2017 11:49:06 -0700

I brought this up with @janaiyengar and @Ianswett at Chicago as well. I'm in favor of option 4 as well which is something I also suggested :)

-- 
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/630#issuecomment-308833755

---

From: Subodh Iyengar <[email-masked]>
Date: Thu, 15 Jun 2017 11:52:18 -0700

Without option 4 that is with a different packet type, we have to worry about what attacks are possible if a mitm being is able to change the initial packet type and then change the packet split. I don't think This has  implications to crypto but allowing the split could mess with transport parameter calculations 

-- 
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/630#issuecomment-308834510

---

From: Mike Bishop <[email-masked]>
Date: Thu, 22 Jun 2017 08:58:07 -0700

Is there a reason not to simply define Client Initial to *always* contain a cleartext portion and a 0-RTT portion?  If you don't have a 0-RTT key, that section will be empty, but so what?  If the server doesn't accept the 0-RTT that you didn't offer, it won't try to decrypt it, so it can be random padding.  (Or you can pad in cleartext, I suppose.)

-- 
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/630#issuecomment-310424081

---

From: ekr <[email-masked]>
Date: Thu, 22 Jun 2017 09:02:57 -0700

As noted above, this creates a situation in which there are two different packet protection mechanisms applied to the same message (the AEAD and the cleartext integrity check). That seems unfortunate.

-- 
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/630#issuecomment-310425467