Subject: [TLS] Single round trip abbreviated handshake

From: Ravi Ganesan <[email-masked]>
Date: Tue, 2 Feb 2010 20:12:08 -0800

Hi,

I was hoping to make an RFC out of this with those in this list who
think alike and then post, but since the discussion has started
thought I'd join in the fun and  send on this link below.

http://www.safemashups.com/downloads/Optimizing_the_SSL_and_MashSSL_Handshakes.pdf

Basically, we ran into the 'ssl handshakes need at least two
roundtrips' about a year ago in our work in MashSSL (see
www.mashssl.org). Almost all MashSSL handshakes will be "abbreviated
handshakes" (aka session resumption), and since our "transport" was
HTTP, we were in the awkward position of having to do two HTTP
requests to complete the handshake.  This is awkward for us not just
from a latency perspective, but it would be very nice if the initial
request came with all the information needed for the Server to figure
out who is on the other end. (e.g. a cross domain XHR request).

So here is what we came up with. The abbreviated handshake is:

C   ->  Client Hello (including client-random and unix_gmt)  -> S
(neither party know who is at other end at this point)

C   <-   Server Finished (including server-random and unix_gmt)  <- S
(client has auth server at this point)

C   ->  Client Finished     -> S
(only now does server authenticate client)

If we want to reduce this to a single round trip, then the C needs to
send the Client Finished in first message.
BUT the Client Finished depends on the server-random and unix_gmt
response from S which C does not know.

So the idea is for the C to SUGGEST a server-random, and if the S
accepts the suggestion then for the S to use the suggested
server_random and the same unix_gmt as sent by the C (after ensuring
it is within some range; hence loose clock synchronization).

Now, having the counter party in an auth protocol suggest which
'random' number you should use is on the surface utterly preposterous.
 So I went about trying to understand WHY we have these random numbers
in the abbreviated handshake (keep in mind that at this point both
sides have a shared master_secret). The SSL history here was not
entirely clear, but if you see the Schneier and Kocher papers from
that time you can start trying to reconstruct the rationale for them.
And, my analysis was that you can get away with not having the
server-random be truly random, as long as you constrain it.

Anyway, after weighing the unknown RISK introduced against the HUGE
benefits for reducing the number of round trips, our thinking is that,
different apps should be allowed to make different decisions on the
risk/reward trade-off.

(i) the Client should be able to SUGGEST (in an extension) that the
Server use a particular server-random, and then send along the
client-finished optimistically assuming the Server will cooperate.
(ii) the Server can be nice and cooperate, or coldly ignore the Client
and respond as if the extension was not there (taking care either way
to construct the running hashes with only the appropriate messages).

As protection one does not want to let the Client suggest ANY
server-random. Rather, we probably limit attacks (if any) caused by
this model, by setting server-random = function(client-random,
unix_gmt).

Adam/Google was going down this road independently. Adam has suggested
server-random = function(client-random, unix-gmt, epoch) where last
value is derived from Server cert.

Adam has also suggested this can work for full handshake as well. In
the rough paper I reference above we actually considered that
possibility but to put it bluntly 'chickened out'.

(and yes the backing out of data sent etc., reversing change cipher
specs, etc. is not elegant, but its ok if the plumbing looks ugly as
along as it works real fast...!)

If you truly hate this thinking I suspect you will say so; but then do
also consider proposing an alternative. I think the world NEEDS a one
round trip abbreviated handshake (and perhaps to Adam's point, a full
handshake also).  We can either meet that need within the umbrella of
the TLS we know and love, or else the world will eventually come up
with a completely new alternative which will not take advantage of the
15 years of SSL analysis and the SSL trust infrastructure. I am not
sure why latter is better alternative.

Cheers,

Ravi

---

From: Adam Langley <[email-masked]>
Date: Wed, 3 Feb 2010 06:40:38 -0500

> value is derived from Server cert.

At the moment, OCSP disk caches and OCSP stapling are the low hanging
latency fruit, but this idea has been knocked around at Google.

However, I didn't explain the 'epoch' bit very well in my emails to
Ravi so I'll try again.

The goal is to give the server an nonce. If the server chooses a long
random string then the job is obviously done. However, if the server
promises to only accept each nonce once, for all time, then we have an
nonce via another route. In order for the server to do this it needs
to bound its storage. Loose clock synchronisation gets us that. The
server can make a trade off between how loose and how much storage.

