Subject: [quicwg/base-drafts] Do Initial secrets change after Retry packet? (#2823)

From: Nick Harper <[email-masked]>
Date: Thu, 20 Jun 2019 14:10:46 -0700

https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#rfc.section.5.2 states that "Initial packets are protected with a secret derived from the Destination Connection ID field from the client’s first Initial packet of the connection." This sounds like a second Initial packet from the client (in response to a server's Retry) would still be encrypted using keys derived from the original DCID instead of a potentially new DCID. However, that section later mentions the client creating an Initial packet in response to a Retry packet and the DCID is selected by the server.

These two statements should be reconciled to clarify that either the initial keys stay the same for the entire connection, or that initial keys can change. (From the discussion in #2180, it sounds like an Initial sent in response to a Retry is still the same connection.)

I think there are 3 options for behavior:
1. The initial keys stay the same for the entire connection
2. The initial keys for encrypting/decrypting a packet are derived from the server's CID listed in that packet
3. The initial keys are derived from the client's first DCID, unless the server sends a Retry packet, after which the initial keys are re-derived from the server's new DCID.

These options are in my preference order.

My understanding for why initial keys change after a Retry is to support servers handling Retry statelessly. A server should still be able to use the original DCID for initial key derivation in this case because the ODCID is needed for transport parameters, and the retry token is sent in the clear in the Initial packet, so the server can recover it from the token.

Option 2 lets the keys change, but follows a simpler principle for what the keys are. When processing a packet for a connection, the information to encrypt or decrypt it is all self-contained - there is no additional connection state to check whether a new encrypter or decrypter is needed because an Initial packet was sent/received after a Retry packet.

One of the reasons why option 3 seems odd to me is that there are multiple ways the server's CID can change between Initial packets on the same connection, but Retry packets are the only case where we change the initial keys. (E.g. consider from a client's perspective sending a second ClientHello in response to a Retry packet has the initial keys change, but sending it in response to a HelloRetryRequest keeps the keys the same, even though the server likely changed its CID in the Initial packet where it sent the HRR.)

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

---

From: ianswett <[email-masked]>
Date: Fri, 21 Jun 2019 12:38:59 -0700

1 and 2 are the clearest contracts and I slightly prefer 1 as well.  3 is odd and very unintuitive 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/2823#issuecomment-504549067

---

From: Nick Banks <[email-masked]>
Date: Sun, 23 Jun 2019 08:28:13 -0700

I think 1 is probably the best. I believe it would remove the need to include the original CID in the transport parameters as well, in the Retry scenario.

-- 
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/2823#issuecomment-504762056

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 23 Jun 2019 18:39:29 -0700

@nharper Maybe I am wrong, but haven't we had interop based on the understanding that the 2 is the correct way (i.e. the "S" column of the interop matrix)?

> (From the discussion in #2180, it sounds like an Initial sent in response to a Retry is still the same connection.)

IIUC, the discussion is about "cryptographic handshake message" (i.e. ClientHello transmitted as the payload of the CYRPTO frame) being consistent. Not about the key that encrypts (obfuscates) the frames.

One practical issue with option 1 is that it requires the server and the issuer of the Retry token to share the format of the Retry token (as well as a secret key to extract ODICID from the token in certain designs). IIRC, our previous consensus is to permit people to install DDoS mitigation boxes that issue Retry packets, without requiring such coordination between those mitigation boxes and the servers being protected (@nibanks am I correct?)

-- 
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/2823#issuecomment-504809515

---

From: Marten Seemann <[email-masked]>
Date: Sun, 23 Jun 2019 19:28:18 -0700

My understanding is that we interoped on the key being derived from the new DCID (from the client’s perspective) on the Initial packet, so that would be 3.?

-- 
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/2823#issuecomment-504834327

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 23 Jun 2019 19:29:56 -0700

@marten-seemann Correct. It is also my understanding that we do 3 (not 2).

-- 
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/2823#issuecomment-504834613

---

From: Nick Banks <[email-masked]>
Date: Sun, 23 Jun 2019 19:54:42 -0700

@kazuho So long as the backend server has to give the OCID in the TP, you need the shared format/key for the token. This won't change that.

-- 
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/2823#issuecomment-504838340

---

From: Mike Bishop <[email-masked]>
Date: Tue, 25 Jun 2019 11:13:13 -0700

This is already stated in a different section.  In [17.2.5](https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#packet-retry), it says:

> A client sets the Destination Connection ID field of this Initial packet to the value from the Source Connection ID in the Retry packet. **Changing Destination Connection ID also results in a change to the keys used to protect the Initial packet.** It also sets the Token field to the token provided in the Retry. The client MUST NOT change the Source Connection ID because the server could include the connection ID as part of its token validation logic (see Section 8.1.3).

-- 
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/2823#issuecomment-505560244

---

From: Martin Thomson <[email-masked]>
Date: Tue, 25 Jun 2019 18:15:16 -0700

Yes.  Right now we have 3, though not exactly as stated.  It is

> The initial keys are derived from the client's first DCID, unless the server sends a Retry packet, after which the initial keys are re-derived from the DCID in the client's Initial packet(s).

-- 
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/2823#issuecomment-505678540