Subject: [quicwg/base-drafts] Consider encrypting the packet number (#231)

From: ekr <[email-masked]>
Date: Tue, 24 Jan 2017 23:47:48 -0800

Quoting myself from the mailing list:

TL;DR. Encrypt the packet number with ECB or something like it. This
is probably a bad idea but I wanted to write it down.

I had an idea last night about encrypting the packet number. Here's
a diagram of a QUIC regular packet:

 ```  +-+-+-+-+-+-+-+-+
   |   Flags (8)   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                     [Connection ID (64)]                      +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        [Version (32)]                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
   |                  Packet Number (8/16/32/48)                 ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    {Encrypted Payload (*)}                  ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   ```
The insight here is that the reason that the packet number is outside
of the encryption is because it is used as the nonce for the AEAD
function. However, there are encryption algorithms (which we usually
avoid for various reasons) which do not need a nonce. Specifically,
what we could do is derive two keys:

  K_h: header encryption
  K_p: packet encryption

So you get:

 ```
  +-+-+-+-+-+-+-+-+
   |   Flags (8)   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                     [Connection ID (64)]                      +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        [Version (32)]                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ^ 
   |                 {Packet Number (8/16/32/48)}                ... | encrypted with K_h
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ v
   |                    {Encrypted Payload (*)}                  ... ^
   |                                                                 | encrypted with K_p
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ v
```

This of course leaves the question of which crypto mode you use to encrypt
the packet number. The natural choice is ECB, but that only works with
data values the same size as the cipher block, which for AES is much
bigger than the packet number (128 bits). So, that's waste, though you
might of course add stuff to the block if we had other headers.
We could use 3DES (which has a 64-bit block) or FFX (which can be used
with any block size, but at some additional computational cost).

Two pre-emptive responses to common questions:

1. Yes, ECB and FFX are not generally as good as AEAD algorithms, in
particular because they don't have integrity and they reveal patterns
in the plaintext. However, this is data which would (a) otherwise be in the
clear and (b) is folded into the ordinary AEAD integrity check.

2. As long as we correctly generate K_h and K_p independently using
a KDF, then any weaknesses in K_h don't implicate K_p.

Again, this probably isn't worth doing with the current amount of
stuff in the headers, but I wanted to write it down so that people.

-- 
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/issues/231