Subject: [TLS] Resumption Contexts and 0-RTT Finished

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 19 Jul 2016 16:46:26 +0300

Thinking about this...

One option would be like 2 on the slides (the overstriked one!), except:

- The message is synthethized, not actually sent on wire (but still
  logged).
- It only happens after the last ClientHello.
- It uses the actual PSK, even if not #0.

Maybe I should have listened to the talk more carefully, but the
reason I got for overstriking the second option was that it is
unimplementable in practice.

Of course, dunno if the changes would actually fix the problems
with PSK contexts...

-Ilari

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 19 Jul 2016 16:40:38 +0200

The problem with the second option is that it's not safe to send the 0-RTT
Finished on the wire if you don't know that the other side is 1.3; that's
an assumption we made about 0-RTT but not one we want to make for
PSK-resumption.

-Ekr

On Tue, Jul 19, 2016 at 3:46 PM, Ilari Liusvaara <[email-masked]>
wrote:

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

---

From: "Antoine Delignat-Lavaud" <[email-masked]>
Date: Tue, 19 Jul 2016 16:45:01 +0200

Dear all,

Here is an extended summary of the early Finished / resumption context
discussion at the WG.

1. Signature forwarding with external PSK

Currently, resumption context is only defined for resumption-based PSK,
which means that external PSKs are not protected against transcript
synchronization attacks.

At a high level, this means that there is no crypographic binding between
the handshake log (what is signed for authentication) and the PSK used in
the key exchange.
In the resumption case, the resumption context fills this role (which is the
reason why it was introduced); however, all external PSKs currently have
their resumption context set to 0 (and thus, all logs are equivalent w.r.t.
all non-resumption PSK).
Since the handshake log is what get signed during certificate-based
authentication, the lack of binding
means that a signature from a session s1 can be used in a session s2 as long
as the PSK identifier are the same, which is a very weak constraint.

Before Cas Cremer's paper, this was particularly bad because the Finished
(which is bound cryptographically to the PSK) was not part of the handshake
log; therefore, all signatures could potentially be replayed.
However, even though Finished are now part of the log, the server signature
in PSK 1-RTT remains vulnerable (because the log is then ClientHello,
ServerHello, Certificate and thus has no Finished message to save us from
transcript synchronization). For those of you who were at TRON, you may
remember that Karthik made this point quite clearly in his talk (he even
proposed to swap CV and Finished for this very reason!).

An attack against external PSKs easily follows: we assume that an attacker A
wants to impersonate a server S to some
IoT-like client C that can only do pure PSK for key exchange. 

1. C registers to A under the PSK identifier Xc. The PSK between C and A is
Kca
2. A, acting as a client, registers to S under the same identifier Xc. The
PSK between A and S is Kas
3. C connects to A using (Xc, Kca). A forwards the ClientHello to S
4. S sends back ServerHello, [EE, Cert(S), CertVerify, Finished]_hs where hs
depends on Kas and the log [ClientHello, ServerHello]
5. A forwards ServerHello from S to A and re-encrypts [EE, Cert(S),
CertVerify] under hs' which depends on Kca and [ClientHello, ServerHello]
6. Since all logs are synchronized and nothing in the CertVerify depends on
Kca or Kas, C authenticates A as S.

2. Proposals to bind log and PSK

As pointed out by Karthik months ago (and by myself years ago, in the
context of Triple Handshake), implicit authentication (such as PSK or
resumption) is difficult to mix correctly with transcript-based signatures.

We have considered several ways to ensure uniform security for all PSK
modes.
The simplest solution (let's call it option A) is to rely on the draft 13
resumption context infrastructure also in the case of external PSK.
Put it simply, externally-provided PSKs are treated as if they were
resumption master secrets: if K is the external key, we first compute
Ek = extract(K, 0), then PSK=expand(Ek, "external psk") and RC=expand(Ek,
"external psk context").
Resumption context is renamed PSK context and PSK and RC are used as in the
current draft13 key schedule.

While option A does the job, we think it is over-complicated, as we observe
that the early finished can actually play exactly the same role as the
current resumption context (saving the concatenation with rc in every
expansion with an handshake log).

As an option B, we propose to always include an early finished in the log,
regardless of the handshake mode.
This comes with some complications that were discussed during the WG
meeting. Very notably, if this early finished is assumed to always come
after the ClientHello, then it must either a. mangled with the ClientHello
in an ugly way or b.send on the wire at all.
During the WG meeting, it was pointed out that regardless of whether a or b
is used, if the client proposes more than
one PSK, there needs to be more than one early finished.

I have thought more about this, and I now agree that this makes option B
unpractical.
We are left with some more options: one would be to swap CertificateVerify
and Finished, as Karthik originally suggested.
Another would be to have a Finished immediately after ServerHello. Neither
of these alternatives is particularly appealing,
and it may be the case that option A is in fact the better choice.

Best,

Antoine

-----Original Message-----
From: TLS [mailto:[email-masked]] On Behalf Of Ilari Liusvaara
Sent: mardi 19 juillet 2016 15:46
To: [email-masked]
Subject: [TLS] Resumption Contexts and 0-RTT Finished

Thinking about this...

Maybe I should have listened to the talk more carefully, but the reason I
got for overstriking the second option was that it is unimplementable in
practice.

Of course, dunno if the changes would actually fix the problems with PSK
contexts...

-Ilari

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 19 Jul 2016 17:24:23 +0200

> Here is an extended summary of the early Finished / resumption context
Thanks for writing this up!

> as the PSK identifier are the same, which is a very weak constraint.

Note that this form of PSK + server signature isn't a mode we currently
specify
in TLS 1.3  However, given that the negotiation changes we discussed today
would in fact enable it, it seems like that would be something that's good
to fix
now.

> current draft13 key schedule.

I think this is the best option at this point.

-Ekr

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 19 Jul 2016 19:37:32 +0300

On Tue, Jul 19, 2016 at 04:45:01PM +0200, Antoine Delignat-Lavaud wrote:
> transcript synchronization).

