[TLS] Encrypted SNI

Eric Rescorla <ekr@rtfm.com> Sat, 05 December 2015 18:32 UTC

Return-Path: <ekr@rtfm.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com []) by ietfa.amsl.com (Postfix) with ESMTP id BF4811B2BF4 for <tls@ietfa.amsl.com>; Sat, 5 Dec 2015 10:32:53 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.277
X-Spam-Status: No, score=-1.277 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001] autolearn=no
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id LAhHCbUwKgYB for <tls@ietfa.amsl.com>; Sat, 5 Dec 2015 10:32:51 -0800 (PST)
Received: from mail-yk0-x231.google.com (mail-yk0-x231.google.com [IPv6:2607:f8b0:4002:c07::231]) (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 5C0441B2BF3 for <tls@ietf.org>; Sat, 5 Dec 2015 10:32:51 -0800 (PST)
Received: by ykdv3 with SMTP id v3so156409796ykd.0 for <tls@ietf.org>; Sat, 05 Dec 2015 10:32:50 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rtfm-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to:content-type; bh=28bGt+QQm4g2Gsp7RpygEUzLT2hfGcihVOXs1mXGjLw=; b=dX2oM6Vgeyiv8guDo53Tlc6YPY2kI3CgGCDD6mKPLyM7j3XVXBQsopa/0/kfOr4GvY K8559eAqjxbL2fn/O9zeU15hVLCuTR1FEPlgAm+ea/XPaI2azwP8aanJIdXxnG7O8JXg 2E5FYI36Dz/spnq1zZfH73pGNfvhBgtImD4gyVUYE9D4WEdFcJ1OkH9eljaBqMcu5Cwt frYNo4qhygeab/VncaJJiqkreemCLMlG8zbGkQMtWm+j/tqJB0IbbRH+kkvg6vDFWtj3 G8QDXKVsXoM+Shdfy2s0m6xgJo0H7OqR47VYDTEmJsj7UuN+jNk6GGljUvvsWYpt5Lv4 B9sw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to :content-type; bh=28bGt+QQm4g2Gsp7RpygEUzLT2hfGcihVOXs1mXGjLw=; b=QuuGysz2w4sUWxoA2LA2rzje5zmpei5qBOEaYlMi6cO/JguxljLSzUAwKKocs89/jN 2F45DNKtrUOmEP3DKONNv09GLQxtXbukp+Qc3grLpmiGe2876n3V/s6I/kBv/FH7uRmU 37KtVKpbdncDYh4cUPeUT6uagj8DP4XBY0uO9G9aUBIL5hbJSIK7P0dyjoLYccroJkHO m01GZHyEXO8kyhQO0jgiLnNCkh/5az47Ifl7ST6VTQyGbYz6PX54Xf2nCLRN7sNmB457 y216iUk//V35Dj2P5NwobJeohkHGADG/wW/82oL4JE0hAbvfiPY+z74Q4NEnfGnxGC+A T/6Q==
X-Gm-Message-State: ALoCoQlKE0WQyS5KWlpfhsdxPm1HV6+PcmOVFRZDrp5mD9m6brQ59W4rESVzNSal36518XdFzRgT
X-Received: by with SMTP id u81mr15635258ywu.129.1449340370699; Sat, 05 Dec 2015 10:32:50 -0800 (PST)
MIME-Version: 1.0
Received: by with HTTP; Sat, 5 Dec 2015 10:32:11 -0800 (PST)
From: Eric Rescorla <ekr@rtfm.com>
Date: Sat, 05 Dec 2015 10:32:11 -0800
Message-ID: <CABcZeBPFAp4hD3ykY9pAA4=ELsAkNoa2yDhaoiSP917v5XgAiw@mail.gmail.com>
To: "tls@ietf.org" <tls@ietf.org>
Content-Type: multipart/alternative; boundary="001a11409380f4797505262ad9b9"
Archived-At: <http://mailarchive.ietf.org/arch/msg/tls/tXvdcqnogZgqmdfCugrV8M90Ftw>
Subject: [TLS] Encrypted SNI
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sat, 05 Dec 2015 18:32:53 -0000

Subject: SNI Encryption Part XLVIII


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.

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

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

                             + KeyShare
                             + SNI = hidden
                             <Finished>        ---->
                                                        + KeyShare
                     <-------------------------------   {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

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).


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