Re: [TLS] KeyUpdate and unbounded write obligations

David Benjamin <> Thu, 18 August 2016 17:27 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 86D1812D85F for <>; Thu, 18 Aug 2016 10:27:00 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -3.946
X-Spam-Status: No, score=-3.946 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, 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 RKeP7QIaGI9r for <>; Thu, 18 Aug 2016 10:26:56 -0700 (PDT)
Received: from ( [IPv6:2607:f8b0:4001:c06::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 5FD8712DACC for <>; Thu, 18 Aug 2016 10:26:48 -0700 (PDT)
Received: by with SMTP id b62so25273151iod.3 for <>; Thu, 18 Aug 2016 10:26:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=8O8QRI5JLUv32ZWdoSVAGhQHlkSu5kZSvn9Vq4mkvrQ=; b=Tjo54XA8+uYrPPGYcldr6hpG2N4ve4+IEy5oeFCKGOBmKzwL6ITyrhHDLy6WzE6wJ+ JYgqcl4aEpq83abwrm/YdvGGVdcl50gD1PNchu3RrddkmRRqls83wnKScKs8FoREQLNA 1BpR2NYP5Pms6xrIdAcJtMOn8qpBOImz4bRRs=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=8O8QRI5JLUv32ZWdoSVAGhQHlkSu5kZSvn9Vq4mkvrQ=; b=atQPkNf03m7cy3oK/IyB7h+99ZCfj36UuUuKS/lEgzr/YQJmIycMKHKg6NOdn6PaiH hgt+KBEz9zsiTorQGW04cvGGPz/zcDIx190wbAw+bsTQ6fksHmAv18i8Yzpl3i9W7JI2 +IUqIXt9Hl4OPW+eV+t5GvEb/m1B7fDbufiunpOSuYaPjV5ICFErrTQf9JBOVstlQ/qw TMhTu5VmqpQgOjDKs1iVLo6AyvJLcvywHf2WtHGUrFpHjv+EhbqEwNBd8ealZnV2q8Ed b3yVuVp94QlTCCsOiXfGqPzIuEaqEF3dBsjR8e5fSKcf4gaEJOO81vPnCgte+yD5N92f e3Pg==
X-Gm-Message-State: AEkooutfHV/fEk6S41ton/iRQiCs6n9ai6yx2NeFxQsXamxXLkV3BQlK4dI5UIUwvRSusfMdGTLCRubwT4EPOKPx
X-Received: by with SMTP id b189mr4755476ioa.6.1471541207370; Thu, 18 Aug 2016 10:26:47 -0700 (PDT)
MIME-Version: 1.0
References: <> <>
In-Reply-To: <>
From: David Benjamin <>
Date: Thu, 18 Aug 2016 17:26:37 +0000
Message-ID: <>
To: Benjamin Kaduk <>, "" <>
Content-Type: multipart/alternative; boundary="001a11440f7ef06d32053a5be21b"
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:27:00 -0000

On Thu, Aug 18, 2016 at 1:08 PM Benjamin Kaduk <> wrote:

> 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).

Yup. If we say implementations SHOULD/MUST/whatever send KeyUpdates
frequently and we're fine with just saying we rely on each sender to honor
that w.r.t. their own send keys with little other fanfare, I think this
option is the clear winner. We're already relying on the sender to not,
say, exfiltrate all data somewhere nasty.

There seemed to be other motivations for KeyUpdate (Keith's passive
observer use case, I've heard some theories around one side knowing more
about the cipher than another, etc.), so I left that alone for now. I'm not
currently convinced by those use cases, but perhaps the working group feels
differently. I'm reasonably confident splitting the key tracks is correct
regardless, but I wasn't sure which KeyUpdate motivations were considered
important and which weren't.

> - 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.

Sorry, that was unclear. That was more of a side comment to help explain
why I have such strong visceral reactions to any post-handshake auth
mechanisms since part of it is the same issue. I am not proposing we lift
KeyUpdate to the application layer. I'm proposing we split the KeyUpdate
tracks in two and do [insert preferred option here] w.r.t. the
bidirectionality issue. Probably should not have mentioned it since it's
mostly a distraction for this topic. I ramble a lot. :-)