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

Add retry integrity tag #3120

Merged
merged 14 commits into from
Jan 17, 2020
58 changes: 58 additions & 0 deletions draft-ietf-quic-tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,64 @@ TLS ClientHello. The server MAY retain these packets for later decryption in
anticipation of receiving a ClientHello.


## Retry Packet Integrity {#retry-integrity}

Retry packets (see the Retry Packet section of {{QUIC-TRANSPORT}}) carry a
Retry Integrity Tag that provides two properties: it allows discarding
packets that have accidentally been corrupted by the network, and it diminishes
off-path attackers' ability to send valid Retry packets.
DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved

The Retry Integrity Tag is a 128-bit field that is computed as the output of
AEAD_AES_128_GCM {{!AEAD=RFC5116}} used with the following inputs:

- The secret key, K, is 128 bits equal to 0xf5ed4642e0e4c8d878bbbc8a828821c9.
- The nonce, N, is 96 bits all set to zero.
- The plaintext, P, is empty.
- The associated data, A, is the contents of the Retry Pseudo-Packet, as
illustrated in {{retry-pseudo}}:

~~~
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ODCID Len (8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Original Destination Connection ID (0..160) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|1| 3 | Unused|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version (32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Connection ID (0..160) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Connection ID (0..160) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Retry Token (*) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~~
{: #retry-pseudo title="Retry Pseudo-Packet"}

The Retry Pseudo-Packet is not sent over the wire. It is computed by taking
DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved
the transmitted Retry packet, removing the Retry Integrity Tag and prepending
the two following fields:

ODCID Len:

: The ODCID Len contains the length in bytes of the Original Destination
Connection ID field that follows it, encoded as an 8-bit unsigned integer.

Original Destination Connection ID:

: The Original Destination Connection ID contains the value of the Destination
Connection ID from the Initial packet that this Retry is in response to. The
length of this field is given in ODCID Len. The presence of this field
mitigates an off-path attacker's ability to inject a Retry packet.

DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved

# Key Update

Once the handshake is confirmed (see {{handshake-confirmed}}), an endpoint MAY
Expand Down
52 changes: 23 additions & 29 deletions draft-ietf-quic-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -2806,10 +2806,11 @@ available.

## Protected Packets {#packet-protected}

All QUIC packets except Version Negotiation and Retry packets use authenticated
All QUIC packets except Version Negotiation packets use authenticated
encryption with additional data (AEAD) {{!RFC5116}} to provide confidentiality
DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved
and integrity protection. Details of packet protection are found in
{{QUIC-TLS}}; this section includes an overview of the process.
and integrity protection. Retry packets use an AEAD to provide integrity
protection. Details of packet protection are found in {{QUIC-TLS}}; this
section includes an overview of the process.

Initial packets are protected using keys that are statically derived. This
packet protection is not effective confidentiality protection. Initial
Expand Down Expand Up @@ -4178,37 +4179,31 @@ wishes to perform a retry (see {{validate-handshake}}).
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Connection ID (0..160) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ODCID Len (8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Original Destination Connection ID (0..160) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Retry Token (*) ...
DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Retry Integrity Tag (128) +
DavidSchinazi marked this conversation as resolved.
Show resolved Hide resolved
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~~
{: #retry-format title="Retry Packet"}

A Retry packet (shown in {{retry-format}}) does not contain any protected
fields. The value in the Unused field is selected randomly by the server. In
addition to the long header, it contains these additional fields:

ODCID Len:

: The ODCID Len contains the length in bytes of the Original Destination
Connection ID field that follows it. This length is encoded as a 8-bit
unsigned integer. In QUIC version 1, this value MUST NOT exceed 20 bytes.
Clients that receive a version 1 Retry Packet with a value larger than 20 MUST
drop the packet.

Original Destination Connection ID:

: The Original Destination Connection ID contains the value of the Destination
Connection ID from the Initial packet that this Retry is in response to. The
length of this field is given in ODCID Len.

Retry Token:

: An opaque token that the server can use to validate the client's address.

Retry Integrity Tag:

: See the Retry Packet Integrity section of {{QUIC-TLS}}.

<!-- Break this stuff up a little, maybe into "Sending Retry" and "Processing
Retry" sections. -->

Expand All @@ -4233,11 +4228,11 @@ A client MUST accept and process at most one Retry packet for each connection
attempt. After the client has received and processed an Initial or Retry packet
from the server, it MUST discard any subsequent Retry packets that it receives.

Clients MUST discard Retry packets that contain an Original Destination
Connection ID field that does not match the Destination Connection ID from its
Initial packet. This prevents an off-path attacker from injecting a Retry
packet. A client MUST discard a Retry packet with a zero-length Retry Token
field.
Clients MUST discard Retry packets that have a Retry Integrity Tag that cannot
be validated, see the Retry Packet Integrity section of {{QUIC-TLS}}. This
diminishes an off-path attacker's ability to inject a Retry packet and protects
against accidental corruption of Retry packets. A client MUST discard a Retry
packet with a zero-length Retry Token field.

The client responds to a Retry packet with an Initial packet that includes the
provided Retry Token to continue connection establishment.
Expand Down Expand Up @@ -4268,9 +4263,8 @@ processing a Retry packet; {{packet-0rtt}} contains more information on this.
A server acknowledges the use of a Retry packet for a connection using the
original_connection_id transport parameter (see
{{transport-parameter-definitions}}). If the server sends a Retry packet, it
MUST include the value of the Original Destination Connection ID field of the
Retry packet (that is, the Destination Connection ID field from the client's
first Initial packet) in the transport parameter.
MUST include the Destination Connection ID field from the client's first
Initial packet in the transport parameter.

If the client received and processed a Retry packet, it MUST validate that the
original_connection_id transport parameter is present and correct; otherwise, it
Expand Down