Re: [TLS] KeyUpdate and unbounded write obligations

Jim Schaad <ietf@augustcellars.com> Thu, 18 August 2016 19:14 UTC

Return-Path: <ietf@augustcellars.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 4DD7712D794 for <tls@ietfa.amsl.com>; Thu, 18 Aug 2016 12:14:13 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -3.148
X-Spam-Level:
X-Spam-Status: No, score=-3.148 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RP_MATCHES_RCVD=-1.247, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iqoBOq-I-I1h for <tls@ietfa.amsl.com>; Thu, 18 Aug 2016 12:14:10 -0700 (PDT)
Received: from mail2.augustcellars.com (augustcellars.com [50.45.239.150]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id D284512D122 for <tls@ietf.org>; Thu, 18 Aug 2016 12:14:09 -0700 (PDT)
Received: from hebrews (192.168.1.152) by mail2.augustcellars.com (192.168.1.201) with Microsoft SMTP Server (TLS) id 15.0.1178.4; Thu, 18 Aug 2016 12:25:57 -0700
From: Jim Schaad <ietf@augustcellars.com>
To: 'Keith Winstein' <keithw@cs.stanford.edu>, 'David Benjamin' <davidben@chromium.org>
References: <CAF8qwaDgGHGmuBwhZEz9-=Ss2bfzNAYWfmnbMqQDxTQnMUpH7g@mail.gmail.com> <93086b3c-ca1b-4c37-67e1-efbf417a8b58@akamai.com> <CAF8qwaDfWdCCQpD8z8iY0BMJjbrf8qi-qf5X7mSe8m+hNZu-FQ@mail.gmail.com> <CAMzhQmPB0GXZzh+g=-TMmAp9HQxpZUPcht4zi3_K7WW_ouGg6A@mail.gmail.com>
In-Reply-To: <CAMzhQmPB0GXZzh+g=-TMmAp9HQxpZUPcht4zi3_K7WW_ouGg6A@mail.gmail.com>
Date: Thu, 18 Aug 2016 12:13:37 -0700
Message-ID: <08a201d1f984$a16b2d10$e4418730$@augustcellars.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Mailer: Microsoft Outlook 16.0
Thread-Index: AQLBzL2rhv6uAYGgpFsZh/u28QZ33wIMUf02AbA1oKIB270F0p5CrRLg
Content-Language: en-us
X-Originating-IP: [192.168.1.152]
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/RyfyFnME7igS_Yl5JoqIfTw-_SE>
Cc: tls@ietf.org
Subject: Re: [TLS] KeyUpdate and unbounded write obligations
X-BeenThere: tls@ietf.org
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." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 18 Aug 2016 19:14:13 -0000


> -----Original Message-----
> From: TLS [mailto:tls-bounces@ietf.org] On Behalf Of Keith Winstein
> Sent: Thursday, August 18, 2016 11:21 AM
> To: David Benjamin <davidben@chromium.org>
> Cc: tls@ietf.org
> Subject: Re: [TLS] KeyUpdate and unbounded write obligations
> 
> It sounds like there are four properties in play here:
> 
> P1: Either side can rekey its outgoing traffic whenever it wants.
> 
> P2: Either side can "force an update to the entire connection," i.e.
> can ask the other side to rekey *its* outgoing traffic.
> 
> P3: A side can learn that P1 has been read by the other side.

If you are not getting any traffic back, it seems that this might a problem.
P1 + P3 causing P4.  Unless you are willing to not know the difference
between traffic getting lost and traffic being processed.

Jim

> 
> P4: Neither side can cause the other to accrue an unbounded deferred write
> obligation; in fact the maximum accruable deferred write obligation is one
> KeyUpdate.
> 
> The current draft has P1 and P2 only.
> 
> My view: all four properties are important.
> 
> I've previously argued for the benefit of P3.
> 
> Re: P2, there seems to be some disagreement about the value. I think it is
-- one
> endpoint may well have knowledge (about the traffic or its future
susceptibility
> to compromise) that makes it want to ratchet the session. Forward secrecy
is
> not only valuable to the sender. I don't think it's enough to recommend
that
> each side rekey its own direction occasionally.
> 
> I don't think it's a particularly hard design or implementation challenge
to get all
> four properties.
> 
> Here a simple explicit and verbose design as a straw-man, that gets P1,
P2, P3,
> and P4:
> 
> 1) As David proposes, separate the tracks and have two KeyUpdate ladders.
> 
> 2) Define KeyUpdate like this:
> 
>    struct {
>        uint64 desired_minimum_receive_generation;
>        uint64 current_receive_generation;
>    } KeyUpdate;
> 
> Language: "An implementation MAY update its send keys by sending a
> KeyUpdate. An implementation MAY request that the other side update its
send
> keys by increasing the desired_minimum_receive_generation. An
> implementation MUST NOT set desired_minimum_receive_generation to be
> greater than its current_receive_generation plus one."
> 
> "Upon receiving a KeyUpdate, the receiver MUST increment their receiving
> generation by one. If the desired_minimum_receive_generation
> is greater than its current send generation, the receiver MUST update its
send
> keys and send a KeyUpdate. If the desired_minimum_receive_generation is
> greater than the current send generation plus one, the receiver SHOULD
abort."
> 
> -Keith
> 
> On Thu, Aug 18, 2016 at 10:26 AM, David Benjamin <davidben@chromium.org>
> wrote:
> > On Thu, Aug 18, 2016 at 1:08 PM Benjamin Kaduk <bkaduk@akamai.com>
> 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. :-)
> >
> > David
> >
> > _______________________________________________
> > TLS mailing list
> > TLS@ietf.org
> > https://www.ietf.org/mailman/listinfo/tls
> >
> 
> _______________________________________________
> TLS mailing list
> TLS@ietf.org
> https://www.ietf.org/mailman/listinfo/tls