Oh yeah, that.
 
> one PSK, there needs to be more than one early finished.

What about never sending it on the wire but still having it in hash just
before ServerHello, using the actually used PSK key and PRF and logically
sent by the client.

Placing it before SH instead of after CH is because of interactions with
restart/0-RTT. The logical sender matters for DTLS (uses message number
on which side?).

Pros:
- Binds PSK into the log (dealing with the attack above)
- Friendly to TLS 1.2 servers.
- Can be made up on the spot, no need to compute multiple, no need to
  speculate (even if speculating on PSK).

Cons:
- Special case of message being hashed that doesn't appear on the wire,
  no percedent for this (only hs messages on wire not appearing in
  logs).
- Can't be easily included in 0-RTT keymat. But then, seems kinda
  pointless to include it, as 0-RTT keymat already depends on all the
  same inputs (PSK#0 and CH).

Of course, no idea just how nasty implementing this in various TLS
stacks would be... Could be very nasty...

-Ilari

---

From: Hugo Krawczyk <[email-masked]>
Date: Wed, 20 Jul 2016 01:42:58 -0400

Without taking a position on the implementation issues, I am in favor of
Option A with a dedicated context value (and an explicit name "PSK
Context") as this makes clear the function of this value. Relying in
Finished makes it more fragile and open to be dropped in the future when
its binding role is "forgotten" or when deriving some other protocol or
variant.

Also, I insist on the need to remark about the need for collision
resistance of any value with a binding functionality. If this value is
produced with HKDF (or HMAC as in he case of Finished) the need for
collision resistance is not explicit and can lead to truncation (which is
perfectly fine when just deriving keys or when used with a regular PRF
functionality).

Actually, I would suggest that for any such value, we add "collision
resistance" to the label for that derivation - this would apply to
resumption/PSK context and to Exporter key (and possibly others)

Hugo

---

From: Benjamin Kaduk <[email-masked]>
Date: Wed, 20 Jul 2016 10:16:53 -0500

> resumption/PSK context and to Exporter key (and possibly others)

Seems reasonable; space in the label is relatively cheap.

-Ben

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 21 Jul 2016 10:12:17 +0300

> its binding role is "forgotten" or when deriving some other protocol or

Furthermore, I think that there are only two ways to do the kind of
binding required that aren't fatally flawed (as far as I know) in some
way.

One is ADL's "Option A", and the other is implicit variant of "Option B"
I came up with. Both are ugly.

I think ADL's "Option A" is easier to implement (no need to mess with
Finished generation).

I also think that the 0-RTT Finished message should be removed (as
suggested before by one of the "crypto guys", I forgot who). It
is major implementation problem, and doesn't seem to even provode any
security.

> perfectly fine when just deriving keys or when used with a regular PRF

The properties that HKDF and HMAC actually provodes here:

If the base hash is CR and has output length at most blocklength,
then...

- HMAC is CR w.r.t. its message input.
- If the HMAC key is of constant length, the HMAC is CR w.r.t. its
  key.
- HKDF-Extract is CR w.r.t. its key input.
- If the salt is of constant length, HKDF-Extract is CR w.r.t. its
  salt.
- If length is at least one hash output, HKDF-Expand-Label is CR
  w.r.t. its label.
- If length is at least one hash output, HKDF-Expand-Label is CR
  w.r.t. its hashvalue.
- If length is at least one hash output and secret is of constant
  length, HKDF-Expand-Label is CR w.r.t. its secret.

These all can be shown by supposing an counterexample, and showing
that it inevitably follows that the base hash is both CR and not CR
at the same time, which is not possible.

(Conviniently, all length constraints are currently always met).

> resumption/PSK context and to Exporter key (and possibly others)

<bikeshed>
I suggest appending ", collision resistant".
</bikeshed>

(E.g. "TLS 1.3, exporter master secret, collision resistant", after
fully expanding the label)

-Ilari