From 1e8d5dab076371e0e3672320f97494b824139b1a Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 28 Apr 2017 14:35:32 +1000 Subject: [PATCH 1/3] Add a description of the FNV-1a algorithm I've added this in the TLS document, even though this would have been easier to add to the transport document in some ways. The current plan (if we ever clear our backlog) is to move the details of the packet protection and key schedule to the transport. If that ever happens, it will be easy enough to move this new text at the same time as the packet protection. Two choices that I made here: 1. all packets are protected, including Public Reset - this means that the packet construction code can have very simple logic for determining whether to add an integrity check, namely is there an AEAD?; the cost being that public reset is a little bigger 2. the integrity check mechanism can change in a new version - this avoids expanding the list of things that we promise that won't change between versions; the cost being one extra trivial check on receiving an unprotected packet --- draft-ietf-quic-tls.md | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 90e9c245e2..61aaa26e15 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -83,6 +83,15 @@ informative: org: Google role: editor + FNV: + title: "FNV Hash" + date: 2015-01-07 + author: + - + ins: L. Noll + name: Landon Curt Noll + target: "http://www.isthe.com/chongo/tech/comp/fnv/" + --- abstract @@ -821,6 +830,73 @@ used in QUIC can cause packet numbers to be decoded incorrectly if they are delayed significantly. +# Unprotected Packets + +QUIC adds an integrity check to all unprotected packets. Any packet that is not +protected by the negotiated AEAD (see {{packet-protection}}), includes a +integrity check. This check does not prevent the packet from being altered, it +exists for added resilience against data corruption and to provided added +assurance that the sender intends to use QUIC. + +Unprotected 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 +128-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. + +In constructing the packet, the endpoint has to consider the extra length that +the integrity check will add relative to the path MTU. In particular, the +integrity check length needs to be subtracted from available space when padding +the initial client packet. + +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 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. + +An implementation could choose to treat the addition and removal of the +integrity check as though it were an AEAD. + + +## The 128-bit FNV-1a Algorithm {#fnv1a} + +QUIC uses the 128-bit version of the alternative Fowler/Noll/Vo hash, or FNV-1a +{{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 128-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 128-bit FNV-1a is the decimal value +144066263297769815596495629667062367629 (in hex, +0x6c62272e07bb014262b821756295c58d). The prime is 309485009821345068724781371 +(in hex, 0x1000000000000000000013b; or as an expression 2^88 + 2^8 + 0x3b). + +Once all octets have been processed in this fashion, the final integer value is +encoded on 16 octets in network byte order. + + # Key Phases As TLS reports the availability of 0-RTT and 1-RTT keys, new keying material can From b19829cff70c5ea38b9be97e9b2335a3676ca900 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 28 Apr 2017 16:43:36 +1000 Subject: [PATCH 2/3] Remove advice --- draft-ietf-quic-tls.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 61aaa26e15..6a0c949fed 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -866,9 +866,6 @@ correct, then removes the trailing 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. -An implementation could choose to treat the addition and removal of the -integrity check as though it were an AEAD. - ## The 128-bit FNV-1a Algorithm {#fnv1a} From d4622fda0bc141ecc7fa23357da5df1f60aab345 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 1 May 2017 12:22:39 +1000 Subject: [PATCH 3/3] Review comments --- draft-ietf-quic-tls.md | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 6a0c949fed..fd8b1800ce 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -83,15 +83,6 @@ informative: org: Google role: editor - FNV: - title: "FNV Hash" - date: 2015-01-07 - author: - - - ins: L. Noll - name: Landon Curt Noll - target: "http://www.isthe.com/chongo/tech/comp/fnv/" - --- abstract @@ -853,24 +844,19 @@ 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. -In constructing the packet, the endpoint has to consider the extra length that -the integrity check will add relative to the path MTU. In particular, the -integrity check length needs to be subtracted from available space when padding -the initial client packet. - 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 octets. It calculates the integrity check +correct, then removes the trailing 16 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 128-bit FNV-1a Algorithm {#fnv1a} -QUIC uses the 128-bit version of the alternative Fowler/Noll/Vo hash, or FNV-1a -{{FNV}}. +QUIC uses the 128-bit version of the alternative Fowler/Noll/Vo hash (FNV-1a) +{{?FNV=I-D.eastlake-fnv}}. FNV-1a can be expressed in pseudocode as: @@ -891,7 +877,7 @@ The offset basis for the 128-bit FNV-1a is the decimal value (in hex, 0x1000000000000000000013b; or as an expression 2^88 + 2^8 + 0x3b). Once all octets have been processed in this fashion, the final integer value is -encoded on 16 octets in network byte order. +encoded as 16 octets in network byte order. # Key Phases