RE: Packet number encryption

Mikkel Fahnøe Jørgensen <mikkelfj@gmail.com> Fri, 09 February 2018 21:18 UTC

Return-Path: <mikkelfj@gmail.com>
X-Original-To: quic@ietfa.amsl.com
Delivered-To: quic@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 3017E127286 for <quic@ietfa.amsl.com>; Fri, 9 Feb 2018 13:18:24 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.698
X-Spam-Level:
X-Spam-Status: No, score=-2.698 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001, UNPARSEABLE_RELAY=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.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 75c_pggSVdmE for <quic@ietfa.amsl.com>; Fri, 9 Feb 2018 13:18:20 -0800 (PST)
Received: from mail-it0-x22f.google.com (mail-it0-x22f.google.com [IPv6:2607:f8b0:4001:c0b::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 2510F1242F7 for <quic@ietf.org>; Fri, 9 Feb 2018 13:18:20 -0800 (PST)
Received: by mail-it0-x22f.google.com with SMTP id e1so12317859ita.0 for <quic@ietf.org>; Fri, 09 Feb 2018 13:18:20 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:in-reply-to:references:mime-version:date:message-id:subject:to :cc; bh=Sx9uWqdM5yRwaNuFA/GCgDShIWMjyc16f6lbb94ol3I=; b=mlVN041nx7mg3iq8oqbhiPwmMsNB9uafSZtmJQl7J5eXspy61v7ry/kjHtIysUDZK/ 4nJ+UOyOev1EreNj8AytIKZVnznoIlOZ3OWU/d0bhbRwKxleiwhZDE5FcgLwZ00jazAS cgRiOiuu9uKKyTpX2xeffkIGr8czYHix8ANSq3HdGdnTsnWhqhejKh52m88EEpl/HtPJ IRqWSwWZWpWqtIhR+7LYORf7rKJaq1fh3hFrwlxUULoLsJuhqVzZsvb/C1kLWwilheiF UnSBe5+Fq2Kq8h9980x0b244eTaYQjJYWndlalJ4AVs7Pf7hnSinei7Qh9QJH51oZWvw uivA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:in-reply-to:references:mime-version:date :message-id:subject:to:cc; bh=Sx9uWqdM5yRwaNuFA/GCgDShIWMjyc16f6lbb94ol3I=; b=KkuBixR5sA1pQc8s0bot3DZ90xWoCe/hBqQyiTmOXkj8W8ZWhCdI3GMzluQxwv07S2 tLOFpdKa5YzZC6AEMarqCO4Ga8HOy1QF2DzwNE+AKRc4MrADdhwnjP0nSINYtjhwmlB8 BgimYq4CNtVTStSgpwlR90syglkLIAEHwCT4A4h/Nj2XOaC9eK7eDUG+ytRaAsvimkna 4o5EyXqDI9fkl5MIn1GZDyvErnlhBTNFMTUkEVqdQJKN/P9tlVBjne6rBR/6yr6Q8nSw uyVr93vCqDNoPXV/NE6wfCjiWGAJqAoh+qCHjazRmRe6/b8KHvMTB+s1B1ssfyBb9t1j 1Pwg==
X-Gm-Message-State: APf1xPB9wWvYm80xFP7NHBxTiZ/vOnR76aJahNJz8WdbSwginDzyJgav KiGzb0lRzWdkED1LezYrGlBsbqfAgNBQdXd00zU=
X-Google-Smtp-Source: AH8x225yIDEL8rpT8LoibZC1w+Vr+Bstw2SCJQ7Zf5hCVs3qhZveetrn/7nXY3BDPMmeJrd7DxmL3+Frmq7erOITq2Q=
X-Received: by 10.36.178.26 with SMTP id u26mr5058784ite.4.1518211099393; Fri, 09 Feb 2018 13:18:19 -0800 (PST)
Received: from 1058052472880 named unknown by gmailapi.google.com with HTTPREST; Fri, 9 Feb 2018 13:18:18 -0800
From: Mikkel Fahnøe Jørgensen <mikkelfj@gmail.com>
In-Reply-To: <1F436ED13A22A246A59CA374CBC543998B58BAD7@ORSMSX111.amr.corp.intel.com>
References: <CABkgnnVyo3MmWtVULiV=FJTnR528qfY8-OmKGWAs0bCvri-a_g@mail.gmail.com> <CAGD1bZauKbucs_5n7RQbK8H2HiyfiqpGVEcKreGA6umhMBSFgg@mail.gmail.com> <CABcZeBPNrc-9vANSH02r++p53s6gN4pVB8DMd80nUxOhKTp3dA@mail.gmail.com> <CAKcm_gMvHSBhpUvsQCCkV2_o+d_wchF3R3L6H8mp6nKNaaRmSw@mail.gmail.com> <CY4PR21MB0133CCAA6807469BA983D00BB6FC0@CY4PR21MB0133.namprd21.prod.outlook.com> <CABkgnnW4xr_YzpsvCxaJJgcQdBTuX=Yv735_sdd4VoMfji8mbA@mail.gmail.com> <CY4PR21MB0133C759D4A08A4988B641B2B6FC0@CY4PR21MB0133.namprd21.prod.outlook.com> <bdf88936-8edc-d56e-ee59-c9d597058edd@huitema.net> <CY4PR21MB01337C8A700E58B49D90B712B6FC0@CY4PR21MB0133.namprd21.prod.outlook.com> <119b3276-5799-1cc3-8982-7479171bbf27@huitema.net> <CAOYVs2pi8-NVuS+crNMfjsP-n5upK3=5tPeQ8OSGpOvL6RTrjA@mail.gmail.com> <CY4PR21MB0133A1117B2733BBCF049C5FB6FC0@CY4PR21MB0133.namprd21.prod.outlook.com> <MWHPR08MB24327A7BB5AE1AE70FE5CDB1DAF30@MWHPR08MB2432.namprd08.prod.outlook.com> <533a0a2e-3a87-b55f-84ce-c52bc03cd81c@huitema.net> <MWHPR21MB0144C68102972A668611E1FCB6F20@MWHPR21MB0144.namprd21.prod.outlook.com> <CY4PR21MB01332141C3563ABBA240C566B6F20@CY4PR21MB0133.namprd21.prod.outlook.com> <CABcZeBNeTT79nd+d7h-KFPpFYxpr5wt1KgwPY=M0_UQpCkKq1w@mail.gmail.com> <CY4PR21MB01337A5E81D8A8A1D7518D97B6F20@CY4PR21MB0133.namprd21.prod.outlook.com> <CAF8qwaBm6DRpS6eUthSMithsbUq-NMNhBND7RaDUFfzP0tAxnQ@mail.gmail.com> <CY4PR21MB0133A4FC7160DA1FABAA291BB6F20@CY4PR21MB0133.namprd21.prod.outlook.com> <1F436ED13A22A246A59CA374CBC543998B58BAD7@ORSMSX111.amr.corp.intel.com>
X-Mailer: Airmail (420)
MIME-Version: 1.0
Date: Fri, 09 Feb 2018 13:18:18 -0800
Message-ID: <CAN1APdcrE3zsAJwYLsQ31gAekXAfxL=L_xygv_2ehAEP=2n2EQ@mail.gmail.com>
Subject: RE: Packet number encryption
To: David Benjamin <davidben@chromium.org>, "Deval, Manasi" <manasi.deval@intel.com>, Praveen Balasubramanian <pravb@microsoft.com>
Cc: Eric Rescorla <ekr@rtfm.com>, huitema <huitema@huitema.net>, "quic@ietf.org" <quic@ietf.org>
Content-Type: multipart/alternative; boundary="f403045d914c4603dc0564ce1166"
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic/JvIUrwwnuearujwqTQzvCOedq-s>
X-BeenThere: quic@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <quic.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic>, <mailto:quic-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic/>
List-Post: <mailto:quic@ietf.org>
List-Help: <mailto:quic-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic>, <mailto:quic-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 09 Feb 2018 21:18:24 -0000

The obvious advantage of a clear text nonce is that it can be immediately
decrypted without extra processing and without modifying the packet
content, and it avoids latency from a separate packet number decryption
step.

However, having per path unique nonces per path jumping randomly in order
to gain an insignificant amount of anti-ossification is not every
appealing. Neither is the extra space required for having both packet
numbers and nonces, when they in the majority of cases is one and the same,
effectively. The random jumps are effectively a hidden encryption step
although cheaper than packet number encryption.

So, I propose having a nonce that counts from 0 per path per direction and
also having a unique connection identifier per path direction (asymmetric
CID). Lets call this a half-path context (CID+nonce counter). It could also
work shared path CID as today, but it is not as clean.

The nonce can at most count to 2^32-1 due to hard limits on AES-GCM and
possibly general TLS requirements.

This leaves the packet number encoding:

If we enumerate each half-path with a path ID PID as a simpler counter
starting at zero, we have a 1-1 mapping from PID to CID. The packet number
PN is then encoded as <PID * 2^32 + nonce counter>. The PN is used
explicitly and implicitly in ACK frames but is never carried directly on
the wire.

During path migration packet numbers in the same ACK frame may have large
predictable jumps, but the ACK frame already competently deals with this,
and the jumps are limited to the number of concurrently active paths.

The only loss is the ossification concern of having predictable per path
counters, but I think that is low price of admission. There are no
linkability concerns with this, and all the networking monitoring people
would be happy too.

Kind Regards,
Mikkel Fahnøe Jørgensen


On 9 February 2018 at 21.55.33, Deval, Manasi (manasi.deval@intel.com)
wrote:

Going back to Ian’s point here – Can you be explicit about the issue you
see in the packet number encryption?



Thanks,

Manasi





*From:* QUIC [mailto:quic-bounces@ietf.org] *On Behalf Of *Praveen
Balasubramanian
*Sent:* Friday, February 09, 2018 11:59 AM
*To:* David Benjamin <davidben@chromium.org>
*Cc:* Eric Rescorla <ekr@rtfm.com>; quic@ietf.org; huitema <
huitema@huitema.net>
*Subject:* RE: Packet number encryption



With VLE its minimal overhead per packet so you are not encrypting 4 bytes
more all the time even with 64 bit or 128 bit packet number . So its
decidedly better. Also fewer calls into TLS, but I suppose one could do
some refactoring of TLS API. Many CPUs yes but this is a general purpose
transport and could run on CPUs that don’t.



Didn’t ask for nonce to be variable length. Fixed length for connection
lifetime. Datacenters connections could use 64-bit nonce to avoid frequent
key rollover.



Effectively the plain text nonce is a sequence number since it increases
monotonically with small jumps as needed to avoid ossification. So no worse
off than gQUIC or current draft. No more complex than using the packet
number. Just the starting number is randomized. Also please notice that
this proposal does not preclude using encrypted packet number as the nonce
as proposed previously. Changing how the nonce works makes 0 impact on the
transport logic. An implementation can choose to implement any form of
non-repeating nonce without revving the RFC. This is the biggest advantage
of separation of concerns IMHO.



*From:* David Benjamin [mailto:davidben@chromium.org]
*Sent:* Friday, February 9, 2018 11:39 AM
*To:* Praveen Balasubramanian <pravb@microsoft.com>
*Cc:* Eric Rescorla <ekr@rtfm.com>; quic@ietf.org; huitema <
huitema@huitema.net>
*Subject:* Re: Packet number encryption



Your primary worry here was the extra block cipher operation, right? By
moving the packet number into the plaintext, this proposal increases the
length, which will cost that same one extra block cipher operation, no?



It is one block operation under the same key, rather than a different key
so I suppose there are minuscule cache footprint wins (one symmetric key is
16 or 32 bytes). But the cost is per-packet (!) bandwidth and complexity. I
do not see how this could be worth it. Note that, for AES, many CPUs have
dedicated instructions for it already.



> Clear separation of concerns results if we don’t overload the packet
number as the nonce. Connection migration and multi-path are optional
features and we pay no extra compute cost for most connections that are not
impacted by unlnkability. Nonce field becomes optional for crypto that
doesn’t need it and can grow to larger size as needed for bulk transfers to
prevent frequent key rollovers (say in datacenter scenarios).



You're not going to find AEADs that don't require a nonce. Encryption must
not produce the same ciphertext twice for the same plaintext, so you need
some input to diversify them. That input is the nonce. Nonces also are not
variable-length, so you don't get to arbitrarily grow them. (AES-GCM per
spec is variable length, but that's a spec bug. If you size it above 96
bits, it's as if you randomized it and your nonce space crashes per
birthday.)



It is also harmful to separate the two concerns. When you are building a
transport, derive the nonce from a sequence number. TLS 1.2 AES-GCM
separated them, which was a mistake. It's less efficient (the world wasted
quite a lot of bandwidth due to this), and more error-prone. There was
nothing stopping implementations from sending the same nonce or generating
nonces randomly (the AEADs we use don't have large enough nonces for that),
and indeed some did just that. If you use some sort of sequence number, you
can lean on existing work both to filter out the obvious implementation
mistakes and to avoid sending unnecessary data.



On Fri, Feb 9, 2018 at 12:38 PM Praveen Balasubramanian <pravb@microsoft.com>
wrote:

Let me try to summarize the proposal again:



   1. Packet number is in the encrypted portion of the header and is no
   longer used as the nonce. It is encoded as a variable length number. Always
   starts at 0.


   1. No ossification of PN
      2. No linkability using PN
      3. Allows for growth beyond 64 bits if needed in future


   1. The nonce is in the clear in plaintext header. It is generated *per
   path* as a secure random number. Call this the “starting value”. Both
   sides MUST initialize the “starting value” nonce *per path*. Within a
   path it grows monotonically (to avoid repeats just like PN today) and can
   include short random jumps periodically so that middleboxes cannot assume
   anything about the field. Since nonce has nothing to do with PN the jumps
   don’t add any complexity to transport logic. Jumps are for greasing and
   preventing ossification. When the nonce rolls over and reaches close to the
   “starting value”, key rollover must happen. At high data rates the nonce
   field can be 64-bits to prevent frequent key rollover. For crypto that
   doesn’t need nonces, the field can be omitted.


   1. No ossification because there is no pre-determined sequence to the
      nonce.
      2. In gQUIC and the RFC as defined the nonce is a simple sequence
      that increments by one, so this is no worse off in terms of
security. It is
      non-repeating.
      3. No linkability because different paths start at a completely
      different random number. If repeating is a concern then
different paths use
      different keys. Carries forward to not just connection migration but
      mutli-path.
      4. Supports key rollover just like gQUIC and currently defined draft
      RFC.
      5. Allows for omitting the nonce when we use crypto that doesn’t need
      it.
      6. Allows for larger nonces for high data rates.
      7. It doesn’t preclude any other type of non-repeating nonces without
      having to modify the RFC! So implementations that want to use
cryptographic
      nonces can still do so.



The downsides:

   1. Even with variable length encoding the extra PN field is more space
   used per packet when a nonce is required. I think we can do with 2 bytes in
   version 1.
   2. It’s not perfect unlinkabiltiy but I have yet to see any solution
   that can provide this. A simple time based analysis using machine learning
   will allow flow correlation especially for connection migration. The IP
   addresses in the clear allow for a high degree of correlation. There is
   also the application sending pattern and other signals that could be used.



*From:* Eric Rescorla [mailto:ekr@rtfm.com]
*Sent:* Friday, February 9, 2018 5:52 AM
*To:* Praveen Balasubramanian <pravb@microsoft.com>
*Cc:* huitema <huitema@huitema.net>; quic@ietf.org


*Subject:* Re: Packet number encryption







On Thu, Feb 8, 2018 at 9:40 PM, Praveen Balasubramanian <pravb@microsoft.com>
wrote:

Actually taking a step back what if we don’t we overloaded packet number as
the nonce?



Can we:

   1. Put packet number as a separate variable length field in the
   encrypted portion of the header. This allows for growth beyond 64 bits in
   future and completely avoids ossification. For short lived flows variable
   length encoding leads to minimal space overhead.
   2. Put a separate plaintext nonce which starts out as a secure random
   number and monotonically increases as short random jumps (every packet or
   every few packets) and could then rollover. This will prevent linkability
   and scales to multi-path as well. No major compute overhead. We can also
   make the nonce optional for crypto algorithms that do not need a nonce
   saving more space.



I'm not sure how to do #2 safely and efficiently. The primary concern is
that short random jumps don't actually prevent linkability because the high
order bits don't change and long random jumps are effectively randomly
sampling out of the nonce space, and you start to run into birthday
problems. Additionally, the cheapest PRNGs are basically ciphers in counter
mode, so at best you're going to get a small amount of overhead reduction
by getting multiple jump computations out of a single block, though if you
use 96-bit jumps, you only get 25% savings...



-Ekr







Some MSB of the nonce could be used for signaling reorder to the network if
needed. I don’t have the historical context for overloading of PN as the
nonce so pardon me if un-overloading option was discussed and ruled out
before.



*From:* QUIC [mailto:quic-bounces@ietf.org] *On Behalf Of *Praveen
Balasubramanian
*Sent:* Thursday, February 8, 2018 5:51 PM
*To:* huitema <huitema@huitema.net>; quic@ietf.org
*Subject:* RE: Packet number encryption



>> and using separate packet sequences for each path

This alone prevents linkability right?



>> The packet number on each path will start at 1 (or maybe 0 ;-).

Is supporting multiple paths at the same time a goal? If yes, then yes all
paths will need to have separate tracking and ACK state and congestion
control etc. I thought this is not part of V1 RFC. If its just one
additional path for connection migration scenario then all you need is a
(random) jump to a offset in packet number space for the new path so that
the few packets in the old path can continue for a little bit. This works
with just one ACK space so no implementation complexity.



>> 2) Or, leaving the packet number in the clear but using different
encryption contexts for each path, and using separate packet sequences for
each path.
In addition if the value in the clear was obfuscated with an XOR transform
it will help prevent ossification. The obfuscation is not meant to guard
against later analysis that reveals the packet numbers - why do we care
about that. It is meant to grease the space and not make the numbers serial
so middleboxes cannot assume ordering etc.



