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

MikkelFJ <notifications@github.com> Thu, 31 October 2019 08:25 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 00B9512084F for <quic-issues@ietfa.amsl.com>; Thu, 31 Oct 2019 01:25:07 -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 AsigiKoiTNPP for <quic-issues@ietfa.amsl.com>; Thu, 31 Oct 2019 01:25:04 -0700 (PDT)
Received: from out-2.smtp.github.com (out-2.smtp.github.com [192.30.252.193]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 1FBCF12084A for <quic-issues@ietf.org>; Thu, 31 Oct 2019 01:25:04 -0700 (PDT)
Date: Thu, 31 Oct 2019 01:25:03 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; s=pf2014; t=1572510303; bh=XSVRTPE/+xq1pL8HxDphtEsaTkvCpEeF+jlLiHW97Ts=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=I+kwqZQNDlE+XrLkXzvTHXMUa6cXiB9rc0/OOqazFOH5Wls2cDm3oqHOlAU4Hn5Jq n/kTrV0mCj1Fqgxb+wR6eLV5hjTZJmMX5t5/YjQ0LkYcy4K9J4zRGzi46sunrbopAN JH/ZzbMquzkvZSslXtov/TFKKXmy6QgjfOZFr74A=
From: MikkelFJ <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+AFTOJK77UFZ5H66NZHDSVRV3Y7GN7EVBNHHB5HRKFQ@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/309698002@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_5dba9a5f4efb7_d7c3feb096cd96c7579e4"; charset=UTF-8
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: mikkelfj
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/x9xpmmVdJjfPK2Z33oDN_hk_Ft8>
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: Thu, 31 Oct 2019 08:25:07 -0000

mikkelfj commented on this pull request.



> @@ -2721,6 +2724,96 @@ between endpoints.  Application protocols SHOULD define rules for handling
 streams that are prematurely cancelled by either endpoint.
 
 
+# Seeding {#seeding}
+
+In order to avoid ossification of the cleartext and obfuscated fields of QUIC
+packets, a server can announce a set of alternative initial values to be used,
+which is comprised of:
+
+* 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 obfuscates the Long Packet Type of
+  a long header packet ({{long-header}}).  The long packet type bits of a long
+  header packet is encoded as an bti-wise exclusive or (XOR) of the packet type

```suggestion
  header packet is encoded as an bit-wise exclusive or (XOR) of the packet type
```

> +
+The rest of this section applies to the servers that advertise non-default
+values as their seeds.
+
+
+## Server Behavior
+
+Typically, a server that advertises the alternative seeds would act in the
+following steps:
+
+* The server pre-allocates 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.
+
+* When issuing a NEW_TOKEN token, the server generates the alternative initial
+  salt by calling a pseudo-random function.  Then it builds a token that

There is no need to use a pseudo-random function if the server has access to better randomness (but to be fair this is for a typical implementation). I would just say it generates a cryptographically secure random number.

> +values as their seeds.
+
+
+## Server Behavior
+
+Typically, a server that advertises the alternative seeds would act in the
+following steps:
+
+* The server pre-allocates 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.
+
+* When issuing a NEW_TOKEN token, the server generates the alternative initial
+  salt by calling a pseudo-random function.  Then it builds a token that
+  embeds the alternative seeds including the initial salt being generated.  The
+  token will be encrypted using a key known only to the server, thereby

```suggestion
  token will be encrypted using a key known only to the server, or server cluster, thereby
```

> +## Server Behavior
+
+Typically, a server that advertises the alternative seeds would act in the
+following steps:
+
+* The server pre-allocates 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.
+
+* When issuing a NEW_TOKEN token, the server generates the alternative initial
+  salt by calling a pseudo-random function.  Then it builds a token that
+  embeds the alternative seeds including the initial salt being generated.  The
+  token will be encrypted using a key known only to the server, thereby
+  conforming to the requirements in {{validate-future}}. After that, the server
+  sends a NEW_TOKEN frame that contains the generated token and the seeds that
+  have been embedded to that token.

```suggestion
  have been embedded into that token.
```

> +  have been embedded to that token.
+
+* When the client reconnects to the server by using the provided token and the
+  seeds, 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 initial salt, uses that to decrypt the payload of the
+  Initial packet.
+
+* When sending a Retry in response to an Initial packet carrying an alternative
+  version number, the server embeds the NEW_TOKEN token found in the Initial
+  packet within the retry token it issues.  Once the server receives a response
+  from the client carrying that retry token and the path is validated, it
+  decrypts the NEW_TOKEN token embedded in the retry token to recover the

```suggestion
  decrypts the NEW_TOKEN token embedded within the retry token to recover the
```

> +  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 initial salt, uses that to decrypt the payload of the
+  Initial packet.
+
+* When sending a Retry in response to an Initial packet carrying an alternative
+  version number, the server embeds the NEW_TOKEN token found in the Initial
+  packet within the retry token it issues.  Once the server receives a response
+  from the client carrying that retry token and the path is validated, it
+  decrypts the NEW_TOKEN token embedded in the retry token to recover the
+  alternative initial salt that is to be used for unprotecting the packet
+  payload.
+
+Instead of associating a new alternative initial salt to every NEW_TOKEN token,

```suggestion
Instead of associating a new alternative initial salt with every NEW_TOKEN token,
```

> +* When sending a Retry in response to an Initial packet carrying an alternative
+  version number, the server embeds the NEW_TOKEN token found in the Initial
+  packet within the retry token it issues.  Once the server receives a response
+  from the client carrying that retry token and the path is validated, it
+  decrypts the NEW_TOKEN token embedded in the retry token to recover the
+  alternative initial salt that is to be used for unprotecting the packet
+  payload.
+
+Instead of associating a new alternative initial salt to every NEW_TOKEN token,
+a server might map a fixed salt to each of the alternative version numbers it
+issues.  Such design is not recommended, as an active attacker might build a
+list of known alternative version numbers and their initial salts and use that
+list to decrypt the payload of Initial packets using those alternative version
+numbers.  But still, having a set of version numbers and initial salts used
+concurrently is considered better than just using the default values of QUIC in
+terms of preventing ossification.

I am not comfortable with the slack given here. While it does improve things when salt is reused, it also gives the client a false sense of security. It would be better if the client could be certain that it does indeed sent private information on the wire.

For example it might create an initial connection to bootstrap safety, similar to if it connected to a secure DNS with crypto keys (TBD), and then reconnects to send confidential informational information. 

Taking this one further, it would be advantageous if a token could be used across different server certificates so the initial certificate could be "harmless" in order to enhance privacy.

> +issues.  Such design is not recommended, as an active attacker might build a
+list of known alternative version numbers and their initial salts and use that
+list to decrypt the payload of Initial packets using those alternative version
+numbers.  But still, having a set of version numbers and initial salts used
+concurrently is considered better than just using the default values of QUIC in
+terms of preventing ossification.
+
+A server MUST NOT send a Version Negotitation packet in response to a long
+header packet with an alternative version number it has advertised.
+
+
+## Distributing the Seeds
+
+This specification defines how the seeds are used as well as how they are
+advertised using a NEW_TOKEN frame.  Other specifications MAY define other
+methods for distributing or deducing these seeds.

What are "other specifications"? Another QUIC version?

> @@ -2721,6 +2724,96 @@ between endpoints.  Application protocols SHOULD define rules for handling
 streams that are prematurely cancelled by either endpoint.
 
 
+# Seeding {#seeding}
+
+In order to avoid ossification of the cleartext and obfuscated fields of QUIC
+packets, a server can announce a set of alternative initial values to be used,
+which is comprised of:
+
+* 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}}).

It is not very clear from this text if the intention is to generate a new representation of the same version in which the token was generated, or there is indeed a new version. Since this does not cover version negotiation, it presumably refers to the same version. But that could change as versions get added and perhaps V1 should be prepared for that (I'm not sure I am getting this right). @MikeBishop alluded to something similar in an earlier comment AFAIR.

-- 
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-309698002