Subject: [TLS] Encrypted SNI

From: Eric Rescorla <[email-masked]>
Date: Sat, 5 Dec 2015 10:32:11 -0800

Subject: SNI Encryption Part XLVIII

Folks,

TL;DR.
This message describes a technique for doing SNI encryption that just
requires (re)adding EncryptedExtensions to the client's first flight [0]
defining an extension that indicates "tunnelled TLS" and (maybe) a new
TLS content type. We would only tunnel the first flight and everything
else would be handed off to the hidden service. This seems like the
minimal change to enable Encrypted SNI while retaining our existing
analytical frame for the rest of TLS.

DETAILS
During the discussion of SNI Encryption in Yokohama, Deb Cooley
argued that rather than messing with TLS to allow SNI encryption,
we should just tunnel TLS in TLS. A number of people objected
to this on the grounds of the performance cost for the gateway
because it has to encrypt and decrypt everything.

After the meeting, Martin Thomson suggested a modification to the
tunnelling proposal that removes this cost. The key observation is
that if we think of the 0-RTT flight as a separate message attached to
the handshake, then we can tunnel a second first flight in it. Here's
the idea:

 Client                       Gateway                      Hidden

 ClientHello#1
  + KeyShare
  + EarlyDataIndication
  + SNI = gateway
 (Finished)
 (
   ClientHello#2
    + KeyShare
    + SNI = hidden
   <Finished>        //
 )
 (end_of_early_data alert)  ---->

                             ClientHello#2
                             + KeyShare
                             + SNI = hidden
                             <Finished>        ---->
                                                       ServerHello
                                                        + KeyShare
                                             {EncryptedExtensions}
                                            {ServerConfiguration*}
                                                    {Certificate*}
                                             {CertificateRequest*}
                                              {CertificateVerify*}
                     <-------------------------------   {Finished}
{Finished}           ------------------------------->

Key to brackets:

  () encrypted with Client->Gateway 0-RTT key (either handshake or data)
  <> encrypted with Client->Hidden 0-RTT key
  {} encrypted with Client->Hidden 1-RTT handshake

The way this works is that the Gateway decrypts the *data* in the
client's first flight, which is actually ClientHello#2 from the
client, containing the true SNI and then passes it on to the, Hidden
server. However, the Hidden server responds with its own ServerHello
which the Gateway just passes unchanged, because it's actually the
response to ClientHello#2 rather than to ClientHello#1. As long as
ClientHello#1 and ClientHello#2 are similar (e.g., differing only in
the client's actual share (though of course it must be in the same
group)), SNI, and maybe EarlyDataIndication), then an attacker should
not be able to distinguish these cases.

Notes on several obvious technical issues:

1. How does the Gateway distinguish this case from where the initial
   flight is actual application data? See below for some thoughts
   on this.

2. Can we make this work with 0-RTT data from the client to the Hidden
   server? I believe the answer here is "yes", because the server's
   EarlyDataIndication does not carry the configuration_id. I just
   didn't show it in the diagram because it was already getting
   complicated.

3. What happens if the Gateway server doesn't gateway, e.g., because
   it has forgotten the ServerConfiguration? In that case, the
   client gets a handshake with the Gateway, which it will have
   to determine via trial decryption. At this point the Gateway
   supplies a ServerConfiguration and the client can reconnect
   as above.

