Re: [TLS] The case for a single stream of data

Colm MacCárthaigh <colm@allcosts.net> Thu, 11 May 2017 06:01 UTC

Return-Path: <colm@allcosts.net>
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 44807129A99 for <tls@ietfa.amsl.com>; Wed, 10 May 2017 23:01:49 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.599
X-Spam-Level:
X-Spam-Status: No, score=-2.599 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=allcosts-net.20150623.gappssmtp.com
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 biBRY_q3UtT0 for <tls@ietfa.amsl.com>; Wed, 10 May 2017 23:01:46 -0700 (PDT)
Received: from mail-yw0-x22c.google.com (mail-yw0-x22c.google.com [IPv6:2607:f8b0:4002:c05::22c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 54BDF128BC8 for <tls@ietf.org>; Wed, 10 May 2017 23:01:46 -0700 (PDT)
Received: by mail-yw0-x22c.google.com with SMTP id b68so7860250ywe.3 for <tls@ietf.org>; Wed, 10 May 2017 23:01:46 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=allcosts-net.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=ye5ySPHMhQkisjJ8IFPVK+RhQTHlcVjImCC1SeiBwi0=; b=gLEAM8TaVki3wFnKamYFU0+wI0Ey5SHQYHEZllEuSvPq3o2Ku8B518uc+lubfE9Ny9 9qtqcovy5jrixivMVrrf7vg7ghcOuOUitILf9YIwgF2GTtJa0xcoX8Di7Ep8WGZG2oZ6 pYRXFwLhdTHpvvqgRFiyMpiAyEoFuFMyTYDKWr5KEyyFndzvFdbIHpXEC5GYdOZKw3We vUkUdw7IkpB+XM4xu5ITvJReDRWlEZeTo85Xf+9BePTujDcJtkvCz/F65NnjlzlNBjyG ldOerST6ahoQ/lyQaP6GXY3JsUumOkM6IQtirqGgSxnQMg5eVYTwT/2RhML5BFG3D3SZ BeCg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=ye5ySPHMhQkisjJ8IFPVK+RhQTHlcVjImCC1SeiBwi0=; b=hhl4fSUvWvZjUVusTSb7Zv5XitHL7pSP7IgXi1LnyB7553ADvPaW3ATNHjwn3D1Jiv HTqKS6m31jmMu1Wyp6AaHJP2CAG5hfHJ9+/ZFIsDlGangZZ15OalloYzjpNAKjEBLd5j TKlFNG3125KaI5mJYAperxt7Nb093lTRNXBfPcpTUo1vJ30pjqKtshHLWqOrLdl+/tiB /NBq8iJ/sw1nOo2rzQuhtUCOEw3vxWz4t1AXybFeChOvuFwM8KrrwUjryp8CiWyVtGRK UuyNdBWuYSKY/wRRMG9+RcSxsp+DSpc0sC9Zhx78t6N0vQGOclmOZ60SFkm1Cp8zBqur nr5g==
X-Gm-Message-State: AODbwcAmzvQg8A697YX0mChVlMCd01eIhiYP9zduoVawI7NaDVonENlF k8J7kUoOBHQv3uT6O+bigHR1DbOkIA==
X-Received: by 10.129.96.69 with SMTP id u66mr392217ywb.241.1494482505336; Wed, 10 May 2017 23:01:45 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.129.57.67 with HTTP; Wed, 10 May 2017 23:01:44 -0700 (PDT)
In-Reply-To: <c94ff8ac-583c-7bf4-83a3-5757e677b9c6@akamai.com>
References: <CAAF6GDfm=voTt_=JrdGtiaYby1JG8ySU2s6myjjpHKeGvi0bMg@mail.gmail.com> <c94ff8ac-583c-7bf4-83a3-5757e677b9c6@akamai.com>
From: Colm MacCárthaigh <colm@allcosts.net>
Date: Wed, 10 May 2017 23:01:44 -0700
Message-ID: <CAAF6GDdM64Eg8u84Q0_DpSa=ThRNYKRsT1zDgFV7XRFSoiT0+Q@mail.gmail.com>
To: Benjamin Kaduk <bkaduk@akamai.com>
Cc: "tls@ietf.org" <tls@ietf.org>
Content-Type: multipart/alternative; boundary="001a11471c00da9dcf054f395286"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/vpU-BMUvCb0cZQEvLV9bWOx8V7s>
Subject: Re: [TLS] The case for a single stream of data
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.22
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, 11 May 2017 06:01:49 -0000

On Wed, May 10, 2017 at 10:00 PM, Benjamin Kaduk <bkaduk@akamai.com> wrote:
>
> However, I'm still not convinced that requiring strong 0-RTT non-replay is
> feasible/the right thing to do.
>

[ I've cut a lot for brevity, but hopefully what I've replied with can
address this, and the rest ]

The case for requiring servers, and especially middle-boxes to provide
strong 0-RTT non-replay is really the resource exhaustion, throttle
exhaustion and cache timing attacks. I think that's where the really
dangerous bugs are, the ones that will be exploited - maybe even
inadvertently - and that are a show-stopper for the stateless mitigation.
It just doesn't work.

Thankfully it's within our capabilities to fix this and there's nothing
logically impossible about providing non-replay for the 0-RTT sections.


> On 05/05/2017 11:28 AM, Colm MacCárthaigh wrote:
>
> "Client sends a request with a 0-RTT section. The attacker lets the server
> receive it, but suppresses the server responses, so the client downgrades
> and retries as a 1-RTT request over a new connection. Repeating the
> request".
>
> Does the client always downgrade?  We don't require it to do so, in TLS
> 1.3, though of course browsers would.
>

The current draft says that clients should only use tickets once, if they
do that, then the repeat attempt (even if it's still 0-RTT, with a
different ticket) is un-correlatable.

I feel like many applications that use delay-and-retry will see this and
> conclude that they should just not attempt to use 0-RTT.
>

Per the section of the original review about violation of layers and
separation of actors; this breaks the well-established relationship between
the layers. It's predictable that a site-administrator will enable 0-RTT
without any appreciation for the application-level impact. Vendors are
already providing 0-RTT in backwards compatible ways.

What is actually needed here, I think, is client-side signaling. Careful
> clients need to be made aware of the original 0-RTT failure.
>
> So for example, an SDK that writes to an eventually consistent data store
> may treat any 0-RTT failure as a hard failure, and *not* proceed to sending
> the request over 1-RTT. Instead it
>
>
> Right; nothing *requires* the client to retry failed 0-RTT as 1-RTT; the
> application can decide it's willing to take the risk or use some other
> strategy.  But I'm not convinced that the TLS stack needs to decide on its
> own, without application input.
>

I'm just describing the only backwards compatible safe-by-default scheme I
can concoct, it's definitely kludgey and awkward. For this thread, my main
take-away from it is that separating streams doesn't actually help the
application; instead, it's a timing thing.


> Does a careful client really need the TLS stack to signal connection
> error?  Surely the TLS stack will provide a mechanism to inquire as to the
> connection state, and whether 0-RTT was rejected.  The application could
> implement its own delay.
>

Yep, absolutely; but it'd be client-side signaling, and it's not
backwards-compatible or safe-by-default to rely on.


> And I read what you wrote in the github issue about how saying "don't use
> 0-RTT" is not practical, but I don't believe that it is universally true.
> Some (careful) applications will rightly consider the tradeoffs and decide
> to not use it.  On the web ... there are different forces at play, and it
> may well take a (security bug) name and website to cause webapp creators
> and framework authors to take proper notice.  But I am having a hard time
> squaring your point about careful clients with the point about
> non-practicality.  If there are careful clients, they will heed warnings;
> if just using warnings is not practical, then what are the careful clients
> doing?
>

I actually share the optimism here. I think it's workable for careful
clients, and I wouldn't hold 0-RTT hostage to the DKG corner case. I think
we should ship it. All I'm trying to get at is that separate streams are
needless complexity, and they seem to be getting ignored by implementors
anyway.

Right now there's a very weird take in the draft: let the server figure it
out by marking the data as replay-able. Well actually that doesn't work; on
the server side, the sections can't always be correlated, and even if they
were an application would still need its own anti-retry strategy. It's
well-meaning; but doesn't work. We should take it out.

Here's an example. Client has two tickets: AA and BB.

T1. Client makes 0-RTT request for /foo/ with ticket AA. Servers receives
the request and marks as replayable-data, maybe uses AA to derive a
convenient idempotency/anti-replay key (like the X- header trick).

T2. Client was blocked, Tries again, doesn't re-use the ticket, per the
draft. So repeats with 0-RTT again, with ticket BB. Same as before, except
now the key is derived from BB.

T3. Client tries again, this time over 1RTT. Per the draft, there's *no*
signaling of repayable data.

What on earth is a server side application suppose to do with this sequence
of events? None of these 3 requests can be correlated, unless the
application author added their own key ... in which case they don't need
any of this TLS-layer stuff.

Some applications mitigate this kind of problem client side, what I'm
pointing out there is that to work robustly, then a client needs to 1) know
about the 0-RTT failure, 2) know for how long the 0-RTT request may be
replayed.  With that small modification; a client can actually repair
failures too.

