Subject: [quicwg/base-drafts] Rules for discarding old keys (#1636)

From: Martin Thomson <[email-masked]>
Date: Tue, 07 Aug 2018 00:05:41 -0700

This is - at its core - simple.  When you are done with keys, set a
timer.  Working through all the ramifications and defining this
precisely takes more words than I'd originally anticipated.

Closes #1544.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/1636

-- Commit Summary --

  * Rules for discarding old keys

-- File Changes --

    M draft-ietf-quic-tls.md (83)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/1636.patch
https://github.com/quicwg/base-drafts/pull/1636.diff

-- 
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/pull/1636

---

From: Mike Bishop <[email-masked]>
Date: Tue, 07 Aug 2018 13:50:36 -0700

MikeBishop commented on this pull request.

Good content, but some structural feedback.

> @@ -619,6 +619,55 @@ The alert level of all TLS alerts is "fatal"; a TLS stack MUST NOT generate
 alerts at the "warning" level.

+## Discarding Unused Keys
+
+After QUIC moves to a new encryption level, packet protection keys for previous
+encryption levels can be discarded.  This occurs several times during the
+handshake, as well as when keys are updated (see {{key-update}}).
+
+QUIC endpoints MUST retain keys until they are no longer needed.  If packets
+from a lower encryption level contain CRYPTO frames, frames that retransmit that
+data MUST be sent at the same encryption level.  Similarly, an endpoint
+generates acknowledgements for packets at the same encryption level as the
+packet being acknowledged.  Thus, it is possible that keys for a lower
+encryption level are needed for a short time after keys for a newer encryption
+level are available.
+
+An endpoint can only discard keys for a given encryption level only after it has

Pick an only, but only one.

> +handshake, as well as when keys are updated (see {{key-update}}).
+
+QUIC endpoints MUST retain keys until they are no longer needed.  If packets
+from a lower encryption level contain CRYPTO frames, frames that retransmit that
+data MUST be sent at the same encryption level.  Similarly, an endpoint
+generates acknowledgements for packets at the same encryption level as the
+packet being acknowledged.  Thus, it is possible that keys for a lower
+encryption level are needed for a short time after keys for a newer encryption
+level are available.
+
+An endpoint can only discard keys for a given encryption level only after it has
+both received and acknowledged all CRYPTO frames for that encryption level and
+when it has had all CRYPTO frames for that encryption level acknowledged by its
+peer.  However, this does not guarantee that no further packets will need to be
+received or sent at that encryption level because a peer might not have received
+all the acknowledgements necessary to reach the same state.

This paragraph seems duplicative of the preceding one.  Can they be consolidated?  Or if they are substantially different, the difference highlighted?

> +from a lower encryption level contain CRYPTO frames, frames that retransmit that
+data MUST be sent at the same encryption level.  Similarly, an endpoint
+generates acknowledgements for packets at the same encryption level as the
+packet being acknowledged.  Thus, it is possible that keys for a lower
+encryption level are needed for a short time after keys for a newer encryption
+level are available.
+
+An endpoint can only discard keys for a given encryption level only after it has
+both received and acknowledged all CRYPTO frames for that encryption level and
+when it has had all CRYPTO frames for that encryption level acknowledged by its
+peer.  However, this does not guarantee that no further packets will need to be
+received or sent at that encryption level because a peer might not have received
+all the acknowledgements necessary to reach the same state.
+
+After all CRYPTO frames for a given encryption level have been either sent or
+received and the corresponding acknowledgments have been received or sent, an

Given that each encryption level other than 0-RTT includes CRYPTO frames in both directions, I'd question the use of "either" here -- after all outgoing CRYPTO frames have been sent and all expected CRYPTO frames have been received, and the corresponding acknowledgements have also been sent and received.

> +when it has had all CRYPTO frames for that encryption level acknowledged by its
+peer.  However, this does not guarantee that no further packets will need to be
+received or sent at that encryption level because a peer might not have received
+all the acknowledgements necessary to reach the same state.
+
+After all CRYPTO frames for a given encryption level have been either sent or
+received and the corresponding acknowledgments have been received or sent, an
+endpoint starts a timer.  To limit the effect of packet loss around a change in
+keys, endpoints MUST retain packet protection keys for that encryption level for
+at least three times the current Retramsmission Timeout (RTO) interval as
+defined in {{QUIC-RECOVERY}}.  Retaining keys for this interval allows packets
+containing CRYPTO or ACK frames at that encryption level to be sent if packets
+are determined to be lost or new packets require acknowledgment.  While this
+timer is running, an endpoint MUST use the most recent packet protection keys
+for all packets, except to protect packets containing CRYPTO and ACK frames for
+the older encryption level.  These packets MAY also include PADDING frames.

Talking about the "most recent packet protection keys" feels a little jarring here, since you're actually talking about encryption levels in this section.  This doesn't flow as clearly if you mix in key updates at the same time.

Perhaps "New data MUST be sent at the highest currently-available encryption level, but ACK frames and retransmissions of CRYPTO frames from prior encryption levels continue to be sent at that encryption level."

> +defined in {{QUIC-RECOVERY}}.  Retaining keys for this interval allows packets
+containing CRYPTO or ACK frames at that encryption level to be sent if packets
+are determined to be lost or new packets require acknowledgment.  While this
+timer is running, an endpoint MUST use the most recent packet protection keys
+for all packets, except to protect packets containing CRYPTO and ACK frames for
+the older encryption level.  These packets MAY also include PADDING frames.
+
+Once this timer expires, an endpoint MUST NOT either accept or generate new
+packets using those packet protection keys.  An endpoint can discard packet
+protection keys for that encryption level.
+
+An endpoint can update keys multiple times (see {{key-update}}) while this timer
+runs.  In that case, packets protected with the newest packet protection keys
+and packets sent two updates prior will appear to use the same keys.  After the
+handshake is complete, endpoints only need to maintain the two latest sets of
+packet protection keys and MAY discard older keys.

Make the transition to discussing key updates more explicit, if you need to do it in this section.  Maybe, "Key updates in the 1-RTT encryption level do not require that keys from other encryption levels have already been discarded."  I'd be inclined to move the rest of the key update discussion to that section and leave it with that statement.  

Wherever that discussion lands, it feels like these two paragraphs need to merge.  Something like "Frequent key updates could create confusion about which generation of 1-RTT keys were used to protect the packet.  To mitigate this, key updates can be performed only once per RTT.  This means...."

-- 
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/pull/1636#pullrequestreview-144174218

---

From: Martin Thomson <[email-masked]>
Date: Tue, 07 Aug 2018 18:51:17 -0700

martinthomson commented on this pull request.

+

Yes, I think so.  The previous paragraph is intended to highlight the reasons why keys might be retained in a general sense.  The second paragraph is intended to be more precise about what the requirements are.  A small tweak to the lead-in of each should help emphasize the difference.

-- 
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/pull/1636#discussion_r208435074

---

From: Martin Thomson <[email-masked]>
Date: Tue, 07 Aug 2018 19:03:25 -0700

The mitigation is a structural one - we don't say "don't update too often", instead it's more or less impossible to update that often (peers could update more often if they synchronized their efforts, but the floor is half an RTT).  I'll reword with these comments in mind though.

-- 
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/pull/1636#discussion_r208436580

---

From: Martin Thomson <[email-masked]>
Date: Tue, 07 Aug 2018 19:08:41 -0700

@martinthomson pushed 1 commit.

16e9226  Editorial comments from Mike

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1636/files/19dffbdadc3339c9b2a8b4f13d763fbaef61e1ad..16e92264fd7703ea7ad2b4af97a324a507baa52a

---

From: Mike Bishop <[email-masked]>
Date: Wed, 08 Aug 2018 09:27:04 -0700

>  encryption level are needed for a short time after keys for a newer encryption
 level are available.
 
-An endpoint can only discard keys for a given encryption level only after it has
-both received and acknowledged all CRYPTO frames for that encryption level and
-when it has had all CRYPTO frames for that encryption level acknowledged by its
+An endpoint cannot discard keys for a given encryption level unless it has both
+received and acknowledged all CRYPTO frames for that encryption level and when
+it all CRYPTO frames for that encryption level have been acknowledged by its

"and when ~it~ all"

-- 
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/pull/1636#pullrequestreview-144501735

---

From: Martin Thomson <[email-masked]>
Date: Wed, 08 Aug 2018 21:11:09 +0000 (UTC)

59df9a5  'And when it all', ooooo

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1636/files/16e92264fd7703ea7ad2b4af97a324a507baa52a..59df9a558ac07f7982380c686097e7ae303dc2bd

---

From: Martin Thomson <[email-masked]>
Date: Tue, 14 Aug 2018 15:12:47 -0700

Merged #1636 into master.

-- 
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/pull/1636#event-1788939400