Subject: [TLS] HelloRetryRequest and stateless reject

From: Eric Rescorla <[email-masked]>
Date: Wed, 21 Oct 2015 10:32:59 -0700

Folks,

Several of the remaining TLS 1.3 issues have to do with the
ClientHello/HelloRetryRequest interaction. To recap, if the
ClientHello does not contain a KeyShare with an acceptable group, the
server sends a HelloRetryRequest indicating the correct group,
and the client sends a ClientHello with the correct group:

         Client                                               Server

         ClientHello
           + KeyShare              -------->
                                   <--------       HelloRetryRequest

         ClientHello
           + KeyShare              -------->
                                                         ServerHello
                                                          + KeyShare
         ...

DTLS has a very similar mechanism where the server provides a
HelloVerifyRequest containing a cookie in order to force the client to
provide proof of routabilty at its claimed address. The client
re-sends the ClientHello with the cookie and the handshake restarts.

It seems natural to try to merge these mechanisms, but this raises
the question of whether the handshake hashes should continue through
the rejection exchange (https://github.com/tlswg/tls13-spec/issues/104).
The tension here is that you want to be able to have a stateless
rejection (to avoid DoS in the DTLS scenario) but having things
makes it much harder to analyze the handshake's resistance to
downgrade attacks.

Recently, Karthik, Martin Thomson, and I were talking and I think we've
come to a good resolution. The basic observation is that it's possible
to continue the handshake hash through the rejection exchange while
still being stateless. We are aware of two main techniques here:

- The server offloads its handshake hash state into the cookie
  it provides in the HelloRetryRequest (we'll need the cookie here
  in any case to support the DTLS case. The cookie obviously needs
  to be cryptographically protected, but that's what you're supposed
  to do for DTLS anyway
  (see: https://tools.ietf.org/html/rfc6347#section-4.2.1)

- The server reconstructs the original ClientHello and HelloRetryRequest
  based on the re-sent ClientHello. This is possible because there are
  very strict rules about re-sent ClientHello construction
  (namely: send the same ClientHello except just add a KeyShareEntry
  for the indicated group). The cookie should also allow the server
  to double-check this (and will also need to indicate the reason
  for rejection).

Because the handshake hash is continued through the entire handshake,
it's much easier to analyze the downgrade properties. Moreover,
servers which don't need stateless reject (because there is some
other connection construct as with TLS over TCP or DTLS with
ICE) don't need either of these techniques. They can just continue
the handshake hash in the usual way.

This seems like it fulfills both imperatives, at the primary cost of
some additional complexity on servers who really care about
statelesness (the client is indifferent to the server's implementation
strategy).

If this sounds good to people, I'll work up a PR for this, but
really all it is is saying that you don't reset the hash and
then a non-normative appendix describing stateless implementation
techniques.

Thoughts? Does anyone see anything wrong with this?
-Ekr

---

From: Benjamin Kaduk <[email-masked]>
Date: Wed, 21 Oct 2015 13:07:38 -0500

On 10/21/2015 12:32 PM, Eric Rescorla wrote:
> the rejection exchange (https://github.com/tlswg/tls13-spec/issues/104
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_issues_104&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=ixsUSZ7qRqak0aUyXIFg-hbcXSe9ew3ZditMZBPS3dU&s=dDAwXMVbdm5TPHBOtcEHi49G8ja7gy3s2EcAqUg9La8&e=>).
>   (see: https://tools.ietf.org/html/rfc6347#section-4.2.1
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_rfc6347-23section-2D4.2.1&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=ixsUSZ7qRqak0aUyXIFg-hbcXSe9ew3ZditMZBPS3dU&s=cEa44t6zPucquN3jUqQvxlC8-wwzKckAc4Itu1pwyps&e=>)
>

It sounds like a good plan.  The only thing that comes to mind is
whether a server might want to use encrypted (and MACd) serialized state
instead of an HMAC'd blob for the cookie where it would have to
reconstruct state from the re-sent ClientHello.  (It should be easy to
have text that allows for either case; I just wanted to mention it as a
possibility.)

-Ben

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 21 Oct 2015 11:12:27 -0700

On Wed, Oct 21, 2015 at 11:07 AM, Benjamin Kaduk <[email-masked]> wrote:

> the rejection exchange (
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_issues_104&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=ixsUSZ7qRqak0aUyXIFg-hbcXSe9ew3ZditMZBPS3dU&s=dDAwXMVbdm5TPHBOtcEHi49G8ja7gy3s2EcAqUg9La8&e=>
> https://github.com/tlswg/tls13-spec/issues/104).
> It sounds like a good plan.  The only thing that comes to mind is whether
> a server might want to use encrypted (and MACd) serialized state instead of
> an HMAC'd blob for the cookie where it would have to reconstruct state from
> the re-sent ClientHello.  (It should be easy to have text that allows for
> either case; I just wanted to mention it as a possibility.)
>

Yes, this also seems like a good alternative.

Best,
-Ekr

-Ben

---

From: "Short, Todd" <[email-masked]>
Date: Wed, 21 Oct 2015 18:13:11 +0000

I like the idea. If the functionality is to be merged, perhaps harmonizing the names and contents of the messages (if possible)?
--
-Todd Short
// [email-masked]<mailto:[email-masked]>
// "One if by land, two if by sea, three if by the Internet."

On Oct 21, 2015, at 1:32 PM, Eric Rescorla <[email-masked]<mailto:[email-masked]>> wrote:

Folks,

         Client                                               Server

         ClientHello
           + KeyShare              -------->

         ClientHello
           + KeyShare              -------->
                                                         ServerHello
                                                          + KeyShare
         ...

the rejection exchange (https://github.com/tlswg/tls13-spec/issues/104<https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_issues_104&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=qs-tzs_SwwiU6AH8Y7_q_TnVqYX4ruwLo5qqkgP8HDw&s=o3UsBAmOLmYeA_GnNYIEo3Ila7mxSbS5EkfOOuVR4dY&e=>).

  (see: https://tools.ietf.org/html/rfc6347#section-4.2.1<https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_rfc6347-23section-2D4.2.1&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=qs-tzs_SwwiU6AH8Y7_q_TnVqYX4ruwLo5qqkgP8HDw&s=FqKoPI3ZlKRELrbW0Jr1_9Vs29f-gFLX0bVRoOy3rJk&e=>)

Thoughts? Does anyone see anything wrong with this?
-Ekr
_______________________________________________
TLS mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/tls

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 21 Oct 2015 11:17:10 -0700

On Wed, Oct 21, 2015 at 11:13 AM, Short, Todd <[email-masked]> wrote:

> I like the idea. If the functionality is to be merged, perhaps harmonizing
> the names and contents of the messages (if possible)?
>

Yes. My plan is to name it HelloRetryRequest and get rid of
HelloVerifyRequest.

-Ekr

> // [email-masked]
> On Oct 21, 2015, at 1:32 PM, Eric Rescorla <[email-masked]> wrote:
>
> Folks,
>
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_issues_104&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=qs-tzs_SwwiU6AH8Y7_q_TnVqYX4ruwLo5qqkgP8HDw&s=o3UsBAmOLmYeA_GnNYIEo3Ila7mxSbS5EkfOOuVR4dY&e=>
> ).
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_rfc6347-23section-2D4.2.1&d=CwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=qs-tzs_SwwiU6AH8Y7_q_TnVqYX4ruwLo5qqkgP8HDw&s=FqKoPI3ZlKRELrbW0Jr1_9Vs29f-gFLX0bVRoOy3rJk&e=>
> )
>
> [email-masked]

---

From: Ilari Liusvaara <[email-masked]>
Date: Wed, 21 Oct 2015 22:29:17 +0300

> Yes. My plan is to name it HelloRetryRequest and get rid of

Bit crazy idea: Have vector of causes handshake went wrong
(e.g. required share missing, cookie required). Then the
client verifies that that:
- There is at least one cause
- All causes are known (can't retry with unknown error)
- All causes are proper (e.g. actual missing share).

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Wed, 21 Oct 2015 12:35:51 -0700

> - All causes are proper (e.g. actual missing share).

The client doesn't need this information, though the server might.
That is, if it doesn't want to try several options to see which one
passes the MAC, noting that there aren't that many options.  Given
that, I don't think we need to specify anything.

Note that absence of cookie is the only valid starting state, so you
don't need a bit for that.

---

From: Ilari Liusvaara <[email-masked]>
Date: Sun, 25 Oct 2015 17:35:12 +0200

> it's much easier to analyze the downgrade properties.

It is not just resistance to downgrade on protocol level. It is also
resistance to downgrade at implementation level. Which is nastier
to analyze.

(I found three different ways[1] to potentially cause downgrades against
careless implementaions, continuing hashes stops all of those).

> Thoughts? Does anyone see anything wrong with this?

Sounds good to me. Combines the resistance to downgrade continuing
hashes offers with the possibility of being stateless (for DTLS).

Aside: Has anyone looked at making DTLS 1.3? I would think the main
issue to look at would be how to arrange retransmissions (especially
with things like 0-RTT data, encrypted handshake and final handshake
flight).

[1] 
1) Tamper with ClientHello so server generates HRR causing the client
   to downgrade.
2) Tamper with HRR to cause the client to downgrade.
3) Insert ClientHello causing server to latch weak parameters, eat
   the HRR and replay ClientHello.

-Ilari