Subject: Re: [TLS] 0-RTT and Anti-Replay

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 6 Apr 2015 15:05:54 +0300

On Sun, Mar 22, 2015 at 02:49:28PM -0700, Eric Rescorla wrote:
> In the interim in Seattle, we had an extensive discussion of 0-RTT
> anti-replay in which DKG observed that all the proposed anti-replay
> mechanisms provide limited protection. The underlying problem is the
> desire to present a uniform interface in which the calling application
> can count on reliable delivery of the data it provides in the first
> flight, thus requiring the TLS stack to retransmit it automatically.

[...]
 
> The other two options clearly require a separate API to handle this
> special first-flight data and would require applications to handle it
> separately. So, for instance, in option 2, you would have something
> like:
> 
>     c = new TLSConnection(...)
>     c.setReplayable0RTTData("GET /....")
>     c.connect();

This is on client side, but how about server side?

1)

- Server app indicates to TLS stack if it supports 0RTT.
- If no support or 0RTT fails, 0RTT is refused and retransmitted
  data is prefixed into connection data.
- If supported and 0RTT transmission succeeds, app can read 0RTT
  data using separate call.

Problem: 0RTT supported but failing (e.g. wrong keys) is a special
case for serverside.

2)

- Server app indicates to TLS stack if it supports 0RTT.
- If no support, this is signaled to client.
- If supported but fails, this is signaled to client.
- 0RTT data (original or retransmit) is read using separate
  interface.

Problems: 0RTT supported/not supported is two different cases
for the client. Retransmit would need to be flagged specially.

3)

- If 0RTT fails or not supported, it is refused.
- Just prefix 0RTT data into connection data.

Prolem: Server can't tell apart 0RTT data from normal data.

Also, regarding security considerations due to replayability, would
"MUST NOT authenticate in 0RTT data" (which e.g. means cookies that are
possibly authenticating can't be sent)  be useful consideration?

-Ilari

---

From: Watson Ladd <[email-masked]>
Date: Mon, 6 Apr 2015 22:38:18 -0700

> possibly authenticating can't be sent)  be useful consideration?

Only if we don't guarantee that the person who sent the 0-RTT data is
the same person who carries out the rest of the connection. This seems
possible, but I don't know what the right definition is.

>
>
>
> -Ilari
>
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

-- 
"Man is born free, but everywhere he is in chains".
--Rousseau.

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 7 Apr 2015 09:10:55 +0300

> possible, but I don't know what the right definition is.

The problems here are:
- 0RTT data is replayable (seems there's no way around).
- You can't wait for confirmation (connection reaches normal application
  data capability in 1RTT).

Also, in order to client replaying 0RTT not be able to negotiate
with replayed 0RTT data, one needs client finished type message, or
0RTT key needs to mixed into session key[1] + encrypted message
from client.

The corresponding consideration in server earlydata is "MUST NOT be
confidential.", since it is sent to unknown recipient.

[1] "unified DH-based key exchange" does not get this right, this
input is independent from ES input in late key exchange.

-Ilari

---

From: Ilari Liusvaara <[email-masked]>
Date: Sun, 12 Apr 2015 19:55:42 +0300

> flight, thus requiring the TLS stack to retransmit it automatically.

I thought about 0-RTT some more, here are some questions. Few
might be protocol-relevant, most are only about guidance.

1) What is the recommended 0-RTT API model on server side
   (also consider server apps or app implementations that don't
   support 0-RTT)?
2) What are the semantics of successfully received 0-RTT transfer
   (especially considering the client-side autoretransmit on
   failure)?
3) How does 0-RTT interact with ALPN (especially considering
   potential for multiple protocol candidates)?
4) Can handshake with attempted 0-RTT be securely downgraded to
   v1.2 (obviously causes the 0-RTT to fail)?
5) There is potential footgun if 0-RTT is used with (DH-)PSK: The
   PSK authenticates the connection immediately, but 0-RTT is
   as replayable as ever. What to do with that?
6) The same as above, but when attempting to resume a session.
   with a client certificate (since cc is property of session)?
7) What guidance to give regarding what data can be put to 0-RTT,
   considering its replayability?