The epoch value was intended to be learnt by the client (since the
clients need to know the server's certificate before hand anyway) and
used to segment the nonce space. Consider two different clusters on
different sides of the world, both using the same certificate. Without
an epoch value (which would be specific to each cluster) they would
have to synchronise with each other for every new nonce.

Also, it's very expensive to provide durable transactions for
frequently changing data. If we kept the "used nonce" store in memory
then we would need a way to invalidate all previous nonces in the
event of a power failure or other data loss. Changing the epoch value
would suffice here.

However, having the server's nonce be non-fresh leads to this attack:

Client (A) performs a 0-RTT setup to a server (B). This means that it
sends (somehow) enough information for a valid server to extract
application data with no additional round trips. An attacker (M)
intercepts A's traffic and stops it. A sees a timeout as B never
replies. However, the nonce was never used, so M can replay A's
message at a later time.

This suggests that 0-RTT techniques could only be used when the
request is side-effect free (as GETs are supposed to be in HTTP).

That rather scary and we shant be rushing into anything here.

AGL

---

From: Ravi Ganesan <[email-masked]>
Date: Wed, 3 Feb 2010 04:24:13 -0800

> both using the same certificate

Thx, I missed this before. Assume there is some economic/engineering
reason you do not use unique keys/certs.

Question: Restricting analysis to abbreviated handshake, would it not
be the case that the session_ids and corresponding master secrets for
exisiting session would be separate in the two clusters? i.e. unless
you allow me to do full handshake in cluster 1 and resume it in
cluster 2. If you do not then does this not prevent replay from one
cluster to the other?

---

From: Adam Langley <[email-masked]>
Date: Wed, 3 Feb 2010 07:40:03 -0500

> cluster 2. If you do not then does this not prevent replay from one

Although you can probably probe different Google frontend clusters to
find this stuff out, I'm going to shy away from talking about the
specifics of Google's serving infrastructure.

Keeping things general:

Session IDs need some kind of server-side storage and SessionTickets
contain arbitary server controlled data, so both could contain an
epoch number that the server uses internally when validating an nonce
for uniqueness.

So, if these schemes were to be coupled (resumption and client
supplied nonces), then the need for the client to handle the epoch
could be removed.

AGL

---

From: "Brian Smith" <[email-masked]>
Date: Fri, 5 Feb 2010 12:55:31 -0600

Ravi Ganesan wrote:
 
> This is awkward for us not just from a latency perspective, but it
> would be very nice if the initial request came with all
> the information needed for the Server to figure out who is on the
> other end. (e.g. a cross domain XHR request).

The client finished message verifies that the client has the master secret
because the protocol requires the client to combine the master secret with
bits that the server just provided in this connection. If the server hasn't
provided any input to the client finished message, then it cannot use the
client finished message to verify that the client has the master secret. In
particular, it cannot verify that the client isn't replaying the client
finished message from another connection.

> send the Client Finished in first message.

How does it help to reduce this from three segments to two segments? The
third segment (C -> Client Finished -> S) will usually look like (C ->
Client Finished || Application Data -> S). Unless you include the
application data in the first segment too, you're not really reducing the
number of segments.

> it is within some range; hence loose clock synchronization).

   key_block = PRF(SecurityParameters.master_secret,
                      "key expansion",
                      SecurityParameters.server_random +
                      SecurityParameters.client_random);

If you let the client choose both server_random and client_random, then
you're effectively letting the client choose the encryption keys and
initialization vectors. Common block cipher modes are very sensitive to
reusing initialization vectors. At a minimum, the server would have to keep
a cache to ensure that the "suggested" server random values are never
reused. And, that cache has to be *serialized* across all server threads and
all machines in the server cluster. That seems very unrealistic. 

Even then, the server can't verify that the suggested server_random is
actually random or random enough. That means that the server is relying
solely on the correctness of the client to ensure the randomness of the
resulting initialization vectors and keys. Previous experience has shown
that this isn't safe.

> sure why latter is better alternative.

Like I said above, the TLS resumption handshake already adds only a single
round-trip, compared to a transaction that doesn't even use TLS at all.

Secondly, it seems like you are assuming that your shortcut is obviously
safe, and so would be able to reuse the security analysis of TLS that was
done without this shortcut in mind. AFAICT, that isn't true.

In fact, I don't see how this is safe at all. If I am overlooking something
then please let me know.

Regards,
Brian

---

From: Ravi Ganesan <[email-masked]>
Date: Fri, 5 Feb 2010 19:05:43 -0800

i) I never said the shortcut is "obviously safe"!!! On the contrary I
went to great lengths to say that (a) on surface it if "preposterous",
(b) that I tried my best to dig up the historical reason those random
numbers were added when one moved from ssl 2.0 to ssl 3.0, (I
explained this in separate thread
http://www.ietf.org/mail-archive/web/tls/current/msg05735.html), (c)
then suggested that the client SUGGEST a server random which is
constrained to be a function of the client_random and the unix_gmt
(not let client pick arbitrary random). and (d) let the server decide
where it is in the risk/reward spectrum and decide whether to take the
additional risk or not.  I want to emphasize this, as this is not
something that one does lightly, and in the post, and in the paper
referenced I go to great lengths to point out the risks.

ii) Absolutely recognize replay issue, which requires caching within
clock slew you tolerate, or Adam's epoch scheme. Does all this make
protocol messier...absolutely! Backing out of a ChangeCipherCpecs,
having the application presumptuously send data and then back out when
it realizes something went wrong is all messy. Point is some might be
willing to live with this messiness for the gain in performance.