4. What happens if the client does 0-RTT inside 0-RTT (as in #2 above)
   and the Hidden server doesn't recognize the ServerConfiguration in
   ClientHello#2? In this case, the client gets a 0-RTT rejection and
   it needs to do trial decryption to know whether the rejection was
   from the Gateway or the Hidden server.

The big advantage of this design compared to the designs we were
discussing in Yokohama is that it requires effectively no changes
to TLS. The only thing you need is a way to signal to the Gateway
server that the encrypted application data is actually a ClientHello
which is intended for the hidden service. The two most obvious
designs are:

- Have an EncryptedExtension which indicates that the inner
  data is tunnelled.
- Have a "tunnelled" TLS content type.

In the interest of explicit signaling I think EncryptedExtensions is
best but we either need to require that all TLS 1.3 implementations
handle that extension or *also* have a new content type, because
otherwise it might be possible for an attacker to craft an inner
ClientHello which was processable in part as an upper-level protocol
message, which could be bad.

The major disadvantage of this overall design strategy (however it's
signaled) is that it's somewhat harder to implement in the co-tenanted
cases than the most trivial "RealSNI" scheme. That means that it's
somewhat less likely that servers will implement it "by default" and
more likely that they will have to take explicit effort to allow
Encrypted SNI. Conversely, however, these modes (aside from a server
with a single wildcard or multi-SAN cert) involve more changes to TLS
to deal with issues like "what is the server cert that is digested
into the keys", and that requires more analysis, so there is an
advantage to deferring that. If we have EncryptedExtensions in the
client's first flight it would be possible to add RealSNI later
if/when we had clearer analysis for that case.

Important note: this whole discussion punts the question of how
a client knows that it can do any of this stuff. My assumption
here is that the client learns it from the Hidden server in some
unprotected connection or via some side channel (e.g., DNS).

-Ekr

[0] We need to do this anyway because we need to have stuff like
"this is the ALPN for this first flight".

---

From: Watson Ladd <[email-masked]>
Date: Sat, 5 Dec 2015 14:15:07 -0500

>    from the Gateway or the Hidden server.

I've got another question: how does the client know that the gateway
is supposed to be the gateway? As it stands it seems an attacker can
MITM the Gateway, and recover all SNIs.

Sincerely,
Watson

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 5 Dec 2015 19:31:00 +0000

> MITM the Gateway, and recover all SNIs.

That's a whole lot different than passively reading all the SNIs,
if not this or similar, then we're sending the SNI in the clear...

That said, ekr's post includes:

DNS seems to make sense, because in any case the client will already
be asking for the IP address of the same said server via DNS.  It
may as well ask for the 0-RTT key.  If DNS is in the clear for the
IP address, then encrypting SNI is often (absent TOR and the like)
pointless, if DNS is protected then the key lookup is also protected.

-- 
	Viktor.

---

From: Dave Garrett <[email-masked]>
Date: Sat, 5 Dec 2015 15:53:52 -0500

> analytical frame for the rest of TLS.
[...snip...]

Neat. This design is modeled more similarly to what SNI is actually for and this generalized approach may be useful for other applications. Not that simple, but we knew that we weren't going to get that here.

This is actually more than just SNI encryption; every possible indicator in a server's first flight gets encrypted here. We can get encrypted ALPN through this too, which could be nice to have. It would give ideal protection against attempts to identify the intended server via ClientHello fingerprinting, in general. (still a finite amount of virtual hosts to guess from, but that's not fixable here)

Sounds like a good proposal to me. :)

Dave

---

From: "Salz, Rich" <[email-masked]>
Date: Sun, 6 Dec 2015 01:58:58 +0000

Can we embed an EncryptedExtension inside an existing EE?  That would let us do TOR purely within TLS, right?

You said “in the interest of explicit signaling” but I think you meant in the interest of avoiding that, right?

I still think the “inner/real SNI” is simpler, but will have to think about the two.

--
Senior Architect, Akamai Technologies
IM: [email-masked] Twitter: RichSalz

---

From: Tom Ritter <[email-masked]>
Date: Sat, 5 Dec 2015 21:06:52 -0600

> Subject: SNI Encryption Part XLVIII

A small concern that probably is "No, that can't happen", but I would
want to be sure that a normal (non-encrypted SNI) ClientHello would be
unable to be wrapped in a new ClientHello to a gateway by a MITM
(without being detected.)

Also, I'm a little confused about what the client is supposed to put
in the outer SNI (for the gateway). Is this blank? Some constant? Does
this change at all in the simple deployment situation when there is no
gateway involved, and everything sits on the same server?

-tom

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 5 Dec 2015 19:31:06 -0800

> (without being detected.)

That would certainly be consistent with the proposed design. Why is that
bad?

> in the outer SNI (for the gateway). Is this blank? Some constant?

Whatever SNI you would use to talk to the gateway ordinarily. Otherwise
you would have a distinguisher.

> Does

No.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 5 Dec 2015 19:38:54 -0800

On Sat, Dec 5, 2015 at 5:58 PM, Salz, Rich <[email-masked]> wrote:

> Can we embed an EncryptedExtension inside an existing EE?
>

I'm not sure I understand the design you're suggesting.

>   That would let us do TOR purely within TLS, right?
>

See above.

> the interest of avoiding that, right?

No, I don't think so. One option would be to simply send a new tunneled
application data
type without any explicit signaling and the other would be to have an
(encrypted) extension which indicated that that is what you are doing. I am
endorsing the latter..

---

From: Tom Ritter <[email-masked]>
Date: Sat, 5 Dec 2015 22:20:05 -0600

> That would certainly be consistent with the proposed design. Why is that

It doesn't seem safe that a MITM can actively change the way a
handshake occurs and is processed by the other side without being
detected. It's like asking for some sort of more complex attack. We
don't allow a MITM to change other parts of the handshake.

A trivial, though contrived, example could be a CDN that supports
eSNI. All requests it receives from... Turkmenistan[0] use eSNI. Seems
good? Actually the government blocks all client-originated eSNI
requests and re-wraps them so to the outside world it appears less
censored than it is. Could be done state-wide or (if god forbid we had
a fallback) to individual clients.

