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

Karthik Bhargavan <karthikeyan.bhargavan@inria.fr> Fri, 25 March 2016 18:38 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 11CDB12D5AA for <tls@ietfa.amsl.com>; Fri, 25 Mar 2016 11:38:51 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.909
X-Spam-Level:
X-Spam-Status: No, score=-6.909 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, 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 fFzxbweM6q7g for <tls@ietfa.amsl.com>; Fri, 25 Mar 2016 11:38:48 -0700 (PDT)
Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) (using TLSv1.2 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 888A512D59E for <tls@ietf.org>; Fri, 25 Mar 2016 11:38:47 -0700 (PDT)
X-IronPort-AV: E=Sophos;i="5.24,392,1454972400"; d="scan'208,217";a="210260493"
Received: from 89-156-8-219.rev.numericable.fr (HELO [192.168.0.51]) ([89.156.8.219]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 25 Mar 2016 19:38:45 +0100
Content-Type: multipart/alternative; boundary="Apple-Mail=_B5E314A5-0F71-472F-B907-09FB7B60E6D6"
Mime-Version: 1.0 (Mac OS X Mail 9.2 \(3112\))
From: Karthik Bhargavan <karthikeyan.bhargavan@inria.fr>
In-Reply-To: <CABcZeBOP08V6obrN1vQkXkvFEXdux33mu_8zn=uyFo2OVim7Eg@mail.gmail.com>
Date: Fri, 25 Mar 2016 19:38:44 +0100
Message-Id: <68D617BC-BE11-4972-BF28-40829EE5AA9B@inria.fr>
References: <BC748097-6833-4BEB-9282-AF278B00FB96@inria.fr> <CABcZeBOP08V6obrN1vQkXkvFEXdux33mu_8zn=uyFo2OVim7Eg@mail.gmail.com>
To: Eric Rescorla <ekr@rtfm.com>
X-Mailer: Apple Mail (2.3112)
Archived-At: <http://mailarchive.ietf.org/arch/msg/tls/oGi59dIDg-jcSFub_NWugy8cH4I>
Cc: "tls@ietf.org" <tls@ietf.org>
Subject: Re: [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 18:38:51 -0000

Hi Eric,

Yes, I now agree with Ilari and you that we should have a separate pre_shared_key extension
in order to signal multiple PSKs. I wonder if we could still share the structure between
PSK and DH though, although that’s mainly an aesthetic choice.

> The second idea seems sensible, and I do like the idea of binding the
> session hash of the previous handshake into PSK-Resumption. One thing
> that seems unclear would be what the responsibilities of the server
> are with respect to the context. In the current draft, the client
> and server both digest it explicitly but it's not signalled, which
> has the disadvantage that you can't just run the session transcript
> forward. If the client just provides it to the server, then that
> seems to have different security properties unless we require the
> server to verify it. Is that what you have in mind here?

I suggest that the “context” is something that the client generates
and the server must  check. 

When a client receives a DH ServerConfiguration,
or a NewSessionTicket, or an out-of-band PSK, it
generates and stores the context with the key material.

When the server receives the id+context, it always has
enough information to be able to check the context
after processing the id. (e.g. it decrypts the sessionticket
and then verifies the context.) The server must perform this check.

> I note that the context value here was intended for a different
> purpose,

Yeah, sorry for reusing the name, but we were already using Handshake Context,
so perhaps this confusion was already there.

Best,
Karthik

> 
> It's not super-elegant to have a switch here in the decode for
> EarlyDataIndication, but they actually are semantically different, so
> I'm not sure it's that bad. The idea here would be to design to a
> different invariant, namely:
> 
> - The client gets to offer the server a bunch of options for the
>   1-RTT handshake. The server picks one.
>   
> - The client offers the server exactly one option for 0-RTT and
>   the server can take it or leave it.
> 
> This is the way that 0-RTT DHE works now. It does open the door
> to the server somehow picking a different option for 1-RTT than
> the client chose for 0-RTT, but this is something we could forbid.
>   
> 
> > 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;
> 
> The cipher suites indication seems generally sensible.
> 
> 
> >         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)
> 
> This is an interested suggestion. I agree that it's important to
> be able to say "don't send me 0-RTT data" (see above). ISTM that
> "all_early_data_allowed" would be useful primarily if we allowed
> clients who received it to use the ordinary TLS 1.3 API for sending
> 0-RTT data. That would be a real advantage, it seems to me.
> 
> 
> 
> > 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,
> 
> Nit: This doesn't sound like a passive attacker to me...
> 
> 
> > 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.
> 
> Yes, I agree that this is an improvement.
> 
> -Ekr
> 
> 
> On Fri, Mar 25, 2016 at 2:29 AM, Karthik Bhargavan <karthikeyan.bhargavan@inria.fr <mailto:karthikeyan.bhargavan@inria.fr>> wrote:
> 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
> 
> 
> 
> 
> 
> _______________________________________________
> TLS mailing list
> TLS@ietf.org <mailto:TLS@ietf.org>
> https://www.ietf.org/mailman/listinfo/tls <https://www.ietf.org/mailman/listinfo/tls>
>