From a0c571b42e22bdbf2f8e49f9fec03c2be6816ab5 Mon Sep 17 00:00:00 2001 From: EKR Date: Mon, 9 Oct 2017 12:05:34 -0700 Subject: [PATCH 1/2] AEAD all packets. Fixed #693, Fixes #840. This makes the change we discussed in Seattle where all Cleartext packets are encrypted with AES-GCM using a key derived from the client connection ID and a random per-version value. Note: I generated this value using randomness.org. --- draft-ietf-quic-tls.md | 100 ++++++++++++----------------------- draft-ietf-quic-transport.md | 16 ++++-- 2 files changed, 46 insertions(+), 70 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index af9214e2ee..60e2b1eef4 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -632,6 +632,33 @@ QUIC uses HKDF with the same hash function negotiated by TLS for key derivation. For example, if TLS is using the TLS_AES_128_GCM_SHA256, the SHA-256 hash function is used. +### Cleartext Packet Secrets {#cleartext-secrets} + +Cleartext packets are protected with secrets derived from the client's +connection ID. Specifically: + +~~~ + quic_version_1_salt = ed 1d a2 c6 0b ae 80 03 eb db 17 d8 92 5d 95 92 + 4a 6e 87 57 cd 48 d9 bf d2 41 c7 19 cb 80 81 ef + + cleartext_secret = HKDF-Extract(quic_version_1_salt, + client_connection_id) + + client_cleartext_secret = + HKDF-Expand-Label(cleartext_secret, + "QUIC client cleartext Secret", + "", Hash.length) + server_cleartext_secret = + HKDF-Expand-Label(cleartext_secret, + "QUIC server cleartext Secret", + "", Hash.length) +~~~ + +Future versions of QUIC SHOULD generate a new salt value, thus ensuring +that the keys are different for each version of QUIC. This prevents +a middlebox that only recognizes one version of QUIC from seeing or +modifying the contents of cleartext packets from future versions. + ### 0-RTT Secret {#zero-rtt-secrets} @@ -758,8 +785,11 @@ used for QUIC packet protection is AEAD that is negotiated for use with the TLS connection. For example, if TLS is using the TLS_AES_128_GCM_SHA256, the AEAD_AES_128_GCM function is used. -Regular QUIC packets are protected by an AEAD algorithm {{!RFC5116}}. Version -negotiation and public reset packets are not protected. +All QUIC packets other than version negotiation and public reset packets are +protected with an AEAD algorithm {{!RFC5116}}. Cleartext packets are protected +with the AEAD_AES_128_GCM and a key derived from the client's connection ID. +This provides protection against off-path attackers and robustness against +QUIC version unaware middleboxes, but not against on-path attackers. Once TLS has provided a key, the contents of regular QUIC packets immediately after any TLS messages have been sent are protected by the AEAD selected by TLS. @@ -838,64 +868,6 @@ number gaps on connection ID transitions. That secret is computed as: "", Hash.length) ~~~ -# Unprotected Packets - -QUIC adds an integrity check to all cleartext packets. Cleartext packets are -not protected by the negotiated AEAD (see {{packet-protection}}), but instead -include an integrity check. This check does not prevent the packet from being -altered, it exists for added resilience against data corruption and to provide -added assurance that the sender intends to use QUIC. - -Cleartext packets all use the long form of the QUIC header and so will include a -version number. For this version of QUIC, the integrity check uses the 64-bit -FNV-1a hash (see {{fnv1a}}). The output of this hash is appended to the payload -of the packet. - -The integrity check algorithm MAY change for other versions of the protocol. - - -## Integrity Check Processing - -An endpoint sending a packet that has a long header and a type that does not -indicate that the packet will be protected (that is, 0-RTT Encrypted (0x05), -1-RTT Encrypted (key phase 0) (0x06), or 1-RTT Encrypted (key phase 1) (0x07)) -first constructs the packet that it sends without the integrity check. - -The sender then calculates the integrity check over the entire packet, starting -from the type field. The output of the hash is appended to the packet. - -A receiver that receives an unprotected packet first checks that the version is -correct, then removes the trailing 8 octets. It calculates the integrity check -over the remainder of the packet. Unprotected packets that do not contain a -valid integrity check MUST be discarded. - - -## The 64-bit FNV-1a Algorithm {#fnv1a} - -QUIC uses the 64-bit version of the alternative Fowler/Noll/Vo hash (FNV-1a) -{{?FNV=I-D.eastlake-fnv}}. - -FNV-1a can be expressed in pseudocode as: - -~~~ -hash := offset basis -for each input octet: - hash := hash XOR input octet - hash := hash * prime -~~~ - -That is, a 64-bit unsigned integer is initialized with an offset basis. Then, -for each octet of the input, the exclusive binary OR of the value is taken, then -multiplied by a prime. Any overflow from multiplication is discarded. - -The offset basis for the 64-bit FNV-1a is the decimal value 14695981039346656037 -(in hex, 0xcbf29ce484222325). The prime is 1099511628211 (in hex, -0x100000001b3; or as an expression 2^40 + 2^8 + 0xb3). - -Once all octets have been processed in this fashion, the final integer value is -encoded as 8 octets in network byte order. - - # Key Phases As TLS reports the availability of 0-RTT and 1-RTT keys, new keying material can @@ -924,10 +896,8 @@ ensure that TLS handshake messages are sent with the correct packet protection. ## Packet Protection for the TLS Handshake {#cleartext-hs} -The initial exchange of packets are sent without protection. These packets use -a cleartext packet type. - -TLS handshake messages MUST NOT be protected using QUIC packet protection. All +The initial exchange of packets are sent using a cleartext packet type and +AEAD-protected using the initial key as described in {{cleartext-secrets}}. All TLS handshake messages up to the TLS Finished message sent by either endpoint use cleartext packets. @@ -944,7 +914,7 @@ client in cleartext packets. ### Initial Key Transitions {#first-keys} Once the TLS handshake is complete, keying material is exported from TLS and -QUIC packet protection commences. +used to protect QUIC packets. Packets protected with 1-RTT keys initially have a KEY_PHASE bit set to 0. This bit inverts with each subsequent key update (see {{key-update}}). diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 285be2deb7..3e6a99edcf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -555,8 +555,11 @@ Cleartext packets are sent during the handshake prior to key negotiation. All cleartext packets contain the current QUIC version in the version field. -The payload of cleartext packets also includes an integrity check, which is -described in {{QUIC-TLS}}. +In order to prevent tampering by version-unaware middleboxes, Cleartext +packets are protected with a connection and version specific key, as +described in {{QUIC-TLS}}. This protection does not provide confidentiality +or integrity against on-path attackers, but provides some level of +protection against off-path attackers. ### Client Initial Packet {#packet-client-initial} @@ -926,8 +929,9 @@ Version Negotiation packet. A client MUST ignore a Version Negotiation packet that lists the client's chosen version. -Version negotiation uses unprotected data. The result of the negotiation MUST be -revalidated as part of the cryptographic handshake (see {{version-validation}}). +Version negotiation packets have no cryptographic protection. The +result of the negotiation MUST be revalidated as part of the +cryptographic handshake (see {{version-validation}}). ### Using Reserved Versions @@ -1638,6 +1642,8 @@ connection that is reset by revealing the Stateless Reset Token cannot be reused for new connections at the same server without first changing to use a different static key or server identifier. +Note that Stateless Reset messages do not have any cryptographic protection. + # Frame Types and Formats @@ -3316,7 +3322,7 @@ Issue and pull request numbers are listed with a leading octothorp. ## Since draft-ietf-quic-transport-06 -Nothing yet. +- Replaced FNV-1a with AES-GCM for all "Cleartext" packets. ## Since draft-ietf-quic-transport-05 From cf605489cedb96ccc796ba5735d132e81b5e56c4 Mon Sep 17 00:00:00 2001 From: EKR Date: Mon, 9 Oct 2017 16:58:17 -0700 Subject: [PATCH 2/2] Update salt. This salt isn't random but rather is the git hash of the revision corresponding to the -06 drafts. It's still essentially arbitrary but now it's predictable arbitrary. --- draft-ietf-quic-tls.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 60e2b1eef4..8f560c528a 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -638,8 +638,7 @@ Cleartext packets are protected with secrets derived from the client's connection ID. Specifically: ~~~ - quic_version_1_salt = ed 1d a2 c6 0b ae 80 03 eb db 17 d8 92 5d 95 92 - 4a 6e 87 57 cd 48 d9 bf d2 41 c7 19 cb 80 81 ef + quic_version_1_salt = afc824ec5fc77eca1e9d36f37fb2d46518c36639 cleartext_secret = HKDF-Extract(quic_version_1_salt, client_connection_id) @@ -896,10 +895,10 @@ ensure that TLS handshake messages are sent with the correct packet protection. ## Packet Protection for the TLS Handshake {#cleartext-hs} -The initial exchange of packets are sent using a cleartext packet type and -AEAD-protected using the initial key as described in {{cleartext-secrets}}. All -TLS handshake messages up to the TLS Finished message sent by either endpoint -use cleartext packets. +The initial exchange of packets are sent using a cleartext packet type +and AEAD-protected using the cleartext key generated as described in +{{cleartext-secrets}}. All TLS handshake messages up to the TLS +Finished message sent by either endpoint use cleartext packets. Any TLS handshake messages that are sent after completing the TLS handshake do not need special packet protection rules. Packets containing these messages use