Subject: Privacy for connection IDs

From: Eric Rescorla <[email-masked]>
Date: Wed, 7 Jun 2017 09:45:04 +0200

[Also filed as https://github.com/quicwg/base-drafts/issues/598]

I and some others have been looking at how to protect the connection
ID from correlation between any two packets. The basic threat model
here is that it's possible to have unknown network transitions and so
if you just have the client initiate non-linkage events, then you
might have unknown linkage. Thus it should be, to the extent
practical, impossible to link any two packets. We can -- and I'm sure
will -- debate whether this is the right threat model, but the topic
of this email is just techniques.

There are two main sources of potential inter-packet linkage:

- The conn_id (which is the same)
- The packet number (which is sequential)

The current design, which allows you to occasionally change the
conn_id and then has a random PN increment, doesn't scale well to this
scenario.

I'm aware of two primary overall designs here, either of which will
work but neither of which is a complete no-brainer.

1. Omit the connection ID and then directly encrypt the packet number
   with a per-connection key. This basically forfeits the automatic
   connection mobility feature that the conn_id provides, because the
   server/LB needs to use the 5-tuple to recover the key.

2. Have the server provide the client with a pool of connection
   tokens, each of which is actually a wrapped version of the
   (conn_id, PN) pair. The client uses one token per packet, and the
   server/LB then unwraps the pair upon packet receipt.  In order for
   this to work, the server has to periodically replenish the pool,
   though it's not a disaster if the client runs out, because we can
   probably invent some way to reuse a token with a PN delta, though
   at some privacy cost.

Neither of these designs is 100% ideal. The first isn't at all
consistent with automatic mobility or recovering from NAT rebinding,
which was the motivation for connection ID in the first place
(basically, you have no connection ID). It also may come at some
additional bandwidth cost because the PN is used to compute the
per-packet nonce, but at absolute worst it's 16 extra bytes per
packet.

The second doesn't require giving up mobility/rebinding resistance,
but comes at some additional costs, specifically (1) some protocol
complexity (2) bandwidth overhead because you need to send the tokens
in the reverse direction [best estimate is 16-24 overall additional
bytes on the wire in both direction] (3) the LB will have to do some
crypto to recover the connection ID (most likely one AES operation).

We have detailed designs for both of these, though it's possible they
can be optimized further. Happy to go into these, but I think it's
more useful to discuss this at a high level rather than going into
the detailed mechanisms at this time.

-Ekr