iii) Your point about "tls security analysis" cannot be applied
blindly is completely true but is not what I was saying. My point was
that if you gave me two alternates: (i) a very close descendant of SSL
with the only change being that on session resumption the
server-random is a function of client_random and client unix_gmt,
versus (ii) a completely new protocol a bunch of people came up with
today because they wanted a one round trip protocol, THEN I for one
would take the TLS descendant in a heartbeat.

Hope this helps!

Ravi

---

From: "Brian Smith" <[email-masked]>
Date: Tue, 9 Feb 2010 09:46:23 -0800

> willing to live with this messiness for the gain in performance.

With DTLS, you can "resume a connection" and send application data all within *one* segment (half a round-trip). If you used DTLS then you wouldn't need to invent anything new, AFAICT.

Regards,
Brian

---

From: Michael Tüxen <[email-masked]>
Date: Tue, 9 Feb 2010 17:00:26 +0100

> With DTLS, you can "resume a connection" and send application data all within *one* segment (half a round-trip). If you used DTLS then you wouldn't need to invent anything new, AFAICT.
... not if you run DTLS over a connection oriented transport protocol
like DCCP or SCTP. For the new transport connection you need to
establish a new DTLS connection.

Best regards
Michael
> 
> Regards,
> Brian
> 
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Ravi Ganesan <[email-masked]>
Date: Tue, 9 Feb 2010 08:15:07 -0800

> With DTLS, you can "resume a connection" and send application data all within *one* segment (half a round-trip). If you used DTLS then you wouldn't need to invent anything new, AFAICT.

I will check it out again, but my understanding was that DTLS is
essentially a binding of TLS for UDP, but does not change the
handshake semantics.

Do keep in mind that the ability to start sending data after the
client_hello by itself does not help, if the client_hello does not
contain all the information needed for the Server to authenticate the
client. So if the server responds with server_hello and then has to
wait for the client_finished, it may not really help (depending on
application).

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 09 Feb 2010 08:39:36 -0800

At Tue, 9 Feb 2010 09:46:23 -0800,
Brian Smith wrote:
> With DTLS, you can "resume a connection" and send application data
> all within *one* segment (half a round-trip). If you used DTLS then
> you wouldn't need to invent anything new, AFAICT.

When you say "With DTLS" you mean with some modification to DTLS,
correct? AFAIK DTLS currently requires the client to compute
the keys based on the ServerRandom which precludes what you
suggest here.

-Ekr

---

From: Michael Tüxen <[email-masked]>
Date: Tue, 9 Feb 2010 18:51:53 +0100

> the keys based on the ServerRandom which precludes what you
I assume that he just "continues to use an existing DTLS connect",
or am I wrong? 

Best regards
Michael

---

From: Ravi Ganesan <[email-masked]>
Date: Tue, 9 Feb 2010 10:35:06 -0800

> I assume that he just "continues to use an existing DTLS connect",

I do not know about DTLS, but in regular TLS one cannot say open a
fresh socket, send a client_hello with an existing session ID, do a
change cipher_spec and start sending data using keys from old session.
You really need to go through the abbreviated handshake dance for a
number of reasons, including fresh keys to keep cut and paste attacks
at bay, etc. It would be very ironic if we ended up with holes that
were fixed in the SSL 2.0 to 3.0 transition. (See section 3.0 and 4.0
of this paper http://www.schneier.com/paper-ssl.pdf).

---

From: "Brian Smith" <[email-masked]>
Date: Tue, 9 Feb 2010 13:47:41 -0800

Michael Tüxen wrote:
> ... not if you run DTLS over a connection oriented transport
> protocol like DCCP or SCTP. For the new transport connection
> you need to establish a new DTLS connection.

That's true. But, MashSSL is TLS tunneled through HTTP over TCP, so it has a lot of flexibility in how it defines a "HTTP over TCP transport connection." MashSSL already lets that transport connection span multiple TCP connections (AFAICT).

> Michael Tüxen wrote:
> > I assume that he just "continues to use an existing DTLS connect", or
> > am I wrong?

You both understand the idea.

Ravi Ganesan wrote:
> I do not know about DTLS, but in regular TLS one cannot say open a fresh socket,
> send a client_hello with an existing session ID, do a change cipher_spec and
> start sending data using keys from old session.
> You really need to go through the abbreviated handshake dance for a number of
> reasons, including fresh keys to keep cut and paste attacks at bay, etc. It would
> be very ironic if we ended up with holes that were fixed in the SSL 2.0 to 3.0
> transition. (See section 3.0 and 4.0 of this paper
> http://www.schneier.com/paper-ssl.pdf).

DTLS and even regular TLS wouldn’t work if that was true. I think it will be help to look at how DTLS works--in particular, how it distinguishes the start of a new DTLS handshake from a continuation of an existing DTLS connection.

Unfortunately, I can't really devote enough time to this topic to explain everything clearly. Maybe in a few weeks I will have time to work on it some more.

Regards,
Brian