Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream0 dt output ready #1377

Closed
wants to merge 6 commits into from
Closed

Conversation

ekr
Copy link
Collaborator

@ekr ekr commented May 23, 2018

This is the output of the Stream 0 Design Team.

A high-level description and rationale for the proposal can be found at:
https://docs.google.com/document/d/1fRsJqPinJl8N3b-bflDRV6auojfJLkxddT93j6SwHY8/edit?ts=5b04c125

that the packet was sent later, and a lower QUIC packet number signifies that
the packet was sent earlier. When a packet containing frames is deemed lost,
QUIC rebundles necessary frames in a new packet with a new packet number,
removing ambiguity about which packet is acknowledged when an ACK is received.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears as if frames are copied into new packets, but it is content or latest status that is sent upon loss detection.

received data in that flow. [TODO(ekr): Double check that this
can't happen]. Implementations MUST treat any violations of this
requirement as a connection error of type PROTOCOL_VIOLATION.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clarify if this is at UDP datagram level or QUIC packet level since datagrams can contain multiple QUIC packets.

The first Initial packet contains a packet number of 0. Each packet sent after
the Initial packet is associated with a packet number space and its packet
number increases monotonically in that space (see {{packet-numbers}}).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears as if the initial packet is not part of a number space so a second packet could start from 0 or a random base and increment from there.

In general, the rules for which data can appear in packets of which
encryption level are the same in QUIC as in TLS over TCP:

- CRYPTO_HS frames MAY appear in packets of any encryption level.
Copy link
Member

@kazuho kazuho May 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text suggests that a CRYPTO_HS frame might appear in a 0-RTT packet. I think we need to forbid that.

IMO, the only handshake message that might make sense to show up in a 0-RTT packet is EndOfEarlyData. However, allowing that introduces unnecessary complexity.

We need to deliver the TLS messages to the TLS stack in the order they were issued.

A QUIC implementation can easily guarantee that plaintext messages (i.e. CH, SH) carried over the Initial packets will be delivered prior to handshake messages carried over the Handshake packets (e.g., EE, Certificate, Finished), because the latter cannot be decrypted without the former being delivered. The same argument goes for NST being delivered after ServerFinished.

If we send EOED using a Handshake packet, we will continue to have the in-order delivery guarantee.

OTOH, if we send EOED using a 0-RTT packet, QUIC stacks will be required to reassembly the input across multiple encryption levels, i.e., delay passing the payload of CRYPTO_HS frames found in Handshake packets until receiving a 0-RTT packet containing a EOED message. Note that a QUIC implementation cannot even tell if a CRYPTO_HS frame found in a 0-RTT packet contains a full EOED message, so we will be required to add a flag to a 0-RTT packet telling the peer that complete EOED has been delivered.

These requirements seem wired to me. Why not just send EOED using a Handshake packet?

EDIT. My argument is based on the understanding is that EOED merely exists to mark the boundary between keys when TLS uses TCP as a transport. In case of TLS messages over QUIC, we have distinct packet types for 0-RTT and handshake packets, and there is no necessity to send it using a 0-RTT packet (aside from aesthetic reasons).

Copy link
Member

@kazuho kazuho May 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other reason to send EOED using a Handshake packet would be to minimize the changes related to the security from TLS. In TLS, EOED is protected by the handshake traffic key. Sending EOED using a 0-RTT packet will mean that we will be changing the traffic key of the message to a different key.

EDIT. Sorry, under the TLS spec., EOED is protected by the early traffic secret. So we need to send it using a 0-RTT packet to minimize the impact of moving to a different packetization scheme. I think my comments about the wiredness still holds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please forgive me for being a complete idiot. The issues pointed out here is based on the assumption that the TLS stack will activate the handshake key before receiving EOED sent using a 0-RTT packet.

They are all non-issues, if the TLS stack delays the activation of the handshake key until it receives EOED (and that is what the stacks are doing now).

except that the label for HKDF-Expand-Label uses the prefix "quic "
rather than "tls 13". The purpose of this change is to provide key
separation between TLS and QUIC, so that TLS stacks can avoid
exposing TLS record protection keys.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see two clarifications here.

Am I correct in assuming that we would be using a modified version of HKDF-Expand-Label (that uses "quic " as the prefix) only when calculating the traffic keys? The other interpretation would be that we would be using the modified version for all cases (e.g. in Derive-Secret, when calculating the finished key). My preference goes to the former considering the fact that we are trying to change the traffic layer (i.e. TLS record) only.

The second issue is that the text seem to state that the non-modified version of HKDF-Expand-Label will be used for calculating the Initial Secret. I'd assume that it is a defect of the text.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that you raised this. I was assuming the former. I believe the latter would be safe but I would love to heard from @ad-l on this point.

The second is just a bug.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, replacing all HKDF expansion labels in the TLS key schedule is the more conservative approach, as it prevents some secrets from being portable between TLS and QUIC. Most notably, if only the record key expansions use the "quic " label prefix, session tickets and PSK binders may potentially be re-used across the two protocols. /This is not necessarily a bad thing/ - a modular security model for the TLS handshake can in fact accommodate this a as feature and tolerate sessions that use a mix of record protocols.

I would say it is up to the IETF to decide whether it wants the two protocols to be immiscible or not. If nobody sees value in mixed-transport sessions, going for disjoint labels is a cheap way to reduce the attack surface of both protocols and ensure they can be analyzed independently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekr @ad-l Thank you for the guidelines. The impact of sharing the labels are now clear to me.

To me now it seems that one way of making the decision in QUIC would be to follow the precedent that is soon going to be set by DTLS 1.3.

If DTLS allows session resumption using a ticket obtained through a TLS connection, I do not see why QUIC should disallow it. If DTLS uses the same traffic key as TLS does, I do not see why QUIC cannot use it as well.

Is my understanding correct that DTLS 1.3 uses the same label for all the cases?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the labels means a future QUIC + TLS 1.4 will lose the version distinguisher, no? So that means that it will impede reuse of the analysis in different direction. If just changing the record-layer labels, that's probably fine since those secrets are derived from earlier versioned secrets. But that is a new detail that must be accounted for in the analysis. If changing the whole thing, then it's no longer obvious that TLS 1.4 will work smoothly.

I'm also not eager to have to route in logic to switch labels around everywhere. (See how the [sender]_write_key, [sender]_write_iv, and KeyUpdate derivations were tweaked so as not to incorporate the side, because the base secrets already did so. That turned out to be a surprisingly large simplification to the implementation.)

Record-layer labels are less of a big deal, but I'm a little confused how even changing them helps the protocols be analyzed independently. We're already splitting TLS apart at the record layer bits, so the record layer portions of the analysis already must be reworked or accounted for in some way. It doesn't seem like changing the labels reduces the contact points.

I agree that aligning with DTLS 1.3 makes sense, including the labels. It seems to be the same scenario: we share the handshake, but tease apart the record layer. (Is DTLS 1.3 changing the labels at all? I don't see any indication of it doing so, but maybe I missed it.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DTLS 1.3 uses the same labels.

@davidben the rationale here was less about analysis than about being to build a TLS 1.3 stack that guaranteed that it would keep the TLS keys internally. And this was intended as a cheap way to do that. I'm not religious about it, but there was some enthusiasm for it on the design team, so I suggested it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rationale here was less about analysis than about being to build a TLS 1.3 stack that guaranteed that it would keep the TLS keys internally. And this was intended as a cheap way to do that. I'm not religious about it, but there was some enthusiasm for it on the design team, so I suggested it.

@ekr I remember having that discussion. OTOH, I do not recall discussing about which (or that all) keys should be kept internally. It could be the case that the hesitation that some had was against sharing one key between two stacks; an issue orthogonal to how we define the labels.

I think that we should discuss the issue in the working group to see what the concern is (or if such a concern really exists).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekr Ah, that makes sense. I think we should try to avoid bifurcating all the labels but the "exported" record keys will need a dedicated path anyway, so it's hopefully not a huge deal either way.

Though having it lose the versioning is a little odd. Should it be a different input to hkdf-expand-label instead?


Because packets may be reordered on the wire, QUIC uses the packet
type to indicate which level a given packet was encrypted
under [TODO: Table needed here?]. When multiple packets of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a table for clarity. Frame types and Packet Types are after all two dimensions and clarity on how encryption level to packet type needs to be clear. And it isn't currently.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

handshake packets (@H) to 1-RTT protection (@1), which happens after it sends
its final set of TLS handshake messages.
~~~
{: #quic-tls-handshake title="QUIC Handshake"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to include packet types in the above diagram, not only the key's symbols?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a new diagram.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants