Re: [quicwg/base-drafts] token-based greasing / initial packet protection (#3166)

David Schinazi <notifications@github.com> Tue, 29 October 2019 17:41 UTC

Return-Path: <noreply@github.com>
X-Original-To: quic-issues@ietfa.amsl.com
Delivered-To: quic-issues@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 7CF0B1200F5 for <quic-issues@ietfa.amsl.com>; Tue, 29 Oct 2019 10:41:31 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -8
X-Spam-Level:
X-Spam-Status: No, score=-8 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=github.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id miDraWpcIetA for <quic-issues@ietfa.amsl.com>; Tue, 29 Oct 2019 10:41:29 -0700 (PDT)
Received: from out-20.smtp.github.com (out-20.smtp.github.com [192.30.252.203]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id C8375120018 for <quic-issues@ietf.org>; Tue, 29 Oct 2019 10:41:28 -0700 (PDT)
Received: from github-lowworker-edec459.ac4-iad.github.net (github-lowworker-edec459.ac4-iad.github.net [10.52.18.32]) by smtp.github.com (Postfix) with ESMTP id 14C038C0783 for <quic-issues@ietf.org>; Tue, 29 Oct 2019 10:41:28 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; s=pf2014; t=1572370888; bh=6RPiaa0NnNG1b7fK3nsHFvS2+wYzf4xZG2cydc7fdao=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=IJhkal2T/sUWE1BnlOTEYoCsAruTZmTPZNrGp6FKp+UMmuX4hxoAfR4S2iU0dbQR5 hb3aIB0YRcDwGj6OYvXyQVQUqgBbMgVdJOU8YeXghpyydm19WIBb/81lpFsNKk03aD WM5Hlrb8pg74LJoFQHd9I04GVnb2tIxryV0Zsiws=
Date: Tue, 29 Oct 2019 10:41:27 -0700
From: David Schinazi <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+AFTOJKYKQZ2N4OQTIADEUBF3YW5FPEVBNHHB5HRKFQ@reply.github.com>
To: quicwg/base-drafts <base-drafts@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Message-ID: <quicwg/base-drafts/pull/3166/review/308689911@github.com>
In-Reply-To: <quicwg/base-drafts/pull/3166@github.com>
References: <quicwg/base-drafts/pull/3166@github.com>
Subject: Re: [quicwg/base-drafts] token-based greasing / initial packet protection (#3166)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5db879c7e4ce2_60323fcec2ecd968435b9"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: DavidSchinazi
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
X-GitHub-Recipient-Address: quic-issues@ietf.org
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic-issues/NbgUPFo6uKIlCBZcJwAu65LdmDg>
X-BeenThere: quic-issues@ietf.org
X-Mailman-Version: 2.1.29
List-Id: Notification list for GitHub issues related to the QUIC WG <quic-issues.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic-issues/>
List-Post: <mailto:quic-issues@ietf.org>
List-Help: <mailto:quic-issues-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 29 Oct 2019 17:41:32 -0000

DavidSchinazi commented on this pull request.

Thanks for writing this up! I like the token approach but we might need to tighten how this interacts with version negotiation.

> @@ -2721,6 +2721,66 @@ between endpoints.  Application protocols SHOULD define rules for handling
 streams that are prematurely cancelled by either endpoint.
 
 
+# Alternative Initial Set {#alternative-initial}
+
+In order to avoid ossification of the cleartext and obfuscated fields of QUIC
+packets, a server can announce an alternative set of initial values to be used,
+which is comprised of:
+
+* Alternative version number; a 32-bit unsigned number that is to be presented
+  on wire in place of the version number specified in this document.  This value
+  MUST NOT be a reserved version ({{versions}}).
+
+* Packet type modifier; a two-bit value that is to be applied as a bit-wise
+  exclusive or (XOR) to the most significant bits of the Initial, Handshake,

Shouldn't this be `to the Long Packet Type field of` instead of `to the most significant bits of` ?

> +  0-RTT, and Retry packets. This XOR is applied after the packets are encrypted
+  and before they are decrypted.
+
+* Alternative initial salt; a 16-byte binary blob that is to be used in place of
+  the initial salt defined in section 5.2 of {{QUIC-TLS}}.
+
+A server advertises these values using a NEW_TOKEN frame {{frame-new-token}}.
+The token MUST include or associated with the alternative version number with
+which it can be used.
+
+Typically, a server would pre-allocate a set of unused version numbers as the
+alternative version numbers, associating each of those version numbers with a
+packet type modifier chosen at random.  Then, when issuing a token using a
+NEW_TOKEN frame, the server generates the alternative initial salt by calling a
+pseudo-random function, embeds that initial salt into the token which is then
+encrypted, and sends a NEW_TOKEN frame that comprises of the generated token and

I might be worth adding a bit more detail to how the token is encrypted, perhaps `which is then encrypted using a key only known to the server`

> +NEW_TOKEN frame, the server generates the alternative initial salt by calling a
+pseudo-random function, embeds that initial salt into the token which is then
+encrypted, and sends a NEW_TOKEN frame that comprises of the generated token and
+the alternative initial set.
+
+When the client reconnects to the server by using the provided token and the
+alternative initial set, the server first checks if the version number field of
+the incoming packet contains one of the alternative version numbers it
+advertises, then if that is the case, applies the corresponding packet type
+modifier to recover the correct packet type.  If the recovered packet type is an
+Initial packet and that packet contains a NEW_TOKEN token, the server decrypts
+the embedded token and recovers the alternative initial salt, uses that to
+decrypt the payload of the Initial packet.
+
+When the server is incapable of determining the alternative initial salt, it can
+send a Version Negotiation packet that instructs the client to use the default

In the current spec, the client fails the connection upon receipt of a Version Negotiation packet. So this has a dependency on the version downgrade prevention extension.

But assuming the presence of a version negotiation mechanism with downgrade prevention, I think we have an issue here. If the server rotates the key it uses to encrypt the alternative initial salt, and then receives a token it can no longer decrypt, it sends a version negotiation packet, and the client tries again with QUICv1. This is likely to trip the version downgrade prevention mechanism - how do we distinguish between a server that has forgotten their key and an attacker that is trying to force a downgrade to QUICv1?

> @@ -3940,6 +4007,19 @@ 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.
 
+Additionally, the token is accompanied by a checksum.  This is because when a

Seeing a checksum here makes me uncomfortable. We're adding a checksum to retry packets because they have no other mechanism to detect corruption. Initial packets on the other hand have an auth tag, so a corrupted token will cause the deprotection to fail. In an ideal world we should handle that like any other corruption on the initial packet. But I think this goes back to my other question about version negotiation, I think there be dragons.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3166#pullrequestreview-308689911