So if we want to fully mitigate DKG attacks, I think it is useful to hard
> cap the replay, say that it MUST be at most 10 seconds. And then worst
> case, a client that needs to be careful can wait 10 seconds. Note that the
> TLS implementation can do this on the client's behalf, by inserting a
> delay. Of course that means that for these kinds of applications, this
> means that 0-RTT delivers speed most of the time, but may occasionally slow
> things down by 10 seconds. I think that's an ok trade-off to make for
> backwards compatibility.
>
>
> Again, does this need to be in the TLS implementation or can the (careful)
> application do it?
>

I don't think a careful application can do it without a hard-cap; otherwise
a zombie write could come along at any time and invalidate its state.

That's one reason why the review suggests something else too:  just lock
> careful applications out, but in a mechanistic way rather than a "good
> intentions" way, by having TLS implementations *intentionally* duplicate
> 0-RTT sections.
>
>
> Err, regularly locking out careful applications is supposed to be a good
> thing?
>

Well, it locks out the careless ones, so yes ime, same as GREASE really :)


> (Again, the mandatory 10-second delay on 0-RTT rejection introduces huge
> processing time variance, which is a no-go in some environments.)
>

It needn't be mandatory; just the default. A careful client could do as
you're suggesting; handle this at a different layer.

-- 
Colm