Subject: [TLS] Do we really need two 0-RTT keys?

From: Christian Huitema <[email-masked]>
Date: Fri, 18 Dec 2015 22:45:15 +0000

The ladder diagram describing the 0-RTT exchange is simple enough, as seen in this extract:

         Client                                               Server
        
         ClientHello
           + KeyShare
           + EarlyDataIndication
      ^  (Certificate*)
0-RTT |  (CertificateVerify*)
Data  |  (Finished)
      v  (Application Data*)
         (end_of_early_data)        -------->

The text indicates that client auth and application data messages are protected by "keys derived from the static secret." But then, hidden in section 7.2 is an interesting twist -- too different keys are supposed to be derived from the static secret, one for 0-RTT handshake, another for 0-RTT Application. If I understand correctly, the Certificate, CertificateVerify and Client Finished message would be protected with the "0-RTT Handshake" key, and the Application data and end-of-early data message would be protected with the "0-RTT Application" key.

I assume that there is a good reason for this extra complexity, even if it eludes me. But I worry a bit about what that would do when we start working on DTLS 1.3. UDP messages can arrive out of order. Yes, there is a message number, but the record layer is not necessarily well positioned to interpret it -- the certificate and verify message are optional, so when a record layer receives packet #3 before packet #2, it does not know whether this is a CertificateVerify message (handshake key) or an application message (application key). 

Yes, there are solutions, yes, it can be managed, but are we sure that this particular bit of complexity is worth it?

And if it worth it, can we add a description of the key switching logic in section 6.2.2?

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 18 Dec 2015 15:02:09 -0800

On Fri, Dec 18, 2015 at 2:45 PM, Christian Huitema <[email-masked]>
wrote:

> The text indicates that client auth and application data messages are
> protected by "keys derived from the static secret." But then, hidden in
> section 7.2 is an interesting twist -- too different keys are supposed to
> be derived from the static secret, one for 0-RTT handshake, another for
> 0-RTT Application. If I understand correctly, the Certificate,
> CertificateVerify and Client Finished message would be protected with the
> "0-RTT Handshake" key, and the Application data and end-of-early data
> message would be protected with the "0-RTT Application" key.
>

Yes, that's correct.

> I assume that there is a good reason for this extra complexity, even if it
> eludes me.

The motivation for this was that a number of people working on analysis
complained
that using the same key to encrypt handshake traffic and application
traffic (as
is done in TLS 1.2 with Finished and application messages) made analysis
harder.
I'm not equipped to take a position on this, but that's what I have been
told. We
already do that for the 1-RTT keys and we're doing the same thing here.

> But I worry a bit about what that would do when we start working on DTLS
> 1.3. UDP messages can arrive out of order. Yes, there is a message number,
> but the record layer is not necessarily well positioned to interpret it --
> the certificate and verify message are optional, so when a record layer
> receives packet #3 before packet #2, it does not know whether this is a
> CertificateVerify message (handshake key) or an application message
> (application key).
>

Note: the Certificate message isn't optional in the sense that the server
doesn't
know if it's coming. Whether it's sent is conditioned on the configuration
(in WIP-11)
an on the client's EarlyDataInfication (in WIP-10).

But your general point is right in that you can have loss and reordering.
So, for instance,
say that the client sends messages with seq nums as follows:

    ClientHello: 0 (in clear)
    Finished: 1 (with Handshake Key)
    AppData:  2 (with app key)

    Now, 1 and 2 are lost, and the client retransmits:

    Finished: 3 (with Handshake Key)
    AppData: 4 (with app key)

If #3 is now lost, the server may not know if #4 is handshake or
application data
since (for instance) the client might have fragmented the Finished over two
records.

Now, I think there are several ways to deal with this. First, the server
can just
continue to attempt to process records with the handshake key until the
handshake
is completed, in which case it will drop #4 and then get the retransmit of
the
Finished (#5, presumably). Second, DTLS has an epoch # used to indicate
which
generation key you are using. We should come down on some deterministic use
of
that in which case things will be obvious.

Yes, there are solutions, yes, it can be managed, but are we sure that this
> particular bit of complexity is worth it?
>

Karthik? Others? :)

> And if it worth it, can we add a description of the key switching logic in

That seems like a good plan...

Ekr

-- Christian Huitema
>
>
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Christian Huitema <[email-masked]>
Date: Sat, 19 Dec 2015 00:41:28 +0000

On Friday, December 18, 2015 3:02 PM, Eric Rescorla wrote:
> On Fri, Dec 18, 2015 at 2:45 PM, Christian Huitema <[email-masked]> wrote:
>...
>> The text indicates that client auth and application data messages are protected by "keys 
>> derived from the static secret." But then, hidden in section 7.2 is an interesting twist -- 
>> two different keys are supposed to be derived from the static secret, one for 0-RTT 
>> handshake, another for 0-RTT Application. If I understand correctly, the Certificate,
>> CertificateVerify and Client Finished message would be protected with the "0-RTT
>> Handshake" key, and the Application data and end-of-early data message would 
>> be protected with the "0-RTT Application" key.
>
> Yes, that's correct.
>
>> I assume that there is a good reason for this extra complexity, even if it eludes me.
>
> The motivation for this was that a number of people working on analysis complained
> that using the same key to encrypt handshake traffic and application traffic (as
> is done in TLS 1.2 with Finished and application messages) made analysis harder.
> I'm not equipped to take a position on this, but that's what I have been told. We

Actually, we do both. In section 6.2.3, the diagram shows [NewSessionTicket] between square brackets, i.e. encrypted with the same key as Application Data. Which makes sense, because it will be received after the Server Finished message. I assume the same is true for other Post Handshake messages.
 
>> But I worry a bit about what that would do when we start working on DTLS 1.3. UDP 
>> messages can arrive out of order. Yes, there is a message number, but the record layer 
>> is not necessarily well positioned to interpret it -- the certificate and verify message 
>> are optional, so when a record layer receives packet #3 before packet #2, it does not 
>> know whether this is a CertificateVerify message (handshake key) or an application 
>> message (application key).
>
> Note: the Certificate message isn't optional in the sense that the server doesn't
> know if it's coming. Whether it's sent is conditioned on the configuration (in WIP-11)

Yes, I realize that. But in theory we have a "layered protocol." What you describe is somewhat of  a layer violation.

> But your general point is right in that you can have loss and reordering. So, for instance,
> If #3 is now lost, the server may not know if #4 is handshake or application data
> Now, I think there are several ways to deal with this. First, the server can just
> continue to attempt to process records with the handshake key until the handshake
> is completed, in which case it will drop #4 and then get the retransmit of the
> Finished (#5, presumably). Second, DTLS has an epoch # used to indicate which
> generation key you are using. We should come down on some deterministic use of

The obvious workaround is to have several keys available at the record layer, and if one fails try the other. Of course, it opens the gates for interesting bugs...

> That seems like a good plan...

Yes please!

-- Christian Huitema