8) If resumption attempt has 0-RTT data, what keying material is
   used for the 0-RTT?
9) Can server roll over its 0-RTT keys without waiting for the
   previous ones to expire?
10) How is attacker establishing a session (or at least decoding
    server's first application flight) replaying captured
    0-RTT data prevented (since that could leak quite a bit of
    info about what's in 0-RTT blob)? Or not?

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Apr 2015 10:02:43 -0700

This would have to be similar to the client one, which if you recall was either:

    client.addReplayableData(replayable);
    client.connect();

or:

   client.addUnreliableData(unreliable);
   client.connect();
   client.onunreliabledatalost = () => tls.send(unreliable);

You would have to have the server opt in either with:

   server.enableReplayableData(true);
   server.accept(443);

or:

   server.onunreliabledata = data => { /* handle it */ }
   server.accept(443);

I hope my javascript isn't too obtuse.

This is protocol-defined.

But I imagine that this depends on the model we employ.  Replayable
data could just be consider the start of a stream.  On the other hand,
unreliable data doesn't work very well for a stream mode.  Conversely,
replayable data makes no sense in a datagram mode, but all data is
unreliable there.

I imagine that the ALPN from the previous session applies.  If the
client wants to change anything, it probably shouldn't use 0-RTT. Note
that this includes cipher suites and maybe other extensions too.

Not safely.  The decision we made at the last meeting (or interim, I
can't remember) was to require that the server make a commitment to
support - or at least to ignore - TLS 1.3 handshake for at least the
validity period of the 0-RTT information.  The 0-RTT messages might be
ignored in DTLS, but they are unlikely to be handled cleanly by a TLS
1.2 implementation.  I would expect a fatal error.

How is that materially different to other suites?

As before, if the information is replayable, then it needs to be
understood by both parties that it is replayable.  And both need to
understand how that is not a concern.  The client certificate doesn't
present a special risk here.  At least not as far as I've been able to
determine.

What guidance do you want?  It's replayable.  If it causes something
to happen that you don't want to have happen twice (or more), then
don't use 0-RTT.

   used for the 0-RTT?

That combination might not be valid.  If it is, I'm guessing that the
first client flight is encrypted and authenticated as a "normal" 0-RTT
handshake.

   previous ones to expire?

Yes, there will need to be a key identifier in the clear that allows a
server to identify which key to use to decrypt the client's flight.

Well, the attacker presumably doesn't have the private keys used by
either client or server.  They might be able to cause a replay, but if
we have decent crypto, they aren't able to decrypt anything, nor can
they continue the session.

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 13 Apr 2015 21:11:44 +0300

> replayable data makes no sense in a datagram mode, but all data is

I thought the recommended client-side interface called for auto-
retransmit, which would mean that if application handled 0RTT as anything
else than a prefix, it would now create two cases serverside.
 
> that this includes cipher suites and maybe other extensions too.

You mean 0-RTT "KeyIDs" include the application? Note that ALPN is one
of the very few extensions that is not invariant across resumption
(might even be the only one that isn't resumption mechanism itself).

Or guidance that one is to send at most one ALPN identifier if trying
to send 0-RTT data?

Also, there's the case 0-RTT is attempted without resumption. Or is
0-RTT intended only for session resumption attempts (which would cut
quite a bit of complexity)?

> 1.2 implementation.  I would expect a fatal error.

There's the case where there are multiple servers behind a load-
balancer (working at TCP or even IP level).

Inability to gracefully fall back would imply that all servers serving
something need to be upgraded at once.

> present a special risk here.  At least not as far as I've been able to

Yeah, shouldn't be exploitable unless the client sends really dumb
things in 0-RTT data.

> first client flight is encrypted and authenticated as a "normal" 0-RTT

One can't attempt resumption with 0-RTT data?

Also, if session is resumed, I think the server won't appreciate having
to decode "normal" 0-RTT data transmission, since that is relatively
expensive operation (much more expensive than symmetric decryption of
reasonable amounts of data).

There are three possible cases with respect to resumption:
1) Client does not try to resume (full handshake)
2) Client tries to resume, resume failed (fallback to full handshake).
3) Client tries to resume, resume successful (abbrevated hanshake)

> server to identify which key to use to decrypt the client's flight.

OK (just that one knows that key exchange needs to deal with that case).

> they continue the session.

If one does 0-RTT with resume, then sure. But 0-RTT without resumption,
it depends on specifics of the key exchange if that kind of attack
is possible or not.

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Apr 2015 11:24:13 -0700

> else than a prefix, it would now create two cases serverside.

That retransmit doesn't make sense in DTLS.  I believe that the
current situation is "replayable in TLS", "unreliable in DTLS".

> (might even be the only one that isn't resumption mechanism itself).

They probably need to include the application and more.

> Or guidance that one is to send at most one ALPN identifier if trying

I wouldn't do that: if the 0-RTT state is rejected, then protocol
negotiation is still possible.  I would instead recommend that both
peers remember(or encrypt) certain state to the key identifier and use
that state.

> quite a bit of complexity)?

I don't know how this is intended to work, but I always think of 0-RTT
as resumption.  Nothing much else makes sense.

> something need to be upgraded at once.

Yes, all servers in that farm would need to be upgraded at least to
the level that they would be able to ignore the TLS 1.3 garbage.
Before allowing any node to enable 0-RTT.

> One can't attempt resumption with 0-RTT data?

I don't actually know the answer to this.

> reasonable amounts of data).

