Porting QUIC to Transport Layer Security (TLS)Mozillamartin.thomson@gmail.comGooglerch@google.comThe QUIC experiment defines a custom security protocol. This was necessary to
gain handshake latency improvements. This document describes how that security
protocol might be replaced with TLS.QUIC provides a multiplexed transport for HTTP
semantics that provides several key advantages over HTTP/1.1
or HTTP/2 over TCP .The custom security protocol designed for QUIC provides critical latency
improvements for connection establishment. Absent packet loss, most new
connections can be established with a single round trip; on subsequent
connections between the same client and server, the client can often send
application data immediately, that is, zero round trip setup. TLS 1.3 uses a
similar design and aims to provide the same set of improvements.This document describes how the standardized TLS 1.3 might serve as a security
layer for QUIC. The same design could work for TLS 1.2, though few of the
benefits QUIC provides would be realized due to the handshake latency in
versions of TLS prior to 1.3.
There are other designs that are possible; and many of these alternative
designs are likely to be equally good. The point of this document is to
articulate a coherent single design. Notes like this throughout the document
are used describe points where alternatives were considered.
This is a rough draft. Many details have not been ironed out. Ryan is not
responsible for any errors or omissions.The words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” are used in this document.
It’s not shouting; when they are capitalized, they have the special meaning
defined in .QUIC can be separated into several modules:The basic frame envelope describes the common packet layout. This layer
includes connection identification, version negotiation, and includes the
indicators that allow the framing, public reset, and FEC modules to be
identified.The public reset is an unprotected frame that allows an intermediary (an
entity that is not part of the security context) to request the termination
of a QUIC connection.The forward error correction (FEC) module provides redundant entropy that
allows for frames to be repaired in event of loss.Framing comprises most of the QUIC protocol. Framing provides a number of
different types of frame, each with a specific purpose. Framing supports
frames for both congestion management and stream multiplexing. Framing
additionally provides a liveness testing capability (the PING frame).Crypto provides confidentiality and integrity protection for frames. All
frames are protected after the handshake completes on stream 1. Prior to
this, data is protected with the 0-RTT keys.Multiplexed streams are the primary payload of QUIC. These provide reliable,
in-order delivery of data and are used to carry the encryption handshake and
transport parameters (stream 1), HTTP header fields (stream 3), and HTTP
requests and responses. Frames for managing multiplexing include those for
creating and destroying streams as well as flow control and priority frames.Congestion management includes packet acknowledgment and other signal
required to ensure effective use of available link capacity.HTTP mapping provides an adaptation to HTTP that is based on HTTP/2.The relative relationship of these components are pictorally represented in
.This document describes a replacement of the cryptographic parts of QUIC. This
includes the handshake messages that are exchanged on stream 1, plus the record
protection that is used to encrypt and authenticate all other frames.TLS 1.3 provides two basic handshake modes of interest to QUIC:A full handshake in which the client is able to send application data after
one round trip and the server immediately after receiving the first message
from the client.A 0-RTT handshake in which the client uses information about the server to
send immediately. This data can be replayed by an attacker so it MUST NOT
carry a self-contained trigger for any non-idempotent action.A simplified TLS 1.3 handshake with 0-RTT application data is shown in
, see for more options.Two additional variations on this basic handshake exchange are relevant to this
document:The server can respond to a ClientHello with a HelloRetryRequest, which adds
an additional round trip prior to the basic exchange. This is needed if the
server wishes to request a different key exchange key from the client.
HelloRetryRequest might also be used to verify that the client is correctly
able to receive packets on the address it claims to have (see
).A pre-shared key mode can be used for subsequent handshakes to avoid public
key operations. This might be the basis for 0-RTT, even if the remainder of
the connection is protected by a new Diffie-Hellman exchange.QUIC completes its cryptographic handshake on stream 1, which means that the
negotiation of keying material happens within the QUIC protocol. QUIC over TLS
does the same, relying on the ordered delivery guarantees provided by QUIC to
ensure that the TLS handshake packets are delivered reliably and in order.In this design the QUIC envelope carries QUIC frames until the TLS handshake
completes. After the handshake successfully completes the key exchange, QUIC
frames are then protected by TLS record protection.QUIC stream 1 is used to exchange TLS handshake packets. QUIC provides for
reliable and in-order delivery of the TLS handshake messages.Prior to the completion of the TLS handshake, QUIC frames can be exchanged.
However, these frames are not authenticated or confidentiality protected.
covers some of the implications of this design.
TLS could be used to protect the entire QUIC envelope. QUIC version
negotiation could be subsumed by TLS and ALPN . The only unprotected
packets are then public resets and ACK frames, both of which could be given
first octet values that would easily distinguish them from other TLS packets.
This requires that the QUIC sequence numbers be moved to the outside of the
record.Several changes to the structure of QUIC are necessary to make a layered design
practical.These changes produce the handshake shown in . In this
handshake, QUIC STREAM frames on stream 1 carry the TLS handshake. QUIC is
responsible for ensuring that the handshake packets are re-sent in case of loss
and that they can be ordered correctly.QUIC operates without any record protection until the handshake completes, just
as TLS over TCP does not include record protection for the handshake messages.
Once complete, QUIC frames and forward error control (FEC) messages are
encapsulated in using TLS record protection.The remainder of this document describes the changes to QUIC and TLS that allow
the protocols to operate together.The QUIC version negotiation mechanism is used to negotiate the version of QUIC
that is used prior to the completion of the handshake. However, this packet is
not authenticated, enabling an active attacker to force a version downgrade.To ensure that a QUIC version downgrade is not forced by an attacker, version
information is copied into the TLS handshake, which provides integrity
protection for the QUIC negotiation. This doesn’t prevent version downgrade
during the handshake, though it does prevent a connection from completing with a
downgraded version, see .
The QUIC version negotiation has poor performance in the event that a client
is forced to downgrade from their preferred version.QUIC implementations describe a source address token. This is an opaque blob
that a server provides to clients when they first use a given source address.
The client returns this token in subsequent messages as a return routeability
check. That is, the client returns this token to prove that it is able to
receive packets at the source address that it claims.Since this token is opaque and consumed only by the server, it can be included
in the TLS 1.3 configuration identifier for 0-RTT handshakes. Servers that use
0-RTT are advised to provide new configuration identifiers after every handshake
to avoid passive linkability of connections from the same client.A server that is under load might include the same information in the cookie
extension/field of a HelloRetryRequest. (Note: the current version of TLS 1.3
does not include the ability to include a cookie in HelloRetryRequest.)Each TLS record is encapsulated in the QUIC envelope. This provides length
information, which means that the length field can be dropped from the TLS
record.The sequence number used by TLS record protection is changed to deal with the
potential for packets to be dropped or lost. The QUIC sequence number is used
in place of the monotonically increasing TLS record sequence number. This means
that the TLS record protection employed is closer to DTLS in both its form and
the guarantees that are provided.QUIC has a single, contiguous sequence number space. In comparison, TLS
restarts its sequence number each time that record protection keys are changed.
The sequence number restart in TLS ensures that a compromise of the current
traffic keys does not allow an attacker to truncate the data that is sent after
a key update by sending additional packets under the old key (causing new
packets to be discarded).QUIC does not rely on there being a continuous sequence of application data
packets; QUIC uses authenticated repair mechansims that operate above the layer
of encryption. QUIC can therefore operate without restarting sequence numbers.TLS 1.3 adds encryption for handshake messages. This introduces an additional
transition between different record protection keys during the handshake. A
consequence of this is that it becomes more important to explicitly identify the
transition from one set of keys to the next (see ).Each time that the TLS record protection keys are changed, the message
initiating the change could be lost. This results in subsequent packets being
indecipherable to the peer that receives them. Key changes happen at the
conclusion of the handshake and and immediately after a KeyUpdate message.TLS relies on an ordered, reliable transport and therefore provides no other
mechanism to ensure that a peer receives the message initiating a key change
prior to receiving the subsequent messages that are protected using the new
key. A similar mechanism here would introduce head-of-line blocking.The simplest solution here is to steal a single bit from the unprotected part of
the QUIC header that signals key updates, similar to how DTLS signals the epoch
on each packet. The epoch bit is encoded into 0x80 of the QUIC public flags.Each time the epoch bit changes, an attempt is made to update the keys used to
read. Peers are prohibited from sending multiple KeyUpdate messages until they
see a reciprocal KeyUpdate to prevent the chance that a transition is undetected
as a result of two changes in this bit.The transition from cleartext to encrypted packets is exempt from this limit of
one key change. Two key changes occur during the handshake. The server sends
packets in the clear, plus packets protected using handshake and application
data keys. With only a single bit available to discriminate between keys,
packets protected with the application data keys will have the same bit value as
cleartext packets. This condition will be easily identified and handled, likely
by discarding the application data, since the encrypted packets will be highly
unlikely to be valid.Each peer maintains a 48-bit send sequence number that is incremented with each
packet that is sent (even retransmissions). The least significant 8-, 16-, 32-,
or 48-bits of this number is encoded in the QUIC sequence number field in every
packet. A 16-bit send epoch number is maintained; the epoch is incremented each
time new record protection keying material is used. The least significant bit
of the epoch number is encoded into the epoch bit (0x80) of the QUIC public flags.A receiver maintains the same values, but recovers values based on the packets
it receives. This is based on the sequence number of packets that it has
received. A simple scheme predicts the receive sequence number of an incoming
packet by incrementing the sequence number of the most recent packet to be
successfully decrypted by one and expecting the sequence number to be within a
range centered on that value. The receive epoch value is incremented each time
that the epoch bit (0x80) changes.The sequence number used for record protection is the 64-bit value obtained by
concatenating the epoch and sequence number, both in network byte order.An exporter could be used to provide keying material for a QUIC-specific record
protection. This could draw on the selected cipher suite and the TLS record
protection design so that the overall effort required to design and analyze is
kept minimal.One concern with using exporters is that TLS doesn’t define an exporter for use
prior to the end of the handshake. That means the creation of a special
exporter for use in protecting 0-RTT data. That’s a pretty sharp object to
leave lying around, and it’s not clear what the properties we could provide.
(That doesn’t mean that there wouldn’t be demand for such a thing, the
possibility has already been raised.)An exporter-based scheme might opt not to use the handshake traffic keys to
protect QUIC packets during the handshake, relying instead on separate
protection for the TLS handshake records. This complicates implementations
somewhat, so an exporter might still be used.In the end, using an exporter doesn’t alter the design significantly. Given the
risks, a modification to the record protocol is probably safer.Implementations MUST NOT exchange data on any stream other than stream 1 prior
to the TLS handshake completing. However, QUIC requires the use of several
types of frame for managing loss detection and recovery. In addition, it might
be useful to use the data acquired during the exchange of unauthenticated
messages for congestion management.The actions that a peer takes as a result of receiving an unauthenticated packet
needs tobe limited. In particular, state established by these packets cannot be
retained once record protection commences.There are several approaches possible for dealing with unauthenticated packets
prior to handshake completion:discard and ignore themuse them, but reset any state that is established once the handshake completesuse them and authenticate them afterwards; failing the handshake if they can’t
be authenticatedsave them and use them when they can be properly authenticatedtreat them as a fatal errorDifferent strategies are appropriate for different types of data. This document
proposes that all strategies are possible depending on the type of message.Transport parameters and options are made usable and authenticated as part of
the TLS handshake (see ).Most unprotected messages are treated as fatal errors when received except for
the small number necessary to permit the handshake to complete (see
).Protected packets can be discarded, but can be saved and later used (see
).A client describes characteristics of the transport protocol it intends to
conduct with the server in a new QUIC-specific extension in its ClientHello.
The server uses this information to determine whether it wants to continue the
connection, request source address validation, or reject the connection. Having
this information unencrypted permits this check to occur prior to committing the
resources needed to complete the initial key exchange.If the server decides to complete the connection, it generates a corresponding
response and includes it in the EncryptedExtensions message.These parameters are not confidentiality-protected when sent by the client, but
the server response is protected by the handshake traffic keys. The entire
exchange is integrity protected once the handshake completes.This information is not used by TLS, but can be passed to the QUIC protocol as
initialization parmeters.The quic_parameters extension contains a declarative set of parameters that
establish QUIC operating parameters and constrain the behaviour of a peer. The
connection identifier and version are first negotiated using QUIC, and are
included in the TLS handshake in order to provide integrity protection.This extension MUST be included if a QUIC version is negotiated. A server MUST
NOT negotiate QUIC if this extension is not present.Based on the values offered by a client a server MAY use the values in this
extension to determine whether it wants to continue the connection, request
source address validation, or reject the connection. Since this extension is
initially unencrypted, the server can use the information prior to committing
the resources needed to complete a key exchange.If the server decides to use QUIC, this extension MUST be included in the
EncryptedExtensions message.The parameters are:
The 64-bit connection identifier for the connection, as selected by the
client.
The currently selected QUIC version that is used for the connection. This is
the version negotiated using the unauthenticated QUIC version negotiation
().
This is a list of supported QUIC versions for each peer. A client sends an
empty list if the version of QUIC being used is their preferred version;
however, a client MUST include their preferred version if this was not
negotiated using QUIC version negotiation. A server MUST include all versions
that it supports in this list.
The initial value for the connection flow control window for the endpoint, in
octets.
The initial value for the flow control window of new streams created by the
peer endpoint, in octets.
The time, in seconds, that a connection can remain idle before being
implicitly shutdown.
A list of parameters for the QUIC connection, expressed as key-value pairs of
arbitrary length. The QuicTransportParameterType identifies each parameter;
duplicate types are not permitted and MUST be rejected with a fatal
illegal_parameter alert. Type values are taken from a single space that is
shared by all QUIC versions.
There is currently no way to update the value of parameters once the
connection has started. QUIC crypto provided a SCFG message that could be
sent after the connection was established.
A list of options that can be negotiated for a given connection. These are
set during the initial handshake and are fixed thereafter. These options are
used to enable or disable optional features in the protocol.
The set of features that are supported across different versions might vary.
A client SHOULD include all options that it is willing to use. The server MAY
select any subset of those options that apply to the version of QUIC that it
selects. Only those options selected by the server are available for use.
This sort of optional behaviour seems like it could be accommodated
adequately by defining new versions of QUIC for each experiment. However,
as an evolving protocol, multiple experiments need to be conducted
concurrently and continuously. The options parameter provides a flexible
way to regulate which experiments are enabled on a per-connection basis.This section describes the handling of messages that are sent and received prior
to the completion of the TLS handshake.Sending and receiving unprotected messages is hazardous. Unless expressly
permitted, receipt of an unprotected message of any kind MUST be treated as a
fatal error.STREAM frames for stream 1 are permitted. These carry the TLS handshake
messages.Receiving unprotected STREAM frames that do not contain TLS handshake messages
MUST be treated as a fatal error.ACK frames are permitted prior to the handshake being complete. However, an
unauthenticated ACK frame can only be used to obtain NACK ranges. Timestamps
MUST NOT be included in an unprotected ACK frame, since these might be modified
by an attacker with the intent of altering congestion control response.
Information on FEC-revived packets is redundant, since use of FEC in this phase
is prohibited.ACK frames MAY be sent a second time once record protection is enabled. Once
protected, timestamps can be included.
This prohibition might be a little too strong, but this is the only obviously
safe option. If the amount of damage that an attacker can do by modifying
timestamps is limited, then it might be OK to permit the inclusion of
timestamps. Note that an attacker need not be on-path to inject an ACK.Sending a WINDOW_UPDATE on stream 1 might be necessary to permit the
completion of the TLS handshake, particularly in cases where the certification
path is lengthy. To avoid stalling due to flow control exhaustion,
WINDOW_UPDATE frames with stream 1 are permitted.Receiving a WINDOW_UPDATE frame on streams other than 1 MUST be treated as a
fatal error.Stream 1 is exempt from the connection-level flow control window.The position of the flow control window MUST be reset to defaults once the TLS
handshake is complete. This might result in the window position for either the
connection or stream 1 being smaller than the number of octets that have been
sent on those streams. A WINDOW_UPDATE frame might therefore be necessary to
prevent the connection from being stalled.
This is only potentially problematic for servers, who might need to send large
certificate chains. In other cases, this is unlikely given that QUIC - like
HTTP - is a protocol where the server is unable to exercise the
opportunity TLS presents to send first.If a server has a large certificate chain, or later modifications or
extensions to QUIC permit the server to send first, a client might reduce the
chance of stalling due to flow control in this first round trip by setting
larger values for the initial stream and connection flow control windows using
the quic_parameters extension ().
Unlike ACK, the prohibition on WINDOW_UPDATE is much less of an imposition
on implementations. And, given that a spurious WINDOW_UPDATE might be used
to create a great deal of memory pressure on an endpoint, the restriction
seems justifiable. Besides, I understand this one a lot better.FEC packets MUST NOT be sent prior to completing the TLS handshake. Endpoints
MUST treat receipt of an unprotected FEC packet as a fatal error.Due to reordering and loss, protected packets might be received by an endpoint
before the final handshake messages are received. If these can be decrypted
successfully, such packets MAY be stored and used once the handshake is
complete.Unless expressly permitted below, encrypted packets MUST NOT be used prior to
completing the TLS handshake, in particular the receipt of a valid Finished
message and any authentication of the peer. If packets are processed prior to
completion of the handshake, an attacker might use the willingness of an
implementation to use these packets to mount attacks.TLS handshake messages are covered by record protection during the handshake,
once key agreement has completed. This means that protected messages need to be
decrypted to determine if they are TLS handshake messages or not. Similarly,
ACK and WINDOW_UPDATE frames might be needed to successfully complete the
TLS handshake.Any timestamps present in ACK frames MUST be ignored rather than causing a
fatal error. Timestamps on protected frames MAY be saved and used once the TLS
handshake completes successfully.An endpoint MUST save the last protected WINDOW_UPDATE frame it receives for
each stream and apply the values once the TLS handshake completes.
Ugh. This last one is pretty ugly. Maybe we should just make the TLS
handshake exempt from flow control up to the Finished message. Then we can
prohibit unauthenticated WINDOW_UPDATE messages. We would still likely want
to account for the packets sent and received, since to do otherwise would
create some hairy special cases. That means that stalling is possible, but it
means that we can avoid ugly rules like the above.The QUIC connection identifier serves to identify a connection and to allow a
server to resume an existing connection from a new client address in case of
mobility events. However, this creates an identifier that a passive observer
can use to correlate connections.TLS 1.3 offers connection resumption using pre-shared keys, which also allows a
client to send 0-RTT application data. This mode could be used to continue a
connection rather than rely on a publicly visible correlator. This only
requires that servers produce a new ticket on every connection and that clients
do not resume from the same ticket more than once.The advantage of relying on 0-RTT modes for mobility events is that this is also
more robust. If the new point of attachment results in contacting a new server
instance - one that lacks the session state - then a fallback is easy.The main drawback with a clean restart or anything resembling a restart is that
accumulated state can be lost. Aside from progress on incomplete requests, the
state of the HPACK header compression table could be quite valuable. Existing
QUIC implementations use the connection ID to route packets to the server that
is handling the connection, which avoids this sort of problem.A lightweight state resurrection extension might be used to avoid having to
recreate any expensive state.There are likely to be some real clangers here eventually, but the current set
of issues is well captured in the relevant sections of the main text.Never assume that because it isn’t in the security considerations section it
doesn’t affect security. Most of this document does.This document has no IANA actions. Yet.Key words for use in RFCs to Indicate Requirement LevelsIn many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.The Transport Layer Security (TLS) Protocol Version 1.3This document specifies Version 1.3 of the Transport Layer Security (TLS) protocol. The TLS protocol allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.QUIC: A UDP-Based Secure and Reliable Transport for HTTP/2QUIC (Quick UDP Internet Connection) is a new multiplexed and secure transport atop UDP, designed from the ground up and optimized for HTTP/2 semantics. While built with HTTP/2 as the primary application protocol, QUIC builds on decades of transport and security experience, and implements mechanisms that make it attractive as a modern general-purpose transport. QUIC provides multiplexing and flow control equivalent to HTTP/2, security equivalent to TLS, and connection semantics, reliability, and congestion control equivalent to TCP.Transport Layer Security (TLS) Application-Layer Protocol Negotiation ExtensionThis document describes a Transport Layer Security (TLS) extension for application-layer protocol negotiation within the TLS handshake. For instances in which multiple application protocols are supported on the same TCP or UDP port, this extension allows the application layer to negotiate which protocol will be used within the TLS connection.Hypertext Transfer Protocol Version 2 (HTTP/2)This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2). HTTP/2 enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection. It also introduces unsolicited push of representations from servers to clients.This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's existing semantics remain unchanged.Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and RoutingThe Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document provides an overview of HTTP architecture and its associated terminology, defines the "http" and "https" Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.Pervasive Monitoring Is an AttackPervasive monitoring is a technical attack that should be mitigated in the design of IETF protocols, where possible.Transmission Control ProtocolChristian Huitema’s knowledge of QUIC is far better than my own. This would be
even more inaccurate and useless if not for his assistance. This document has
variously benefited from a long series of discussions with Ryan Hamilton, Jana
Iyengar, Adam Langley, Roberto Peon, Ian Swett, and likely many others who are
merely forgotten by a faulty meat computer.