Subject: [TLS] A (somewhat) comprehensive proposal for the handshake

From: Watson Ladd <[email-masked]>
Date: Sun, 22 Jun 2014 17:05:12 -0700

Dear all,

I'm writing this to put forward a (somewhat) comprehensive view of how
we can deliver on the promises in the charter, while making sure we
don't have the sort of security problems as before, and making it easy
to support TLS 1.3 in clients and servers that already support TLS
1.2.

My view is the best way forward is to have TLS 1.3 consist of two
extensions to TLS 1.2: one signalling a change to the key derivation
and Finished Messages, the second signaling a guess as to the
ciphersuite and curve to be negotiated, along with the
ClientKeyExchange.

The guess is conceptually easier to describe: it contains the
ciphersuite, the curve that will be picked, and a "point on the curve"
(aka DH value). If the server accepts the guess it sends back this
extension, if it doesn't accept the guess (because it wants a
different ciphersuite or curve) it doesn't send back the extension.

The changes signalled by the first extension are as follows: The
ciphersuite contains a PRF I will call H. At each message we have
H(script), a hash of the transcript of sent messages. We set the
master key at the earliest possible point, namely after the DH values
have been exchanged to H( hlen || H(script) || hlen || H(g^a, g^b,
g^ab) || opt_in_len || opt_in). (Server random and client random are
in the script, opt_in is optional data for channel binding purposes
like renegotation_info or handshake obfuscation). (Yes, I would have
prefered going from {{0,1}*}*->{0,1}^n)

H(script) is used to salt the server signature of its group element.
If we want to protect against clients with bad random number
generators from being fooled we might need to add server_random also.

>From this channel keys are derived as usual. (This might go badly with
resumption: maybe this needs to be rethought)

The Finished message contains a confirmation key H( master_key_len ||
master_key || "client confirm") for the client or "server confirm" for
the server. It's not sent encrypted: the ChangeCipherSpec comes
immediately afterwards. (Yes, you can have a half-encrypted channel at
some stages during the handshake)

Why is this secure? Go to the ROM, and we see that the key derived
from the handshake is a function of the handshake values that is
injective. With a bit more work we see active intervention earns the
attacker nothing, so what is left reduces to DH security. Assume
server_random is unique, and you get anti-replay. I've not formalized
this intuition.

Client authentication has to come after the finished message, but this
is easy: sign a value extracted from the master_secret. Resumption
tickets need to be set in a message after the key is derived. This
proposal is orthogonal to handshake obfuscation.

For the ZRT transport I have no idea.

Sincerely,
Watson Ladd