Subject: Re: [TLS] TLS 1.3 PR #426: KeyUpdate message: add receive_generation field

From: Philip Levis <[email-masked]>
Date: Sat, 5 Mar 2016 00:46:01 -0800

Comments inline.

> On Feb 27, 2016, at 9:53 AM, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Fri, Feb 26, 2016 at 4:24 AM, Ilari Liusvaara <[email-masked]> wrote:
> On Fri, Feb 26, 2016 at 01:27:45AM -0800, Judson Wilson wrote:
> > Hello folks,
> >
> > How this helps: In the current draft, an endpoint that sends a KeyUpdate
> > message and later receives a KeyUpdate message cannot know whether the
> > other side has actually updated its receive keys. The two messages may have
> > been generated independently and crossed in flight. Putting a
> > receive_generation field in the KeyUpdate message lets an endpoint confirm
> > that the other side has received and acted upon an earlier KeyUpdate
> > message.
> 
> Well, the KeyUpdates are designed to be asynchronous so that the other
> end does not need to know if the other has acted on KeyUpdate.
> 
> That's correct. And would continue to be the case here.

Absolutely. This mechanism doesn’t in any way compromise the asynchronous behavior of KeyUpdate. However, there’s a big difference between whether an endpoint has to know, and whether an endpoint can know. The goal of this mechanism is to provide a very simple, lightweight way for an endpoint to (asynchronously) learn when the other side has acted on KeyUpdate (asynchronously). 
> 
>  
> 
> > One way for a client to grant delayed read-only access in TLS 1.3 is with a
> > "rotate and release." The client starts by sending a KeyUpdate. Later,
> > after all traffic keys from the previous generation have been superseded on
> > both sides, the client releases the (superseded) traffic keys to the
> > middlebox. The middlebox can use the keys to decrypt the previous
> > generation of ciphertext, without danger of compromising the integrity of
> > the session. The challenge is that an endpoint can't safely release its old
> > send keys until it knows that the other side has updated its receive keys.
> > Hence the receive_generation field.
> 
> There are better (and less broken) ways to do this kind of thing
> (involving two MACs).
> 
> I agree that there are arguably more elegant approaches if you are willing
> to change TLS. It seems like the argument here is that this doesn't require
> ay significant changes.

Exactly. Two MACs might be elegant, but elegant != deployable.

> 
> > We think this is a pretty lightweight way to resolve the ambiguity from
> > KeyUpdates crossing in flight; it doesn't add any blocking, waiting, or
> > extra rounds or messages. Thanks in advance for any feedback.
> 
> The KeyUpdate design is so that crossings don't matter.

Something I think that might not have been clear is this proposal doesn’t in any way change how KeyUpdates are generated or processed. In that way, crossings do not matter for the protocol. However, from an application standpoint, when a KeyUpdate is performed, there can be ambiguities on which keys are in use. Ambiguities in secure protocols can create problematic edge cases, like the one Judson outlined. We’d like it to be possible to resolve those ambiguities without changing TLS or adding any significant complexity.

Ilari, do you see a security flaw in having one side know which keys the other side is using? Explicit information between the two endpoints seems like a good idea to me. Or do you think this change makes TLS more complex and harder to implement correctly?

Phil

---

From: Ilari Liusvaara <[email-masked]>
Date: Sat, 5 Mar 2016 11:48:43 +0200

On Sat, Mar 05, 2016 at 12:46:01AM -0800, Philip Levis wrote:
 
> Something I think that might not have been clear is this proposal
> doesn’t in any way change how KeyUpdates are generated or processed.
> In that way, crossings do not matter for the protocol. However, from
> an application standpoint, when a KeyUpdate is performed, there can
> be ambiguities on which keys are in use. Ambiguities in secure
> protocols can create problematic edge cases, like the one Judson
> outlined. We’d like it to be possible to resolve those ambiguities
> without changing TLS or adding any significant complexity.

There should be no ambiguities from application standpoint. The whole
reason for fully asynchronous design is that the application does not
have to care about rekeying (other than setting parameters if the
defaults aren't suitable).

And TLS stacks only need to know current valid receive keys (which
is just one key for non-datagram TLS) and the newest send key.

> Ilari, do you see a security flaw in having one side know which
> keys the other side is using? Explicit information between the
> two endpoints seems like a good idea to me. Or do you think this
> change makes TLS more complex and harder to implement correctly?

I don't think the application needs to know that. And TLS stacks
know valid receive keys anyway.

And thanks to fully asynchronous design, have fun if client
requests 27GB Blu-Ray ISO over HTTP/1.1 and server decides to
rekey...

The security problems arise when one uses this as basis to reveal
keys (which is not something TLS libraries should even support, just
the existence of API breaks the security models in all sorts of
nasty ways).

-Ilari