All said if I am alone in being concerned about the perf hit then I’d say
go on with option 1.



*From:* QUIC [mailto:quic-bounces@ietf.org <quic-bounces@ietf.org>] *On
Behalf Of *Christian Huitema
*Sent:* Thursday, February 8, 2018 3:54 PM
*To:* quic@ietf.org
*Subject:* Re: Packet number encryption



On 2/8/2018 1:13 PM, Mike Bishop wrote:

#2 won’t work.  The packet number is an input to the AEAD nonce, so you
have to get to the packet number before you can decrypt the payload.  It
can’t be based on anything internal to the encrypted packet.



In Martin’s proposal, it’s using a combination of the encrypted payload
(which requires nothing to access) and some stored state on each endpoint,
which requires only the Connection ID to look up.  You want the thing you
XOR by to be constantly changing, or it becomes easier to look at sequences
of obfuscated packet numbers and start drawing inferences about what the
XOR value is.  If overhead is the primary concern, I think there are a
couple approaches that might allow you to precompute values and amortize
the cost of doing the encryption step.  (At the cost of keeping the table
of precomputed values, of course.)



I still think Jana’s pushing in the right direction here:  Let’s agree on
goals, and then see if we can craft a design that meets those goals.  I
hear you saying that low overhead is a goal, which I think we can all agree
on.  I also think I hear you saying that 1-1.5% overhead is too high, but
it sounds like there’s less agreement on that.  You also raise an
interesting point that some clients will care less about linkability
because they will never intentionally migrate.


