Subject: Re: [TLS] ESNIKeys over complex

From: Ilari Liusvaara <[email-masked]>
Date: Sat, 8 Dec 2018 18:38:30 +0200

On Tue, Nov 20, 2018 at 09:45:51PM +0000, Stephen Farrell wrote:
> 
> I'm fine that such changes don't get done for a while (so
> I or my student get time to try make stuff work:-) and
> it might in any case take a while to figure out how to
> handle the multi-CDN use-case discussed in Bangkok which
> would I guess also affect this structure some, but I wanted
> to send this to the list while it's fresh for me.

For even nastier combination, combine zone apex (so no CNAMEs)
and multi-CDN. Due to atomicity constraints (the unit of atomicity is
the RRset), plain includes will not work, even if the site is only
using one CDN at a time.

A nasty hack would be to include valid prefixes (with usual more-
specific rules for matching) in include directives. The client could
then match the includes with addresses they belong to.

In the proposed include syntax, there is an issue that the base64
encoding prevents recursive server from returning the referenced
ESNI records in one query. The include would have to be specified as
DNS wire-format name field for DNS recursors to be able to perform such
performance optimization.

For CNAME multi-CDNs, it should be enough to ensure that the ESNI
and address records share owner name and class, as this should
suffice to ensure that address and ESNI always come from the same CDN.

The problems with using CDNs with zone apex are well-known, and there
are attempts at solving those. Any such solution if practical would
also solve the "address CDN" issue for ESNI.

The "recovery" issue seems to be Capital-H Hard. In TLS 1.3, a
really nasty hack would be to restart the handshake after server
finished without resetting encryption (since encryption is not reset,
the client_hello and server_hello would be encrypted, with keys
known by the client and fronting server). However, I do not think that
would work in DTLS 1.3 (as it assumes that keys can not change during
an epoch, and there is space for only one handshake epoch). And even
that hack is likely too much. And of course fallbacks would be horrible
idea here.

Then it seems to me that other ways to do recovery are even worse,
as they would dink even more with the internals of TLS 1.3, which is
not something to do lightly (the "extreme care" remark from RFC8446
definitely appiles here). This seems to apply even if somebody invents
a snappy shortcut using some more exotic cryptographic primitive.

In summary, I do not think "recovery" will work. But this is not the
first DNS record one can take down a site for a long time. But perhaps
the first where one can do that on mass scale...

While thinking about the previous, I ran into some issues with the
split mode. Firstly, if the fronting server does not encrypt the
client_hello when transmitting it to backend server, passive attack
can match incoming connections with backend servers. This reduces
anonymity set to a single backend server (a lot smaller set).

And secondly, even if server encrypts the client_hello, but does not
use a tunnel to backend, if server does not have client hello replay
filtering (and such filtering is hard on typical fronting servers),
replay attacks and some very simple traffic analysis can discover the
backend server (again reducing the anonymity set by a lot).

This means that the fronting server should have an encrypted tunnel
with the backend server (and there is likely double encryption).

Then there is a future compatiblity issue: If one has a PQ IND-CPA
KEM with sufficiently small size (over a dozen of those in NISTPQC),
one can extend base TLS 1.3 to post-quantum in straightforward manner
(client generates a public key, sticks it to key_share, the server
encapsulates a random session key to that public key, sticks the
ciphertext into its key_share and the client decrypts the session key
with the private key. PFS is possible if key generation is cheap enough
for client to do that per-connection). However, such extension is not
compatible with present ESNI design. 

The problem is that key_share in client_hello carries a public key, and
not a ciphertext. And besides, one can not encrypt messages with
IND-CPA KEM (one needs at least IND-CCA KEM). But even if the key
exchange algorithm was IND-CCA, it still would not help because of the
first problem. There are some ways to both perform key agreement and
encrypt using the same PQ key, but all of them are way too slow and
have way too little analysis.

Of course, there does not seem to be straightforware way to fix this:
Decoupling the keys would require some way to ensure one can not copy-
paste ESNI between client hellos (nasty hack that could work would be
to hash client random and client key_share and include that into key
derivation for the ESNI).

Except the above might run into trouble in PSK mode. And reading the
editor's draft: What prevents from using pure-PSK "resumption" with
ESNI (that would be pretty stupid)? As the binding between ESNI and
connection does not apply in straightforward way in that case.

-Ilari

---

From: David Fifield <[email-masked]>
Date: Sat, 8 Dec 2018 11:42:56 -0700

> with the backend server (and there is likely double encryption).

I see--you're thinking of an observer who can see "both sides" of a
connection: the link between the Client and the Client-Facing Server,
and the link between the Client-Facing Server and the Backend Server.
I agree: such an observer could, through timing analysis, deanonymize
client connections (i.e., tell which Backend Server the Client is
accessing, as if it were accessing directly and not through the
Client-Facing Server). I suppose to really defend against a global
observer, you would need some kind of mixnet.

It looks like a little bug in the draft. I've checked just now and I
don't see that it says exactly *where* the observer is. I had assumed
that the observer only sees the Client–Server link (in Shared Mode) or
the link between Client and Client-Facing Server (in Split Mode).

I don't understand your point about replay and encrypting the Client
Hello. An observer doesn't need to see the contents of the Client Hello
to identify a Backend Server--the destination IP address is enough. I
don't see what specific attack you have in mind using replay, but it
seems to me that even an encrypted tunnel is insufficient. Unless the
encrypted tunnel additionally obfuscates packet sizes and timing, an
observer can correlate e.g. burst sizes and match incoming flows to
outgoing flows, in the manner of website fingerprinting.

---

From: Ilari Liusvaara <[email-masked]>
Date: Sat, 8 Dec 2018 21:03:45 +0200

> observer, you would need some kind of mixnet.

If the client hello is not encrypted to backend server, one does not
need timing analysis if one is on both sides: Things like key share
and client random allow much more robust correlation.

> the link between Client and Client-Facing Server (in Split Mode).

I think there have actually been real world attacks where link from
client to CDN is encrypted, but link from CDN to backend is not,
and attacker attacked the CDN to backend link.

And those were active attacks, the attacks I am talking about are
passive-only (not as exciting, but more dangerous).

>From the destination IP address, one can only tell that _some_ client
is accessing the backend. One presumably wants to know _which_ client
is doing so (e.g. correlating the IP address of the client). Because
otherwise the client might actually be someone from juristiction that
is not friendly to you.

And yes, even with encrypted tunnel, traffic analysis can get
great amounts of data. It is just that if client hellos are replayable
and there is no tunnel, it is much easier for the attacker to
correlate connections on both sides (since attacker can then observe
new connections versus just some data exchange).

-Ilari