diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 756e6b5d76..4582cc16b0 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -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. + +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 +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. + + # Key Update Once the handshake is confirmed (see {{handshake-confirmed}}), an endpoint MAY diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 8bd14ff5e8..ebfabe71e5 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -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 -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 @@ -4178,12 +4179,16 @@ wishes to perform a retry (see {{validate-handshake}}). +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Connection ID (0..160) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| ODCID Len (8) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Original Destination Connection ID (0..160) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Retry Token (*) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | ++ + +| | ++ Retry Integrity Tag (128) + +| | ++ + +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ {: #retry-format title="Retry Packet"} @@ -4191,24 +4196,14 @@ 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}}. + @@ -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. @@ -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