I think Victor said it best, "Obfuscation is just encryption done poorly."
Either we encrypt, or we don't. But there is no such thing as an
obfuscation middle-ground. Obfuscation would just be a speed bump, easily
broken. It won't provide privacy, and it won't prevent linkability.

As far as I am concerned, there are only two designs that prevent
linkability:

1) Martin's PR, in which the packet number is encrypted using sensible
crypto;

2) Or, leaving the packet number in the clear but using different
encryption contexts for each path, and using separate packet sequences for
each path.

The second option requires more computation when explicitly setting up a
new path. The connection ID would be used as part of the "salt" when
deriving connection contexts. The packet number on each path will start at
1 (or maybe 0 ;-). This requires maintaining separate SACK dashboards for
each path/Connection-ID, and constraining ACK to be per/path, or
alternatively adding a PATH-ACK frame that indicates the path for which
packets are acked.

The pros and cons of the two options are easy to get:

1) Option 2 does not require the cost of encrypting every packet, thus per
packet processing will be maybe 1% faster than option 1.

2) Option 2 requires computing encryption contexts for each path, which is
more complex than option 1, but the cost will be amortized over the
duration of the path.

3) Option 2 requires more complex data structures and ACK management, thus
increasing the chances that something goes wrong.

4) Option 2 does nothing against packet number ossification. The packet
number effectively becomes part of the invariants.

In short, the only advantage of option 2 is to avoid a single symmetric
encryption operation per packet, while making the code significantly more
complex, and at the cost of not protecting against PN ossification. The way
I see that, there is hardly any debate.

-- Christian Huitema