Something analogous is not allowing an attacker to inject a
HelloRetryRequest.We shouldn't allow that, either I think. I looked at
#104 - it seems like the current plan _is_ to restart the handshake
hash in the event of HelloRetryRequest but that a server cookie must
be replayed? (Theorizing the cookie is an HMAC containing the client
ip and some other things?) I think there's an attack on that if an
attacker can forge packets from a client. (HelloRetryRequest is not
signed by the server, right?)

Client supports SecureA, SecureB, and InsecureC. Server supports
SecureA, SecureB, and InsecureC. Client sends a ClientHello with
KeyShares for A & B. <Pause> Attacker forges a packet from the
client's IP with support for C and RandomD and KeyShares for RandomD.
Server replies with a HelloRetryRequest with a cookie for that client
IP. Attacker forges a HelloRetryRequest from the server, copying the
cookie, and saying "I only support InsecureC." <Unpause> The attacker
sends the forged HelloRetryRequest to the client. Client makes a
KeyShare for InsecureC and sends it along with the cookie, which the
server recognizes as being from it for the IP, and everything proceeds
using InsecureC undetectably.   I think.

> you would have a distinguisher.

But... what is that?  If I look up example.com (over my new private
DNS link) and get an IP back to a CDN (which I wouldn't even know)...
how would I know what the "normal gateway SNI" is?

-tom

[0] To use a real-world example of a heavily censored national internet.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 5 Dec 2015 20:31:20 -0800

> a fallback) to individual clients.

Fair enough. This seems easily solved by requiring the internal
ClentHello to enclose a digest of the external ClientHello in some
extension.

> be replayed?

No, that's not the current plan. See:
http://www.ietf.org/mail-archive/web/tls/current/msg18118.html

> (Theorizing the cookie is an HMAC containing the client

Well the client sends shares for A, B, and C (it is required to append
the new share to the list, not replace it) for exactly this reason. So, as
long
as the server would prefer A or B given A, B, and C, you don't end
up with C. However, as I said, we are not planning to restart the handshake
hash.

> how would I know what the "normal gateway SNI" is?

Well, this isn't what would happen. You would get a response in something
other than an A record that contained "here is the DNS name of the gateway".
That's the only thing that can work because you need to solicit the
ServerConfig
from the gateway in any case. I don't see how to make this work without
a channel richer than just an IP, since the client needs to know how to do
Encrypted SNI.

-Ekr

---

From: Dave Garrett <[email-masked]>
Date: Sun, 6 Dec 2015 02:42:51 -0500

> Can we embed an EncryptedExtension inside an existing EE?  That would let us do TOR purely within TLS, right?

If clients are allowed to send any encrypted extensions other than the tunneling extension (that contains the tunneled hello), then we would have to allow sending an EncryptedExtension through it, otherwise tunneled peers would have less capabilities than non-tunneled. I don't see anything in this design that would prohibit recursively doing this as many times as desired. (e.g. tunnel of a tunnel of a tunnel of a...) That does sound somewhat TOR-like, though obviously, lots more would be needed to actually do anything with that. If this can actually be done, it sounds very promising.

Dave

---

From: Jacob Appelbaum <[email-masked]>
Date: Sun, 6 Dec 2015 08:48:37 +0000

On 12/6/15, Dave Garrett <[email-masked]> wrote:
> If clients are allowed to send any encrypted extensions other than the
> tunneling extension (that contains the tunneled hello), then we would have
> to allow sending an EncryptedExtension through it, otherwise tunneled peers
> would have less capabilities than non-tunneled. I don't see anything in this
> design that would prohibit recursively doing this as many times as desired.
> (e.g. tunnel of a tunnel of a tunnel of a...) That does sound somewhat
> TOR-like, though obviously, lots more would be needed to actually do
> anything with that. If this can actually be done, it sounds very promising.
>

I had a similar thought.

There needs to be a way to blind each server that is two hops away to
make it work:

Alice connects to a server_0, the server routes to server_1, server_1
routes to server_2 and that passes the final TLS to Bob.

Alice's TLS message needs to be passed to server_1 without every
indicating in an encrypted fashion that server_2 is in the path. In
this analogy, server_0 is like the Tor guard, server_1 is the middle
node, and server_2 is the exit node.

There are some issues with such a design - which is why Tor's design
is to use TLS as an outer link layer and then internally to use 512
byte (or slightly larger) cells. I won't get into those here but I
find the general idea of tls within tls to be useful.

All the best,
Jacob

---

From: "Salz, Rich" <[email-masked]>
Date: Sun, 6 Dec 2015 14:46:07 +0000

> I'm not sure I understand the design you're suggesting.

Does the EncryptedExtensions contain the entire hello for the "next hop"?

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 6 Dec 2015 06:49:52 -0800

> Does the EncryptedExtensions contain the entire hello for the "next hop"?

No. It (at most) says "the stuff that is post-handshake is actually a
ClientHello for the next hop". I.e., it's literally TLS in TLS.

-Ekr