Re: [TLS] KeyUpdate and unbounded write obligations

Ilari Liusvaara <> Thu, 25 August 2016 04:23 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id A825012D58A for <>; Wed, 24 Aug 2016 21:23:58 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.448
X-Spam-Status: No, score=-2.448 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RP_MATCHES_RCVD=-0.548] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id t2iAG8xWO1l3 for <>; Wed, 24 Aug 2016 21:23:56 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id C511712D1AD for <>; Wed, 24 Aug 2016 21:23:55 -0700 (PDT)
Received: from localhost (localhost []) by (Postfix) with ESMTP id DDC8BF468; Thu, 25 Aug 2016 07:23:53 +0300 (EEST)
X-Virus-Scanned: Debian amavisd-new at
Received: from ([IPv6:::ffff:]) by localhost ( [::ffff:]) (amavisd-new, port 10024) with ESMTP id QFjaJ1RjudIq; Thu, 25 Aug 2016 07:23:53 +0300 (EEST)
Received: from LK-Perkele-V2 ( []) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPSA id 935CD2310; Thu, 25 Aug 2016 07:23:53 +0300 (EEST)
Date: Thu, 25 Aug 2016 07:23:44 +0300
From: Ilari Liusvaara <>
To: Keith Winstein <>
Message-ID: <>
References: <> <> <> <> <> <> <> <> <> <>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Disposition: inline
In-Reply-To: <>
User-Agent: Mutt/1.6.2-neo (2016-08-21)
Archived-At: <>
Cc: Adam Langley <>, "" <>
Subject: Re: [TLS] KeyUpdate and unbounded write obligations
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." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 25 Aug 2016 04:23:59 -0000

On Wed, Aug 24, 2016 at 04:01:45PM -0700, Keith Winstein wrote:
> Hi Subodh,
> Interesting points.
> On the form of the generation identifier: The draft does already
> specify the generations as integers (traffic_secret_N, N+1, etc.), and
> the semantics of a KeyUpdate are that when you receive one, you
> increment the generation of the receive key. So the proposed
> "receive_generation" field is really just echoing the generation
> number back. I could imagine a different system where the KeyUpdate
> instead includes an opaque identifier, and the receiving
> implementation is then supposed to echo back the most recent opaque
> identifier that it got. That would also provide Property P3, and so I
> would be totally fine with it. But now we're talking about adding
> *two* fields to a KeyUpdate (the sender's opaque identifier, and also
> an echo of the most recently received opaque identifier), instead of
> one field, so I'd be surprised if there were more consensus around
> this alternate approach!

The generations are not specified as integers. It is just some abstract
sequence (nowhere in protocol is that generations are integers used).

And echoing identifiers doesn't work. The key updates can cross in
flight, so neither is after one another.

> On the API that a TLS implementation would expose: Obviously the WG
> doesn't have to specify this, but here are three APIs I could imagine:
> (1) No change to current APIs. The TLS implementation itself triggers
> KeyUpdate when it wants to (e.g. per recommendation on when the
> underlying cipher wants to be rekeyed), but doesn't expose this to the
> application.

The intended application of KeyUpdate is mostly this, with optional
knobs controlling the frequency of rekeying.

> (2) Fire-and-forget. The TLS implementation exposes a
> `rekey_session()` function, which initiates a KeyUpdate. [If we adopt
> the proposal described earlier in this thread, maybe there's a boolean
> parameter about whether to request a reciprocal rekey from the other
> side...]

Due to design, one can't do a reciproal rekey.
> (3) Fire-and-later-check. The TLS implementation exposes #2 above, but
> also `tls_session_generations()`, which returns a pair of integers
> giving the current sending and receiving generations.
> Any application we might want to build can be built on top of #3.

Nope, the KeyUpdate is designed to deal with arbitrary latency in
order to fully decouple the direction (any coupling there would lead
to API problems, which apparently are more major than I initially

And if that is combined with request-response protocol, if you just
send a KeyUpdate without application data, the response will NEVER