[TLS] Cleaning up 0-RTT Signaling (ciphersuites, replays, PSK context)

Karthik Bhargavan <karthikeyan.bhargavan@inria.fr> Fri, 25 March 2016 09:29 UTC

Return-Path: <Karthikeyan.Bhargavan@inria.fr>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 0AAAF12DC02 for <tls@ietfa.amsl.com>; Fri, 25 Mar 2016 02:29:12 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.91
X-Spam-Level:
X-Spam-Status: No, score=-6.91 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, T_RP_MATCHES_RCVD=-0.01] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dPc-4EJjTBE3 for <tls@ietfa.amsl.com>; Fri, 25 Mar 2016 02:29:09 -0700 (PDT)
Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) (using TLSv1.2 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 74ED912D6AB for <tls@ietf.org>; Fri, 25 Mar 2016 02:29:09 -0700 (PDT)
X-IronPort-AV: E=Sophos;i="5.24,390,1454972400"; d="scan'208";a="170776388"
Received: from unknown (HELO [128.93.82.51]) ([128.93.82.51]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 25 Mar 2016 10:29:07 +0100
From: Karthik Bhargavan <karthikeyan.bhargavan@inria.fr>
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Message-Id: <BC748097-6833-4BEB-9282-AF278B00FB96@inria.fr>
Date: Fri, 25 Mar 2016 10:29:06 +0100
To: tls@ietf.org
Mime-Version: 1.0 (Mac OS X Mail 9.2 \(3112\))
X-Mailer: Apple Mail (2.3112)
Archived-At: <http://mailarchive.ietf.org/arch/msg/tls/HVGUmi2UoAbaXq649EDxjQQ71cs>
Subject: [TLS] Cleaning up 0-RTT Signaling (ciphersuites, replays, PSK context)
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.17
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: Fri, 25 Mar 2016 09:29:12 -0000

We currently allow 0-RTT with Semi-static DH, with PSK resumption, and with pure PSK.
Whether or not we keep all of these, it would be good to clean up the protocol design 
so that both the client and server have a uniform way of signaling their preferences.

After implementing and analyzing TLS 1.3, here are a few suggestions for discussion.

1) Early Data Extension

The current early-data extension is too DH-specific.
When using PSK, we now have to look at both early_data and pre_shared extensions.
I suggest reusing the same extension for both, with the following interpretation:

	struct {
          select (Role) {
              case client:
                  opaque id<1..2^16-1>;
                  opaque context<0..255>;
                  CipherSuite cipher_suite;
                  Extension extensions<0..2^16-1>;

              case server:
                 struct {};
          	}
	} EarlyDataIndication;


In the semi-static DH case:
- id is the configuration id
- context is the hash of the ServerConfiguration + Server Certificate + CertificateRequest

In the PSK resumption case:
- id is the session ticket
- context is a *public* value unique to the derived session. For example, it could be defined as the session hash of the original handshake,
  or it could be derived by the client as HKDF(RMS, “early data context”)

In the pure PSK case
- id is the PSK identifier
- context is unique to the PSK and its allowed use.
  For example, it can be generated (out-of-band) as HKDF(PSK, “early data context”)

2) New Session Ticket

The NewSessionTicket message needs to indicate whether the server will accept 0-RTT,
and what ciphersuites it is willing to accept (e.g. pure PSK resumption vs only PSK-ECDHE).

I suggest the following modification to this message:
	struct {
         uint32 ticket_lifetime;
         opaque ticket<0..2^16-1>;
	 CipherSuite cipher_suites<2..2^16-2>;
	 EarlyDataType early_data_type
     	} NewSessionTicket;

        enum {
	  no_early_data_allowed(0),
          replayable_early_data_allowed (1),
          all_early_data_allowed(2),
          (65535)
       } EarlyDataType;

The interpretation of the early_data_type field is that the server is either:
(a) unwilling to accept 0-RTT (no_early_data_allowed), 
(b) willing to accept 0-RTT, but it has no replay cache (replayable_early_data_allowed),
(c) willing to accept 0-RTT and has a replay cache that it uses to prevent replay (all_early_data_allowed)

The client’s response to this ticket message should be to store it in its
session along with the “context” (session hash or derived from RMS),
the allowed cipher suites, and the early_data_indication.

When resuming with this ticket:
- the client should not send any 0-RTT data if no_early_data_allowed
- the client should only send replayable data if replayable_early_data_allowed (e.g. GET requests)
- the client can send any 0-RTT data if all_early_data_allowed, trusting the server to do the right thing.


A note on replay
----------------------

There has been much discussion on 0-RTT replay and here’s a quick summary of my understanding.
We already knew that an active attacker, or a lossy network, or an overzealous web browser could
and would cause 0-RTT (and even 1-RTT) data to be replayed to the server. This can already happen
in TLS 1.2, in QUIC, and so we accepted it as a given in TLS 1.3.

The new concerns on the mailing list (and in my TRON talk which was based on a ProVerif model) 
are that unlike TLS 1.2:
(a) even a passive attacker could replay 0-RTT data, long after the client has gone away,
(b) replaying authenticated 0-RTT data can be more damaging (whether authenticated with client cert or with a cookie), and
(c) by replaying 0-RTT data, the attacker can obtain encrypted 0.5-RTT data which opens up new attack vectors.

As a result of these new concerns, I would say that TLS 1.3 should recommend that all servers SHOULD
implement a replay cache, and those that cannot should clearly signal this to the client, so that the client
can adjust its 0-RTT use case and its expectations accordingly.

A note on authenticating the 0-RTT “context”
----------------------------------------------------------

When trying to figure out how to authenticate 0-RTT DH mode in an earlier draft, we came upon the
design of signing the Handshake Context that consists of the ClientHello + additional information from the previous handshake.
This construction prevents 0-RTT authentication from unknown key share attacks.

Even if we eliminate client certificate authentication from 0-RTT, this notion of “context" is still useful for two reasons:
(a) the application may use TokenBinding or some such protocol to authenticate 0-RTT data, and we need to understand what “channel binding” to provide for this case,
(b) in PSK resumption mode, since the handshake log does not contain much information that is specific to the previous connection, it would be more robust to add an explicit context.

If we accept the definition of “context” in the EarlyDataIndication extension, then we can use the hash of the ClientHello uniformly in all
0-RTT modes for deriving keys, and for deriving a channel binding for the application. Furthermore, we can safely introduce a PSK_ECDHE
mode where the server sends its Certificate and CertificateVerify and its signature is correctly bound to the PSK (via the “context” field).

Best regards,
Karthik