The server decided to allow that possibility; so it has to deal with
the fallout from it.

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 13 Apr 2015 22:17:33 +0300

> I don't actually know the answer to this.

There are three kinds of ClientHellos:
1) Those that attempt resumption (session-id or session-ticket)
2) Those that don't (no session-id, no session-ticket).
3) Some new type that doesn't currently exist (I presume TLS 1.3 won't
   add one).

Is attempt to send 0-RTT data allowed with 1)? With 2)?

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Apr 2015 12:30:04 -0700

> Is attempt to send 0-RTT data allowed with 1)? With 2)?

You assume that 0-RTT doesn't fall into that third category.  I hadn't.

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 13 Apr 2015 22:46:05 +0300

> You assume that 0-RTT doesn't fall into that third category.  I hadn't.

Well, the only examples of 3) I can come up with would be
- Resumption-only (fail enteriely if not resumable)
- Something possibly triggering some new type (neither 1RTT, 2RTT
  nor abbrevated) of handshake.

Of course, I then have trouble even thinking what such new type
of handshake could be.

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Apr 2015 12:57:51 -0700

> Of course, I then have trouble even thinking what such new type

Well, 0-RTT could be a third category.  As Hugo originally proposed
it, this would have the authentication of the connection be based on
successfully proving the ability to generate g^xy.  That's stronger
than resumption, but relies on the authentication of a previous
session in the same way that resumption does.  You might consider that
to be resumption, or not.

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Mon, 13 Apr 2015 16:59:53 -0400

> else than a prefix, it would now create two cases serverside.

Just because the data is replayable doesn't mean that it is replayable
*in the same stream*.

For TLS over TCP, both sides of the stream should be able to model the
state of the other side of the connection in a way that the next piece
of data sent depends on the understanding being correct.

If we decide that the client will auto-retransmit the payload, that
means that an attacker could cause *a second stream* to start in the
same way, not that the existing stream might or might not have the
initial payload loaded twice.

        --dkg

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 14 Apr 2015 08:46:06 +0300

> to be resumption, or not.

I don't consider that to be resumption, since asymmetric crypto is
involved (the whole point of resumption is to avoid asymmetric
crypto).

And furthermore, I don't think it is worth the trouble to introduce
a different kind of handshake for 0RTT case.

I think the idea was (for non-resumption) to derive the 0RTT key from
DH result of client exchange key[1] (possibly with PSK) and cached medium-
term server key.

For resumption, one could derive the 0RTT key from resumption PMS.

The trouble with actual session resumption attempts comes from the fact
that these derive different keys (and at least in threat models I use,
one can't assume key wrapping works).

[1] To prevent that "replay and connect" attack mentioned previously,
either this has to be the actual client exchange key (there can be only
one), key exchange gets complicated since there is now a conditional
input or server can't roll its keys properly.

-Ilari