Re: [TLS] KeyUpdate and unbounded write obligations

Benjamin Kaduk <> Thu, 18 August 2016 17:08 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id B326812D5CA for <>; Thu, 18 Aug 2016 10:08:06 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -3.967
X-Spam-Status: No, score=-3.967 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.247, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id e9dVJChE41yh for <>; Thu, 18 Aug 2016 10:08:04 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id DC65612B027 for <>; Thu, 18 Aug 2016 10:08:03 -0700 (PDT)
Received: from (localhost.localdomain []) by postfix.imss70 (Postfix) with ESMTP id 217B8433424; Thu, 18 Aug 2016 17:08:03 +0000 (GMT)
Received: from ( []) by (Postfix) with ESMTP id F3C5B43340E; Thu, 18 Aug 2016 17:08:02 +0000 (GMT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=a1; t=1471540083; bh=l/T4zNmoeCeZ+Q+Ifd2EiM3EnKix6JKKUhDXucJWIMA=; l=9371; h=To:References:From:Date:In-Reply-To:From; b=yUD6qmHk9ta/XIWSA+c8cn9V5PugFAj0IaBWN1DknjJj69geMbJKtoy1rGk7+hk5+ MbAgeLd8wjO4HyAI/iz+AVU4C8z1zafoQToqB+OGEULDLzSYw1P68rn+MusgZfzrDk MsKt5ytiU6YRCsoZ4JJQu0LMtjpaCcXqWymTU8dA=
Received: from [] ( []) by (Postfix) with ESMTP id A93B91FC86; Thu, 18 Aug 2016 17:08:02 +0000 (GMT)
To: David Benjamin <>, "" <>
References: <>
From: Benjamin Kaduk <>
X-Enigmail-Draft-Status: N1110
Message-ID: <>
Date: Thu, 18 Aug 2016 12:08:02 -0500
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0
MIME-Version: 1.0
In-Reply-To: <>
Content-Type: multipart/alternative; boundary="------------DD6D5AB3EB5EF5D4E832D9B4"
Archived-At: <>
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, 18 Aug 2016 17:08:07 -0000

On 08/17/2016 11:29 PM, David Benjamin wrote:
> However, we lose the "free" (really at the cost of this unboundedness
> problem) generation-based bidirectional KeyUpdate sync. Depending on
> what we want out of KeyUpdate, I can imagine a few options:

My recollection is that the only reason we have KeyUpdate is to avoid
going over the limit for amount of ciphertext encrypted in the same key
within our safety margin (recall the analyses debating whether such
limits would even be reachable for the ciphers currently in use, as well
as the disagreement as to what the safety margin should be).

> - Don't. KeyUpdates are unilateral. Recommend in the spec to KeyUpdate
> every N records or so and leave it at that. (I think this is the best
> option on grounds of simplicity, assuming it meets the primary needs
> of KeyUpdate.)

If we're in a world where implementations are considering leaving out
the required "catch up" KeyUpdate, we may want to consider alternative
options to put in the spec that are easier to implement.  That is, we
can write the spec in various ways to get the functionality that both
write directions get the key updates needed to avoid the ciphertext
limit, and we are reliant on implementations to follow the spec in order
to get that safety property.  So, given that we can only get the safety
property if all implementations follow the spec, why not just ...
require implementations to track the amount sent and rekey if it's too
close to the limit?  That is consistent with a unilateral/unidirectional
KeyUpdate, and having per-connection byte/record counters does not seem
to be a huge overhead.

Keeping the two write directions' keys independent would also avoid
conflict when the two peers disagree on how often a rekey is necessary
(as might happen if a resource-constrained device decided to not
implement byte counters and just rekey after every N records, which is
"free" since you need to track serial numbers anyway).

> - If you receive a KeyUpdate and didn't send one in the last N minutes
> (where N minutes >>> 1 RTT), (optionally?) flag your next write to be
> preceded by KeyUpdate. This is simple but needs an ad-hoc timeout to
> prevent ping-ponging.
> - Variations on sticking a please_echo boolean in the KeyUpdate
> message, generation counts, etc., to get synchronization with
> coalescing if we need it. I would much prefer the simpler options
> unless we truly need this. (KeyUpdate is right now a *required*
> feature, so simplicity should be a priority. Rare use cases are what
> extensions are for.)
> Thoughts?
> David
> PS: We've seen this before with renego (I've seen many OpenSSL
> consumers which lock up if the peer renegotiation), error alerts
> triggered on reads (often they don't get sent), and close_notify (also
> don't get sent in practice). Deviations from dumb filters are expensive.

Yes, simple is better.  Well, here at least :)

> PPS: I'm wary of over-extending post-handshake auth for the same
> reason, though I haven't had time to look carefully at the latest
> proposal yet. Still, having TLS specify and analyze the crypto while
> lifting the actual messages into application-level framing would be
> preferable for these sorts of side protocols. The application gets to
> make assumptions about read/write flows and knows in which contexts
> what is and isn't allowed.

Hmm, so [in the above proposal] that would involve the application doing
the byte/record counters and pushing a "give me a rekey packet now"
button when needed?  I am not sure that I'm comfortable moving "crypto
sensitive" code (well, sort-of) into the application, since many
applications won't do it.  Also, not all applications will have access
to the record serial number, as I understand it, and the formulas I
remember for the ciphertext limits involved both records and bytes.