WEBVTT
00:00:00.000 --> 00:00:14.820
33C3 preroll music
00:00:14.820 --> 00:00:20.190
Herald: Basically the upcoming
talk is about “Deploying TLS 1.3”
00:00:20.190 --> 00:00:23.509
and is by Filippo Valsorda
and Nick Sullivan,
00:00:23.509 --> 00:00:26.989
and they’re both with Cloudflare.
00:00:26.989 --> 00:00:32.110
So please, a warm welcome
to Nick and Filippo!
00:00:32.110 --> 00:00:39.490
applause
00:00:39.490 --> 00:00:43.820
Filippo: Hello everyone. Alright,
we are here to talk about TLS 1.3.
00:00:43.820 --> 00:00:48.340
TLS 1.3 is of course the latest
version of TLS, which stands for
00:00:48.340 --> 00:00:52.960
‘Transport Layer Security’.
Now, you might know it best
00:00:52.960 --> 00:00:57.900
as, of course, the green lock in
the browser, or by its old name SSL,
00:00:57.900 --> 00:01:02.510
which we are still trying
to kill. Now. TLS is
00:01:02.510 --> 00:01:07.890
a transparent security protocol
that can tunnel securely
00:01:07.890 --> 00:01:12.460
arbitrary application traffic.
It’s used by web browsers, of course,
00:01:12.460 --> 00:01:16.760
it’s used by mail servers to
communicate with each other
00:01:16.760 --> 00:01:22.270
to secure SMTP. It’s used by
Tor nodes to talk to each other.
00:01:22.270 --> 00:01:26.810
But it evolved over 20 years,
00:01:26.810 --> 00:01:31.320
but at its core it’s about a client
and a server that want to communicate
00:01:31.320 --> 00:01:36.119
securely over the network.
To communicate securely over the network
00:01:36.119 --> 00:01:41.170
they need to establish some key material,
to agree on some key material
00:01:41.170 --> 00:01:47.349
on the two sides to encrypt
the rest of the traffic.
00:01:47.349 --> 00:01:51.989
Now how they agree on this key material
is [done] in a phase that we call
00:01:51.989 --> 00:01:57.890
the ‘handshake’. The handshake involves
some public key cryptography and some data
00:01:57.890 --> 00:02:02.670
being shovelled from the client to the
server, from the server to the client.
00:02:02.670 --> 00:02:07.170
Now this is how the handshake
looks like in TLS 1.2.
00:02:07.170 --> 00:02:12.790
So the client starts the dances
by sending a ‘Client Hello’ over,
00:02:12.790 --> 00:02:18.960
which specifies what supported
parameters it can use.
NOTE Paragraph
00:02:18.960 --> 00:02:23.430
The server receives that and sends
a message of its own, which is
00:02:23.430 --> 00:02:28.200
‘Server Hello’ that says: “Sure!
Let’s use this cipher suite over here
00:02:28.200 --> 00:02:33.230
that you say you support, and
here is my key share to be used
00:02:33.230 --> 00:02:39.270
in this key agreement algorithm.
And also here is a certificate
00:02:39.270 --> 00:02:45.300
which is signed by an authority
that proves that I am indeed
00:02:45.300 --> 00:02:50.370
Cloudflare.com. And here is a signature
from the certificate to prove that
00:02:50.370 --> 00:02:55.450
this key share is actually the one that
I want you to use, to establish keys”.
00:02:55.450 --> 00:03:00.940
The client receives that, and it generates
its own key share, its own half
00:03:00.940 --> 00:03:06.200
of the Diffie-Hellman key exchange,
and sends over the key share,
00:03:06.200 --> 00:03:10.999
and a message to say: “Alright, this
is it. This wraps up the handshake”
00:03:10.999 --> 00:03:15.490
which is called the ‘Finished’ message.
[The] server receives that, makes
00:03:15.490 --> 00:03:20.679
a ‘Finished’ message of its own,
and answers with that. So.
00:03:20.679 --> 00:03:25.930
Now we can finally send application
data. So to recap, we went:
00:03:25.930 --> 00:03:30.022
Client –> Server, Server –> Client;
Client –> Server, Server –> Client.
00:03:30.022 --> 00:03:34.960
We had to do 2 round trips between the
client and the server before we could do
00:03:34.960 --> 00:03:40.730
anything. We haven’t sent any
byte on the application layer
00:03:40.730 --> 00:03:46.010
until now. Now of course
this, on mobile networks
00:03:46.010 --> 00:03:50.539
or in certain parts of the
world, can build up
00:03:50.539 --> 00:03:55.320
to hundreds of milliseconds of latency.
And this is what needs to happen
00:03:55.320 --> 00:04:00.930
every time a new connection is set up.
Every time the client and the server
00:04:00.930 --> 00:04:06.490
have to go twice between them
to establish the keys before
00:04:06.490 --> 00:04:12.730
the connection can actually
be used. Now, TLS 1.1
00:04:12.730 --> 00:04:17.950
and 1.0 were not that different
from 1.2. So you might ask: well, then
00:04:17.950 --> 00:04:23.750
why are we having an entire talk on
TLS 1.3, which is probably just this other
00:04:23.750 --> 00:04:31.430
iteration over the same concept? Well,
TLS 1.3 is actually a big re-design.
00:04:31.430 --> 00:04:36.740
And in particular, the handshake has been
restructured. And the most visible result
00:04:36.740 --> 00:04:43.139
of this is that an entire round
trip has been shaved off.
00:04:43.139 --> 00:04:48.929
So, here is how a TLS 1.3
handshake looks like.
00:04:48.929 --> 00:04:53.479
How does 1.3 remove a round trip?
How can it do that? Well, it does that
00:04:53.479 --> 00:04:59.799
by predicting what key agreement algorithm
00:04:59.799 --> 00:05:04.740
the server will decide to use, and
sending pre-emptively a key share
00:05:04.740 --> 00:05:10.029
for that algorithm to the server.
So with the first flight we had
00:05:10.029 --> 00:05:15.529
the ‘Client Hello’, the supported
parameters, and a key share
00:05:15.529 --> 00:05:21.549
for the one that the client thinks the
server will like. The server receives that
00:05:21.549 --> 00:05:27.239
and if everything goes well, it will
go like “Oh! Sure! I like this key share.
00:05:27.239 --> 00:05:32.789
Here is my own key share to run
the same algorithm, and here is
00:05:32.789 --> 00:05:37.719
the other parameters we should use.”
It immediately mixes the two key shares
00:05:37.719 --> 00:05:42.319
to get a shared key, because now
it has both key shares – the client’s
00:05:42.319 --> 00:05:47.089
and the server’s – and sends again
the certificate and a signature
00:05:47.089 --> 00:05:51.339
from the certificate, and then
immediately sends a ‘Finished’ message
00:05:51.339 --> 00:05:56.339
because it doesn’t need anything else
from the client. The client receives that,
00:05:56.339 --> 00:06:02.020
takes the key share, mixes the shared key
and sends its own ‘Finished’ message,
00:06:02.020 --> 00:06:07.009
and is ready to send whatever application
layer data it was waiting to send.
00:06:07.009 --> 00:06:12.650
For example your HTTP
request. Now we went:
00:06:12.650 --> 00:06:15.919
Client –> Server, Server –> Client.
00:06:15.919 --> 00:06:21.330
And we are ready to send data at the
application layer. So you are trying
00:06:21.330 --> 00:06:27.239
to setup a HTTPS connection
and your browser
00:06:27.239 --> 00:06:32.769
doesn’t need to wait 4x
the latency, or 4x the ping.
00:06:32.769 --> 00:06:38.929
It only has to wait 2x. And of course
this saves hundreds of milliseconds
00:06:38.929 --> 00:06:46.199
of latency when setting up fresh
connections. Now, this is the happy path.
00:06:46.199 --> 00:06:52.299
So this is what happens when the
prediction is correct and the server likes
00:06:52.299 --> 00:06:58.449
the client key share. If the server
doesn’t support the key share
00:06:58.449 --> 00:07:05.169
that the client sent it will send a polite
request to use a different algorithm
00:07:05.169 --> 00:07:10.530
that the client said it can support. We
call that message ‘Hello Retry Request’.
00:07:10.530 --> 00:07:16.469
It has a cookie, so that can be stateless,
but essentially it makes a fall-back
00:07:16.469 --> 00:07:21.970
to what is effectively a TLS-1.2-like
handshake. And it’s not that hard
00:07:21.970 --> 00:07:26.939
to implement because the client follows up
with a new ‘Client Hello’ which looks
00:07:26.939 --> 00:07:34.489
essentially exactly like a fresh one. Now.
00:07:34.489 --> 00:07:42.179
Here I’ve been lying to you.
TLS 1.2 is not always 2 round trips.
00:07:42.179 --> 00:07:47.779
Most of the connections we see from the
Cloudflare edge e.g. are ‘resumptions’.
00:07:47.779 --> 00:07:53.299
That means that the client has connected
to that website before in the past.
00:07:53.299 --> 00:07:59.079
And we can use that, we can exploit
that to make the handshake faster.
00:07:59.079 --> 00:08:06.290
That means that the client can remember
something about the key material
00:08:06.290 --> 00:08:10.959
to make the next connection
a round trip even in TLS 1.2.
00:08:10.959 --> 00:08:16.019
So here is how it looks like. Here
you have your normal TLS 1.2 full
00:08:16.019 --> 00:08:22.479
2-round trip connection. And over
here it sends a new session ticket.
00:08:22.479 --> 00:08:30.029
A session ticket is nothing else than a
encrypted wrapped blob of key material
00:08:30.029 --> 00:08:35.100
that the client will hold on to. The
session ticket is encrypted and signed
00:08:35.100 --> 00:08:40.039
with a key that only the server knows.
So it’s completely opaque to the client.
00:08:40.039 --> 00:08:45.040
But the client will keep it together
with the key material of the connection,
00:08:45.040 --> 00:08:49.340
so that the next time it makes
a connection to that same website
00:08:49.340 --> 00:08:54.439
it will send a ‘Client Hello’,
and a session ticket.
00:08:54.439 --> 00:08:59.180
If the server recognises the session
ticket it will decrypt it, find inside
00:08:59.180 --> 00:09:04.090
the key material. And now, after only one
round trip, the server will have some
00:09:04.090 --> 00:09:09.820
shared key material with the client because
the client held on to the key material
00:09:09.820 --> 00:09:15.460
from last time and the server just
decrypted it from the session ticket.
00:09:15.460 --> 00:09:20.890
OK? So now the server has some shared
keys to use already, and it sends
00:09:20.890 --> 00:09:26.150
a ‘Finished’ message, and the client sends
its own ‘Finished’ message and the request.
00:09:26.150 --> 00:09:31.550
So this is TLS 1.2. This is what
is already happening every day
00:09:31.550 --> 00:09:37.380
with most modern TLS connections. Now.
00:09:37.380 --> 00:09:43.530
TLS 1.3 resumption is not that different.
It still has the concept of a session ticket.
00:09:43.530 --> 00:09:48.300
We changed the name of what’s inside
the session ticket to a ‘PSK’ but that
00:09:48.300 --> 00:09:53.220
just means ‘Pre-shared Key’ because
that’s what it is: it’s some key material
00:09:53.220 --> 00:09:58.480
that was agreed upon in advance.
And it works the same way:
00:09:58.480 --> 00:10:02.830
the server receives the session
ticket, decrypts it and jumps to the
00:10:02.830 --> 00:10:07.450
‘Finished’ message. Now,
00:10:07.450 --> 00:10:13.070
a problem with resumption
is that if an attacker
00:10:13.070 --> 00:10:17.130
controls the session ticket key
– the key that the server uses
00:10:17.130 --> 00:10:21.540
to encrypt the session ticket that
has inside the key material –
00:10:21.540 --> 00:10:27.050
an attacker can passively or in the future
even, with a recording of the connection,
00:10:27.050 --> 00:10:33.460
decrypt the session ticket from the
‘Client Hello’, find the PSK inside it
00:10:33.460 --> 00:10:38.320
and use it to decrypt the rest of
the connection. This is not good.
00:10:38.320 --> 00:10:42.519
This means that someone can do
passive decryption by just having
00:10:42.519 --> 00:10:47.819
the session ticket key. How this is
addressed usually is that we say
00:10:47.819 --> 00:10:52.540
that session ticket keys are short-
lived. But still it would be nice if
00:10:52.540 --> 00:10:56.270
we didn’t have to rely on that. And there
are actually nice papers that tell us
00:10:56.270 --> 00:11:01.310
that implementations don’t
always do this right. So,
00:11:01.310 --> 00:11:07.050
instead what TLS 1.3 allows
us to do is use Diffie-Hellman
00:11:07.050 --> 00:11:11.760
with resumption. In 1.2 there
was no way to protect
00:11:11.760 --> 00:11:16.720
against session ticket key
compromise. In 1.3 what you can do
00:11:16.720 --> 00:11:21.409
is send a key share as part
of the ‘Client Hello’ anyway,
00:11:21.409 --> 00:11:25.499
and the server will send a key share
together with the ‘Server Hello’,
00:11:25.499 --> 00:11:31.710
and they will run Diffie-Hellman.
Diffie-Hellman is what was used to
00:11:31.710 --> 00:11:36.009
introduce forward secrecy against
the compromise of, for example,
00:11:36.009 --> 00:11:41.339
the certificate private key in 1.2, and
it’s used here to provide forward secrecy
00:11:41.339 --> 00:11:46.290
for resumed connections.
Now, you will say:
00:11:46.290 --> 00:11:51.240
“Now this looks essentially
like a normal 1.3 handshake,
00:11:51.240 --> 00:11:55.770
why having the PSK at all?” Well,
there is something missing from this one,
00:11:55.770 --> 00:11:59.510
there is no certificate. Because
there is no need to re-authenticate
00:11:59.510 --> 00:12:04.620
with a certificate because the client and
the server spoke in the past, and so
00:12:04.620 --> 00:12:09.099
the client knows that it already checked
the certificate of the server and
00:12:09.099 --> 00:12:12.819
if the server can decrypt the session
ticket it means that it’s actually
00:12:12.819 --> 00:12:17.879
who it says it is. So, the two
key shares get mixed together.
00:12:17.879 --> 00:12:22.860
Then mixed with the PSK to make
a key that encrypts the rest
00:12:22.860 --> 00:12:29.580
of the connection. Now.
There is one other feature
00:12:29.580 --> 00:12:34.701
that is introduced by TLS 1.3
resumption. And that is the fact
00:12:34.701 --> 00:12:40.830
that it allows us to make 0-round
trip handshakes. Again,
00:12:40.830 --> 00:12:47.280
all handshakes in 1.3
are mostly 1-round trip.
00:12:47.280 --> 00:12:52.140
TLS 1.2 resumptions can be
at a minimum 1-round trip.
00:12:52.140 --> 00:12:58.331
TLS 1.3 resumptions can be 0-round
trip. How does a 0-round trip
00:12:58.331 --> 00:13:04.210
handshake work? Well, if you think about
it, when you start, you have a PSK,
00:13:04.210 --> 00:13:10.119
a Pre-Shared Key. The client
can just use that to encrypt
00:13:10.119 --> 00:13:15.680
this early data that it wants to
send to the server. So the client
00:13:15.680 --> 00:13:20.439
opens a connection, to a server that it
has already connected to in the past,
00:13:20.439 --> 00:13:25.349
and sends ‘Client Hello’, session ticket,
00:13:25.349 --> 00:13:29.920
key share for Diffie-Hellman and
then early data. Early data is
00:13:29.920 --> 00:13:34.410
this blob of application data
– it can be e.g. a HTTP request –
00:13:34.410 --> 00:13:39.409
encrypted with the PSK.
The server receives this,
00:13:39.409 --> 00:13:45.369
decrypts the session ticket, finds
the PSK, uses the PSK to decrypt the
00:13:45.369 --> 00:13:50.770
early data and then proceeds as normal:
mixes the 2 key shares, mixes the PSK in,
00:13:50.770 --> 00:13:55.270
makes a new key for the rest of the
connection and continues the connection.
00:13:55.270 --> 00:14:00.289
So what happened here? We were able to
send application data immediately upon
00:14:00.289 --> 00:14:05.339
opening the connection. This means that
we completely removed the performance
00:14:05.339 --> 00:14:11.320
overhead of TLS. Now.
00:14:11.320 --> 00:14:16.460
0-RTT handshakes, though, have
2 caveats that are theoretically
00:14:16.460 --> 00:14:22.540
impossible to remove. One is that
that nice thing that we introduced
00:14:22.540 --> 00:14:27.829
with the PSK ECDHE mode, the one where
we do Diffie-Hellman for resumption
00:14:27.829 --> 00:14:33.040
in 1.3, does not help with 0-RTT data.
00:14:33.040 --> 00:14:38.620
We do Diffie-Hellman when we
reach the green box in the slide.
00:14:38.620 --> 00:14:44.000
Of course the early data is only encrypted
with the PSK. So let’s think about
00:14:44.000 --> 00:14:49.150
the attacker again. The attacker somehow
stole our session ticket encryption keys.
00:14:49.150 --> 00:14:54.969
It can look at the ‘Client Hello’, decrypt
the session ticket, get the PSK out,
00:14:54.969 --> 00:15:00.029
use the PSK to decrypt the early data.
00:15:00.029 --> 00:15:05.350
And it can do this even from a recording
if it gets the session ticket later on.
00:15:05.350 --> 00:15:11.519
So the early data is not forward secret
with respect to the session ticket keys.
00:15:11.519 --> 00:15:16.679
Then of course it becomes useless
if we are doing Diffie-Hellman to get
00:15:16.679 --> 00:15:23.020
the server answer. That’s only useful
for the first flight sent from the client.
00:15:23.020 --> 00:15:28.340
So to recap, a lot of things
going on here: TLS 1.2
00:15:28.340 --> 00:15:33.379
introduced forward secrecy
against the compromise of the
00:15:33.379 --> 00:15:39.119
certificate private keys, a long
time ago, by using ECDHE modes.
00:15:39.119 --> 00:15:45.030
So 1.2 connections can be
always forward secret against
00:15:45.030 --> 00:15:50.300
certificate compromise.
TLS 1.3 has that always on as well.
00:15:50.300 --> 00:15:55.090
There is no mode that is not forward
secret against compromise of the
00:15:55.090 --> 00:16:01.279
certificate. But when we think about what
might happen to the session ticket key:
00:16:01.279 --> 00:16:06.000
TLS 1.2 never provides forward secrecy.
00:16:06.000 --> 00:16:11.149
In TLS 1.2 compromising the session
ticket key always means being able
00:16:11.149 --> 00:16:15.819
to passively and in the future
decrypt resumed connections.
00:16:15.819 --> 00:16:22.689
In 1.3 instead, if we use PSK
ECDHE only the early data
00:16:22.689 --> 00:16:28.270
can be decrypted by using
the session ticket key alone.
00:16:28.270 --> 00:16:33.199
Now, I said that there were 2 caveats.
00:16:33.199 --> 00:16:39.329
The second caveat is that
0-RTT data can be replayed.
00:16:39.329 --> 00:16:45.449
The scenario is this: you have
some data in the early data
00:16:45.449 --> 00:16:51.709
that is somehow authenticated. It might be
a HTTP request with some cookies on it.
00:16:51.709 --> 00:16:58.070
And that HTTP request is somehow
executing a transaction,
00:16:58.070 --> 00:17:03.150
okay? Moving some money, instructing
the server to do something. An attacker
00:17:03.150 --> 00:17:07.580
wants to make that happen multiple
times. It can’t decrypt it, of course
00:17:07.580 --> 00:17:13.149
– it’s protected with TLS. So it
can’t read the cookie, and it can’t
00:17:13.149 --> 00:17:17.689
modify it because, of course, it’s
protected with TLS. But it can record
00:17:17.689 --> 00:17:23.069
the encrypted message
and it can then replay it
00:17:23.069 --> 00:17:27.900
against the server. Now if you have
a single server this is easy to fix.
00:17:27.900 --> 00:17:32.520
You just take a note of the messages you
have seen before and you just say like
00:17:32.520 --> 00:17:37.500
“No, this looks exactly like something I
got before”. But if, for example like
00:17:37.500 --> 00:17:42.270
Cloudflare you are running multiple data
centres around the world, you cannot keep
00:17:42.270 --> 00:17:47.650
consistent state all the time, in real
time across all machines. So there would
00:17:47.650 --> 00:17:52.370
be different machines that if they
receive this message will go like
00:17:52.370 --> 00:17:57.530
“Sure I have the session ticket key,
I decrypt the PSK, I use the PSK,
00:17:57.530 --> 00:18:02.080
I decrypt the early data, I find
inside something, I execute what
00:18:02.080 --> 00:18:07.510
it tells me to do.” Now, of
course, this is not desirable.
00:18:07.510 --> 00:18:13.010
One countermeasure that TLS offers
is that the client sends a value
00:18:13.010 --> 00:18:18.689
in that bundle which is how long
ago in milliseconds I obtained
00:18:18.689 --> 00:18:23.790
the session ticket. The server
looks at that value and
00:18:23.790 --> 00:18:29.080
if it does not match its own view of this
information it will reject the message.
00:18:29.080 --> 00:18:34.020
That means that if the attacker records
the message and then 10 seconds later
00:18:34.020 --> 00:18:40.000
tries to replay it the times won’t
match and the server can drop it.
00:18:40.000 --> 00:18:44.510
But this is not a full solution because
if the attacker is fast enough
00:18:44.510 --> 00:18:50.369
it can still replay messages.
So, everything the server can do
00:18:50.369 --> 00:18:55.970
is either accept the
0-RTT data, or reject it.
00:18:55.970 --> 00:19:00.570
It can’t just take some part of it or
take a peek and then decide because
00:19:00.570 --> 00:19:05.540
it’s the ‘Server Hello’ message that
says whether it’s accepted or rejected.
00:19:05.540 --> 00:19:09.759
And the client will keep sending early
data until it gets the ‘Server Hello’.
00:19:09.759 --> 00:19:15.960
There’s a race here. So the server has to
go blind and decide “Am I taking 0-RTT data
00:19:15.960 --> 00:19:20.990
or am I just rejecting it all?” If it’s
taking it, and then it finds out that it’s
00:19:20.990 --> 00:19:26.750
something that it can’t process because
“Oh god, there is a HTTP POST in here
00:19:26.750 --> 00:19:32.470
that says to move some money, I can’t
do this unless I know it’s not replayed.”
00:19:32.470 --> 00:19:37.060
So the server has to get some
confirmation. The good news is that
00:19:37.060 --> 00:19:40.600
if the server waits for the ‘Finished’
message… The server sends
00:19:40.600 --> 00:19:45.280
the ‘Server Hello’, the ‘Finished’
and waits for the client’s one.
00:19:45.280 --> 00:19:51.050
When the client’s one gets there it means
that also the early data was not replayed,
00:19:51.050 --> 00:19:54.950
because that ‘Finished’ message
ties together the entire handshake
00:19:54.950 --> 00:19:59.769
together with some random value that
the server sent. So it’s impossible
00:19:59.769 --> 00:20:04.380
that it was replayed. So, this is
what a server can do: it can accept
00:20:04.380 --> 00:20:08.780
the early data and if it’s something
that is not idempotent, something
00:20:08.780 --> 00:20:14.610
that is dangerous, if it’s replayed it
can just wait for the confirmation.
00:20:14.610 --> 00:20:18.850
But that means it has to buffer it, and
there’s a risk for an attack here, where
00:20:18.850 --> 00:20:25.580
an attacker just sends a HTTP POST, with
a giant body just to fill your memory.
00:20:25.580 --> 00:20:31.840
So what we realised is that we could help
with this if we wrote on the session tickets
00:20:31.840 --> 00:20:37.240
what’s the maximum amount of
early data that the client can send.
00:20:37.240 --> 00:20:41.500
If we see someone sending more than
that, then it’s an attacker and we
00:20:41.500 --> 00:20:47.499
close the connection, drop the
buffer, free up the memory.
00:20:47.499 --> 00:20:52.969
But. Anyway. However
countermeasures we deploy,
00:20:52.969 --> 00:20:58.780
unless we can keep global state across the
servers, we have to inform the application
00:20:58.780 --> 00:21:03.429
that “this data might be replayed”.
The spec knows this.
00:21:03.429 --> 00:21:08.150
So the TLS 1.3 spec EXPLICITLY says
00:21:08.150 --> 00:21:14.420
protocols must NOT use
0-RTT without a profile
00:21:14.420 --> 00:21:19.159
that defines its use. Which means
“without knowing what they are doing”.
00:21:19.159 --> 00:21:24.419
This means that TLS stack
API’s have to do 1 round trip
00:21:24.419 --> 00:21:30.360
by default, which is not affected by
replays, and then allow the server
00:21:30.360 --> 00:21:35.571
to call some API’s to either reject
or wait for the confirmation,
00:21:35.571 --> 00:21:41.470
and to let the client decide what goes
into this dangerous re-playable
00:21:41.470 --> 00:21:46.040
piece of data. So this will change
00:21:46.040 --> 00:21:49.840
based on the protocols but what about
our favourite protocol? What about
00:21:49.840 --> 00:21:55.329
HTTP? Now HTTP should
be easy, the HTTP spec,
00:21:55.329 --> 00:22:00.759
you go read it and it says “Well,
GET requests are idempotent,
00:22:00.759 --> 00:22:06.149
they must not change anything on the
server”. Solved! We will just allow
00:22:06.149 --> 00:22:10.670
GET requests in early data because even
if they are replayed nothing happened!
00:22:10.670 --> 00:22:16.640
Yay! Nope. sighs You will definitely
find some server on the internet
00:22:16.640 --> 00:22:23.020
that has something like
“send-money.php?to=filippo&amount=this”
00:22:23.020 --> 00:22:28.870
and it’s a GET request. And if an attacker
records this, which is early data,
00:22:28.870 --> 00:22:33.510
and then replays this against a different
server in the pool, that will get executed
00:22:33.510 --> 00:22:38.780
twice. And we can’t have that.
00:22:38.780 --> 00:22:43.300
Now, so what can we do here?
00:22:43.300 --> 00:22:46.890
We make trade-offs!
00:22:46.890 --> 00:22:51.779
If you know your application, you can
make very specific trade-offs. E.g.
00:22:51.779 --> 00:22:57.020
Google has been running QUIC
with 0-RTT for the longest time,
00:22:57.020 --> 00:23:02.200
for 3 years I think? And that means that
they know very well their application.
00:23:02.200 --> 00:23:07.419
And they know that they don’t have
any “send-money.php” endpoints.
00:23:07.419 --> 00:23:12.710
But if you are like Cloudflare that
fronts a wide number of applications
00:23:12.710 --> 00:23:17.720
you can’t make such wide sweeping
assumptions, and you have instead
00:23:17.720 --> 00:23:22.570
to hope for some middle ground. For
example, something we might decide to do
00:23:22.570 --> 00:23:28.730
is to only allow GETs
to the root. So “GET /”
00:23:28.730 --> 00:23:33.200
which might be the most benefit because
maybe most connections start like that,
00:23:33.200 --> 00:23:38.710
and the least likely to cause trouble.
00:23:38.710 --> 00:23:43.140
We are still working on how exactly to
bring this to applications. So if you know
00:23:43.140 --> 00:23:48.199
of an application that would get hurt
by something as simple as that
00:23:48.199 --> 00:23:53.840
do email us, but actually,
if you have an application
00:23:53.840 --> 00:23:59.160
that is that vulnerable I have
bad news. Thai Duong et. al.
00:23:59.160 --> 00:24:04.150
demonstrated that browsers will
today, without TLS 1.3 or anything,
00:24:04.150 --> 00:24:09.740
replay HTTP requests
if network errors happen.
00:24:09.740 --> 00:24:15.670
And they will replay them silently.
So it might not be actually worse
00:24:15.670 --> 00:24:21.990
than the current state. Okay.
I can actually see everyone
00:24:21.990 --> 00:24:27.959
getting uneasy in their seats, thinking
“There the cryptographers are at it again!
00:24:27.959 --> 00:24:32.740
They are making the security protocol that
we need more complex than it has to be
00:24:32.740 --> 00:24:38.889
to get their job security for
the next 15 years!” Right?
00:24:38.889 --> 00:24:44.479
No. No. I can actually assure you that
00:24:44.479 --> 00:24:49.709
one of the big changes, in my opinion
even bigger than the round trips in 1.3,
00:24:49.709 --> 00:24:54.770
is that everything is being weighted
for the benefit against the complexity
00:24:54.770 --> 00:24:59.180
that it introduces. And
while 0-RTT made the cut
00:24:59.180 --> 00:25:02.630
most other things definitely didn’t.
00:25:02.630 --> 00:25:07.890
Nick: Right. Thanks Filippo.
00:25:07.890 --> 00:25:13.640
In TLS 1.3 as an iteration of
TLS we also went back, or,
00:25:13.640 --> 00:25:18.120
“we” being the people who are
looking at TLS, went back and
00:25:18.120 --> 00:25:22.770
revisited the existing TLS 1.2 features
that sort of seemed reasonable at the time
00:25:22.770 --> 00:25:27.439
and decided whether or not the complexity
and the danger added by these features,
00:25:27.439 --> 00:25:32.349
or these protocols, or these
primitives involved in TLS were
00:25:32.349 --> 00:25:37.739
reasonable to keep. And the big one which
happened early on in the process is
00:25:37.739 --> 00:25:43.790
‘Static RSA’ mode. So this is the way that
TLS has been working back since SSL.
00:25:43.790 --> 00:25:48.179
Rather than using Diffie-Hellman to
establish a shared key… How this works is,
00:25:48.179 --> 00:25:52.320
the client will make its own shared
key, and encrypt it with the server’s
00:25:52.320 --> 00:25:56.570
certificate public key which is gonna
be an RSA key, and then just send it
00:25:56.570 --> 00:26:00.770
in plain text over the wire to the server.
And then the server would use its
00:26:00.770 --> 00:26:04.650
private key to decrypt that, and then
establish a shared key. So the client
00:26:04.650 --> 00:26:09.710
creates all the key material in this case.
And one thing that is sort of obvious
00:26:09.710 --> 00:26:13.650
from this is that if the private key
for the certificate is comprised,
00:26:13.650 --> 00:26:18.149
even after the fact, even years later,
someone with the transcript of what happened
00:26:18.149 --> 00:26:23.480
can go back and decrypt this key material,
and then see the entire conversation.
00:26:23.480 --> 00:26:28.419
So this was removed very early in the
process, somewhere around 2 years ago
00:26:28.419 --> 00:26:33.919
in TLS 1.3. So, much to our surprise,
and the surprise of everyone
00:26:33.919 --> 00:26:39.680
reading the TLS mailing
list, just very recently,
00:26:39.680 --> 00:26:44.610
near the end of the standardisation
process where TLS 1.3 was almost final
00:26:44.610 --> 00:26:50.800
this e-mail landed on the list. And this
is from Andrew Kennedy who works at BITS
00:26:50.800 --> 00:26:56.550
which basically means he works
at banks. So this is what he said:
00:26:56.550 --> 00:27:01.670
“Deprecation of the RSA key exchange
in TLS 1.3 will cause significant problems
00:27:01.670 --> 00:27:06.760
for financial institutions, almost all of
whom are running TLS internally and have
00:27:06.760 --> 00:27:12.510
significant, security-critical investments
in out-of-band TLS decryption”.
00:27:12.510 --> 00:27:17.810
“Out-of-band TLS decryption”… mmh…
laughs - applause
00:27:17.810 --> 00:27:23.490
That certainly sounds critical…
critical for someone, right?
00:27:23.490 --> 00:27:26.140
laughs - applause
So…
00:27:26.140 --> 00:27:32.200
laughs
applause
00:27:32.200 --> 00:27:37.039
So one of the bright spots was
Kenny Paterson’s response to this,
00:27:37.039 --> 00:27:41.680
in which he said: “My view
concerning your request: no.
00:27:41.680 --> 00:27:44.920
Rationale: We’re trying to build a MORE
secure internet.” The emphasis on ‘more’
00:27:44.920 --> 00:27:47.350
is mine but I’m sure he meant it, yeah.
00:27:47.350 --> 00:27:54.100
applause
00:27:54.100 --> 00:27:58.840
So after this the banking folks came
to the IETF and presented this slide
00:27:58.840 --> 00:28:04.460
to describe how hard it was to actually
debug their system. This is a very simple…
00:28:04.460 --> 00:28:09.270
I guess, with respect to banking. Those
are the different switches, routers,
00:28:09.270 --> 00:28:14.480
middle ware, web applications; and
everything talks TLS one to the other.
00:28:14.480 --> 00:28:19.730
And after this discussion we decided
we came to a compromise.
00:28:19.730 --> 00:28:24.160
But instead of actually compromising
the protocol Matthew Green
00:28:24.160 --> 00:28:28.900
taught them how to use Diffie-Hellman
incorrectly. They ended up actually
00:28:28.900 --> 00:28:33.110
being able to do what they wanted
to do, without us – or anybody
00:28:33.110 --> 00:28:36.780
in the academic community, or in the
TLS community – adding back this
00:28:36.780 --> 00:28:41.720
insecure piece of TLS.
00:28:41.720 --> 00:28:45.580
So if you want to read this it shows
how to do it. But in any case
00:28:45.580 --> 00:28:49.970
– we didn’t add it back.
Don’t do this, basically! laughs
00:28:49.970 --> 00:28:54.300
applause
00:28:54.300 --> 00:29:00.100
So we killed static RSA, and
what else did we kill? Well,
00:29:00.100 --> 00:29:03.769
looking back on the trade-offs there is
a number of primitives that are in use
00:29:03.769 --> 00:29:08.519
in TLS 1.2 and earlier that just
haven’t stood the test of time.
00:29:08.519 --> 00:29:12.130
So, RC4 stream cipher. Gone!
applause
00:29:12.130 --> 00:29:14.790
3DES (Triple DES) block cipher. Gone!
applause
00:29:14.790 --> 00:29:21.529
MD5, SHA1… all gone. Yo!
ongoing applause
00:29:21.529 --> 00:29:26.480
There is even constructions that took…
basic block cipher constructions
00:29:26.480 --> 00:29:31.640
that are gone: AES-CBC.
Gone. RSA-PKCS1-1.5,
00:29:31.640 --> 00:29:36.810
this has been known to have been
problematic since 1998, also gone!
00:29:36.810 --> 00:29:41.770
They have also removed several features
like Compression and Renegotiation which
00:29:41.770 --> 00:29:47.130
was replaced with a very lightweight
‘key update’ mechanism. So in TLS 1.3
00:29:47.130 --> 00:29:52.490
none of these met the balance of
benefit vs. complexity. And a lot of these
00:29:52.490 --> 00:29:58.030
vulnerabilities, you might recognize, are
just impossible in TLS 1.3. So that’s good.
00:29:58.030 --> 00:30:04.010
applause
00:30:04.010 --> 00:30:09.149
So the philosophy for TLS 1.3 in a lot of
places is simplify and make it more robust
00:30:09.149 --> 00:30:14.549
as much as possible. There are a number
of little cases in which we did that.
00:30:14.549 --> 00:30:18.680
Some of the authors of this paper may be
in the audience right now. But there is
00:30:18.680 --> 00:30:24.030
a way in which block ciphers where
used for the actual record layer
00:30:24.030 --> 00:30:27.640
that was not as robust as it could be.
It has been replaced with a much simpler
00:30:27.640 --> 00:30:32.340
mechanism. TLS 1.2 had this
00:30:32.340 --> 00:30:37.520
really kind of funny ‘Catch 22’ in it
where the cipher negotiation
00:30:37.520 --> 00:30:41.810
is protected by a ‘Finished’ message which
is a message-authentication code, but
00:30:41.810 --> 00:30:47.020
the algorithm for that code was determined
in the cipher negotiation, so,
00:30:47.020 --> 00:30:53.090
it had this kind of loop-back effect. And
attacks like FREAK, LogJam and CurveSwap
00:30:53.090 --> 00:30:59.300
(from last year) managed to exploit these
to actually downgrade connections.
00:30:59.300 --> 00:31:02.669
And this was something that was happening
in the wild. And the reason for this is
00:31:02.669 --> 00:31:06.980
that these cipher suites in this handshake
are not actually digitally signed
00:31:06.980 --> 00:31:11.649
by the private key. And in TLS 1.3
this was changed. Everything
00:31:11.649 --> 00:31:16.129
from the signature up is digitally
signed. So this is great!
00:31:16.129 --> 00:31:21.290
What else did we change? Well,
what else did TLS 1.3 change
00:31:21.290 --> 00:31:27.860
vs. TLS 1.2? And that is: fewer, better
choices. And in cryptography
00:31:27.860 --> 00:31:33.410
better choices always means fewer choices.
So there is now a shortlist of curves and
00:31:33.410 --> 00:31:36.920
finite field groups that you can use. And
no arbitrary Diffie-Hellman groups made up
00:31:36.920 --> 00:31:41.949
by the server, no arbitrary curves
that can be used. And this sort of
00:31:41.949 --> 00:31:47.940
shortening of the list of parameters
really enables 1-RTT to work
00:31:47.940 --> 00:31:51.960
a lot of the time. So as Filippo
mentioned, the client has to guess
00:31:51.960 --> 00:31:56.540
which key establishment
methods the server supports,
00:31:56.540 --> 00:32:01.199
and send that key share. If there is
a short list of only-secure options
00:32:01.199 --> 00:32:05.599
this happens a larger percentage of
the time. So when you’re configuring
00:32:05.599 --> 00:32:10.760
your TLS server it no longer looks
like a complicated takeout menu,
00:32:10.760 --> 00:32:15.690
it’s more like a wedding [menu]. Take one
of each, and it’s a lot more delicious
00:32:15.690 --> 00:32:21.970
anyways. And you can look on
Wireshark, it’s also very simple.
00:32:21.970 --> 00:32:27.800
The cipher suites use extensions,
the curves, and you can go from there.
00:32:27.800 --> 00:32:33.301
Filippo: Now, TLS 1.3 also fixed
what I think was one of the biggest
00:32:33.301 --> 00:32:37.441
actual design mistakes of
TLS 1.2. We talked about
00:32:37.441 --> 00:32:43.410
how forward secrecy works
with resumption in 1.2 and 1.3.
00:32:43.410 --> 00:32:49.199
But TLS 1.2 is even more
problematic. TLS 1.2 wraps
00:32:49.199 --> 00:32:55.679
inside the session tickets the actual
master secret of the old connection.
00:32:55.679 --> 00:33:02.509
So it takes the actual keys that encrypt
the traffic of the original connection,
00:33:02.509 --> 00:33:07.860
encrypts them with the session ticket key,
and sends that to the client to be sent
00:33:07.860 --> 00:33:13.619
back the next time. We talked about
how there’s a risk that an attacker will
00:33:13.619 --> 00:33:18.139
obtain session ticket keys, and decrypt
the session tickets, and break
00:33:18.139 --> 00:33:23.859
the forward secrecy and decrypt
the resumed connections. Well,
00:33:23.859 --> 00:33:29.780
in TLS 1.2 it’s even worse. If they
decrypt the session tickets they could
00:33:29.780 --> 00:33:35.950
go back and backward decrypt the original
00:33:35.950 --> 00:33:42.090
non-resumed connection. And
this is completely unnecessary.
00:33:42.090 --> 00:33:46.770
We have hash functions, we have one-way
functions where you put an input in
00:33:46.770 --> 00:33:52.990
and you get something that you can’t
go back from. So that’s what 1.3 does.
00:33:52.990 --> 00:33:58.579
1.3 derives new keys, fresh
keys for the next connection
00:33:58.579 --> 00:34:04.090
and wraps them inside the session ticket
to become the PSK. So even if you
00:34:04.090 --> 00:34:09.439
decrypt a 1.3 session ticket
you can then attack
00:34:09.439 --> 00:34:13.619
the subsequent connection, and we’ve
seen that you might be able to decrypt
00:34:13.619 --> 00:34:18.949
only the early data, or all the connection
depending on what mode it uses. But
00:34:18.949 --> 00:34:25.959
you definitely can’t decrypt the
original non-resumed connection.
00:34:25.959 --> 00:34:31.729
So, this would be bad enough, but 1.2
makes another decision that entirely
00:34:31.729 --> 00:34:36.760
puzzled me. The whole ‘using the master
secret’ might be just because session
00:34:36.760 --> 00:34:41.779
tickets were an extension in
1.2, which they are not in 1.3.
00:34:41.779 --> 00:34:47.990
But, 1.2 sends the new session
ticket message at the beginning
00:34:47.990 --> 00:34:53.490
of the original handshake,
unencrypted! I mean
00:34:53.490 --> 00:34:58.670
encrypted with the session ticket keys
but not with the current session keys.
00:34:58.670 --> 00:35:04.040
So, any server that just supports
00:35:04.040 --> 00:35:10.130
session tickets will have at the
beginning of all connections,
00:35:10.130 --> 00:35:14.670
even if resumption never happens, they
will have a session ticket which is
00:35:14.670 --> 00:35:18.820
nothing else than the ephemeral
keys of that connection
00:35:18.820 --> 00:35:23.400
wrapped with the session
ticket keys. Now, if you are
00:35:23.400 --> 00:35:28.620
a global passive adversary
that somehow wants to do
00:35:28.620 --> 00:35:33.060
passive dragnet surveillance and
you wanted to passively decrypt
00:35:33.060 --> 00:35:38.720
all the connections, and somehow you
were able to obtain session ticket keys,
00:35:38.720 --> 00:35:44.350
what you would find at the beginning
of every TLS 1.2 connection is
00:35:44.350 --> 00:35:49.830
the session keys encrypted with
the session ticket keys. Now,
00:35:49.830 --> 00:35:55.580
1.3 solves this, and in 1.3 this kind
of attacks are completely impossible.
00:35:55.580 --> 00:35:59.420
The only thing that you can passively
decrypt, or decrypt after the fact,
00:35:59.420 --> 00:36:04.230
is the early data, and definitely not non-
resumed connections, and definitely not
00:36:04.230 --> 00:36:10.920
anything that comes after 0-RTT.
00:36:10.920 --> 00:36:12.840
Nick: So it’s safer, basically.
laughs
00:36:12.840 --> 00:36:15.710
Filippo: Hope so!
Nick: …hopefully.
00:36:15.710 --> 00:36:20.670
And how do we know that it’s safer? Well,
these security parameters, and these
00:36:20.670 --> 00:36:25.840
security requirements of TLS have been
formalized and, as opposed to earlier
00:36:25.840 --> 00:36:30.310
versions of TLS the folks in the academic
community who do formal verification were
00:36:30.310 --> 00:36:34.170
involved earlier. So there have been
several papers analyzing the state machine
00:36:34.170 --> 00:36:40.120
and analyzing the different modes of
TLS 1.3, and these have aided a lot
00:36:40.120 --> 00:36:45.360
in the development
of the protocol. So,
00:36:45.360 --> 00:36:50.570
who actually develops TLS 1.3? Well, it’s
00:36:50.570 --> 00:36:54.730
an organization called the IETF which is
the Internet Engineering Taskforce. It’s
00:36:54.730 --> 00:36:59.760
a group of volunteers that meet 3 times
a year and have mailing lists, and they
00:36:59.760 --> 00:37:03.461
debate these protocols endlessly. They
define the protocols that are used
00:37:03.461 --> 00:37:07.910
on the internet. And originally, the first
thing that I ever saw about this – this is
00:37:07.910 --> 00:37:13.250
a tweet of mine from September
2013 – was a wish list for TLS 1.3.
00:37:13.250 --> 00:37:19.920
And since then they came out
with a first draft at the IETF…
00:37:19.920 --> 00:37:24.630
Documents that define protocols
are known as RFCs, and
00:37:24.630 --> 00:37:29.200
the lead-up to something becoming an RFC
is an ‘Internet Draft’. So you start with
00:37:29.200 --> 00:37:34.330
the Internet Draft 0, and then you iterate
on this draft until finally it gets
00:37:34.330 --> 00:37:39.980
accepted or rejected as an RFC. So
the first one was almost 3 years ago
00:37:39.980 --> 00:37:46.080
back in April 2014, and the current
draft (18) which is considered to be
00:37:46.080 --> 00:37:51.590
almost final, it’s in what is
called ‘Last Call’ at the IETF,
00:37:51.590 --> 00:37:57.330
was just recently in October.
In the security landscape
00:37:57.330 --> 00:38:02.400
during that time you’ve seen so many
different types of attacks on TLS. So:
00:38:02.400 --> 00:38:07.860
Triple Handshake, POODLE, FREAK, Logjam,
DROWN (there was a talk about that earlier
00:38:07.860 --> 00:38:12.220
today), Lucky Microseconds, SLOTH.
All these different types of acronyms
00:38:12.220 --> 00:38:15.550
– you may or may not have heard of –
have happened during the development.
00:38:15.550 --> 00:38:21.380
So TLS 1.3 is a living
document, and it’s hopefully
00:38:21.380 --> 00:38:27.561
going to be small. I mean,
TLS 1.2 was 79 pages.
00:38:27.561 --> 00:38:32.521
It’s kind of a rough read, but
give it a shot! If you like. TLS 1.3
00:38:32.521 --> 00:38:36.330
if you shave off a lot of the excess stuff
at the end is actually close. And it’s
00:38:36.330 --> 00:38:40.980
a lot nicer read, it’s a lot more precise,
even though there are some interesting
00:38:40.980 --> 00:38:46.910
features like 0-RTT, resumption. So
practically, how does it get written?
00:38:46.910 --> 00:38:52.810
Well it’s, uh… Github! And a mailing list!
So if you want to send a pull request
00:38:52.810 --> 00:38:59.020
to this TLS working group, there it is.
This is actually how the draft gets defined.
00:38:59.020 --> 00:39:04.190
And you probably want to send a message
to the mailing list to describe what your
00:39:04.190 --> 00:39:09.300
change is, if you want to. I suggest if
anybody wants to be involved this is
00:39:09.300 --> 00:39:14.190
pretty late. I mean it’s in ‘Last Call’…
But the mailing list is still open. Now
00:39:14.190 --> 00:39:18.370
I’ve been working on this with a bunch of
other people, Filippo as well. We were
00:39:18.370 --> 00:39:23.230
contributors on the draft, been working
for over a year on this. You can check
00:39:23.230 --> 00:39:29.230
the Github issues to see how much work
has gone into it. The draft has changed
00:39:29.230 --> 00:39:34.130
over the years and months.
00:39:34.130 --> 00:39:38.620
E.g. Draft 9 had this very
complicated tree structure
00:39:38.620 --> 00:39:43.550
for a key schedule, you can see
htk… all these different things
00:39:43.550 --> 00:39:49.980
had to do with different keys in the TLS
handshake. And this was inspired by QUIC,
00:39:49.980 --> 00:39:55.650
the Google protocol that Filippo mentioned
earlier as well as a paper called ‘OPTLS’.
00:39:55.650 --> 00:40:00.610
And it had lots of different modes,
semi-static Diffie-Hellman, and this
00:40:00.610 --> 00:40:04.950
tree-based key schedule. And over the
time this was widdled down from this
00:40:04.950 --> 00:40:10.510
complicated diagram to what we have
now in TLS 1.3. Which is a very simple
00:40:10.510 --> 00:40:16.330
derivation algorithm. This took a lot
of work to get from something big
00:40:16.330 --> 00:40:21.670
to something small. But it’s happened!
Other things that happened
00:40:21.670 --> 00:40:27.230
in TLS 1.3 are sort of less substantial,
cryptographically, and that involves
00:40:27.230 --> 00:40:32.550
naming! If anyone has been following
along, TLS 1.3 is not necessarily
00:40:32.550 --> 00:40:38.180
the unanimous choice for the name of this
protocol. It’s, as Filippo mentioned, 1.0,
00:40:38.180 --> 00:40:44.000
1.1, 1.2 are pretty small iterations
even on SSLv3, whereas
00:40:44.000 --> 00:40:49.071
TLS 1.3 is quite a big change.
So there is a lot of options
00:40:49.071 --> 00:40:54.950
for names! Let’s have
a show of hands: Who here
00:40:54.950 --> 00:40:59.860
thinks it should be called 1.3?
laughs
00:40:59.860 --> 00:41:02.030
Thanks, Filippo! Filippo laughs
Yeah, so, pretty good number.
00:41:02.030 --> 00:41:07.840
How about TLS 2? Anybody?
Well, that actually looks like more than…
00:41:07.840 --> 00:41:12.940
Filippo: Remember that SSLv2 is
a thing! And it’s a terrible thing!
00:41:12.940 --> 00:41:18.040
Nick: You don’t want to confuse
that with us! So how about TLS 4?
00:41:18.040 --> 00:41:22.520
Still a significant number of people…
How about TLS 2017? Yeah…
00:41:22.520 --> 00:41:25.780
Alright! TLS 7 anybody? Okay…
00:41:25.780 --> 00:41:30.400
Filippo: TLS Millennium 2019 X?
00:41:30.400 --> 00:41:35.410
YES! Sold!
Nick: Alright! TLS Vista?
00:41:35.410 --> 00:41:38.860
laughter - Nick and Filippo laugh
applause
00:41:38.860 --> 00:41:44.800
Nick: Lots of options! But just as
a reminder, the rest of the world
00:41:44.800 --> 00:41:50.040
doesn’t really call it TLS. This is Google
trends, interest over time, searching for
00:41:50.040 --> 00:41:55.300
‘SSL vs. TLS’. SSL is really what most
of the world calls this protocol. So SSL
00:41:55.300 --> 00:42:00.240
has the highest version of Version 3,
and that’s kind of the reason why people
00:42:00.240 --> 00:42:05.210
thought ‘TLS 4’ was a good idea, because
“Oh, people are confused: 3 is higher
00:42:05.210 --> 00:42:10.720
than 1.2, yada-yada-yada”.
00:42:10.720 --> 00:42:14.870
This poll was not the only poll. It was
taken there some informal twitter polls.
00:42:14.870 --> 00:42:20.030
“Mmm, Bacon!” was a good one,
52% of Ryan Hurst’s poll.
00:42:20.030 --> 00:42:23.870
laughter
00:42:23.870 --> 00:42:28.130
Versions are a really sticky thing in TLS.
00:42:28.130 --> 00:42:32.780
E.g. the versions that we have of TLS
– if you look at them on the wire
00:42:32.780 --> 00:42:37.640
they actually don’t match up.
So SSL 3 is 3.0 which does match up.
00:42:37.640 --> 00:42:43.720
But TLS 1 is 3.1; 3.2…
TLS 1.2 is 3.3; and originally
00:42:43.720 --> 00:42:49.000
I think up to Draft 16
of TLS 1.3 it was 3.4.
00:42:49.000 --> 00:42:53.761
Just sort of a bumping the minor
version of TLS 1.2, very confusing.
00:42:53.761 --> 00:42:58.511
But after doing some internet
measurement it was determined that
00:42:58.511 --> 00:43:02.670
a lot of servers, if you send a ‘Client
Hello’ with ‘3.4’, it just disconnects. So
00:43:02.670 --> 00:43:07.960
this is actually really bad, it prevents
browsers from being able to actually
00:43:07.960 --> 00:43:13.080
safely downgrade. What a server is
supposed to do if it sees a version
00:43:13.080 --> 00:43:18.780
higher than 3.3 is just respond with “3.3”
saying: “Hey, this is the best I have”.
00:43:18.780 --> 00:43:24.880
But turns out a lot of these break.
So 3.3 is in the ‘Client Hello’ now, and
00:43:24.880 --> 00:43:30.680
3.4 is negotiated as a sub
protocol. So this is messy.
00:43:30.680 --> 00:43:35.610
Right? But we do balance the benefits vs.
complexity, and this is one of the ones
00:43:35.610 --> 00:43:39.640
where the benefits of not having servers
fail outweigh the complexity added,
00:43:39.640 --> 00:43:44.340
of adding an additional thing. And to
prevent this from happening in the future
00:43:44.340 --> 00:43:48.820
David Benjamin proposed something called
GREASE where in every single piece of
00:43:48.820 --> 00:43:53.920
TLS negotiation you are supposed to,
as a client, add some random stuff
00:43:53.920 --> 00:43:56.980
in there, so that servers will
get used to seeing things
00:43:56.980 --> 00:44:01.050
that are not versions they’re used to.
So, 0x8a8a. It’s all GREASE-d up!
00:44:01.050 --> 00:44:06.320
Filippo: It’s a real thing!
It’s a real very useful thing!
00:44:06.320 --> 00:44:08.760
Nick: This is going to be very useful,
for the future, for preventing
00:44:08.760 --> 00:44:13.850
these sorts of things. But it’s really
unfortunate that that had to happen.
00:44:13.850 --> 00:44:18.830
We are running low on time, but
we dued to actually get involved with
00:44:18.830 --> 00:44:23.430
getting our hands dirty. And one thing
the IETF really loves when developing
00:44:23.430 --> 00:44:28.680
these standards is running code. So we
started with the IETF 95 Hackathon
00:44:28.680 --> 00:44:32.950
which is in April, and managed,
by the end of it, to get Firefox
00:44:32.950 --> 00:44:37.740
to load a server hosted by Cloudflare
over TLS 1.3. Which was a big
00:44:37.740 --> 00:44:43.250
accomplishment at the time. We used NSS
which is the security library in Firefox
00:44:43.250 --> 00:44:48.850
and ‘Mint’ which was a new version
00:44:48.850 --> 00:44:52.890
of TLS 1.3, from scratch, written in Go.
00:44:52.890 --> 00:44:57.640
And the result was, it worked! But
this was just a proof-of-concept.
00:44:57.640 --> 00:45:02.950
Filippo: To build something that was more
production ready, we looked at what was
00:45:02.950 --> 00:45:08.330
the TLS library that we were most
confident modifying, which unsurprisingly
00:45:08.330 --> 00:45:13.370
wasn’t OpenSSL! So we opted to
00:45:13.370 --> 00:45:17.990
build 1.3 on top of the Go
crypto/tls library, which is
00:45:17.990 --> 00:45:24.210
in the Go language standard library.
The result, we call it ‘tls-tris’,
00:45:24.210 --> 00:45:28.500
and it’s a drop-in replacement for
crypto/tls, and comes with this
00:45:28.500 --> 00:45:33.970
wonderful warning that says “Do not use
this for the sake of everything that’s
00:45:33.970 --> 00:45:38.990
good and just!” Now, it used to be about
everything, but now it’s not really
00:45:38.990 --> 00:45:45.190
about security anymore, we got this
audited, but it’s still about stability.
00:45:45.190 --> 00:45:50.510
We are working on upstreaming
this, which will solidify the API,
00:45:50.510 --> 00:45:56.000
and you can follow along with the
upstreaming process. The Google people
00:45:56.000 --> 00:46:00.830
were kind enough to open us a branch to do
the development, and it will definitely not
00:46:00.830 --> 00:46:06.960
hit the next Go release, Go 1.8, but we
are looking forward to upstreaming this.
00:46:06.960 --> 00:46:12.010
Anyway, even if you use Go,
deploying is hard.
00:46:12.010 --> 00:46:17.800
The first time we deployed Tris
the draft number version was 13.
00:46:17.800 --> 00:46:23.630
And to actually support browsers
going forward from there we had
00:46:23.630 --> 00:46:29.140
to support multiple draft versions
at the same time by switching on
00:46:29.140 --> 00:46:34.590
obscure details sometimes. And sometimes
had to support things that were definitely
00:46:34.590 --> 00:46:40.030
not even drafts because
browsers started to… diverge.
00:46:40.030 --> 00:46:44.970
Now, anyway, we had
a test matrix that would run
00:46:44.970 --> 00:46:50.610
all our commits against all the different
versions of the client libraries,
00:46:50.610 --> 00:46:54.980
and that would make sure that we are
always compatible with the browsers.
00:46:54.980 --> 00:47:00.170
And these days the clients are actually
much more stable, and indeed
00:47:00.170 --> 00:47:05.050
you might be already using it
without knowing. E.g. Chrome Beta,
00:47:05.050 --> 00:47:11.160
the beta channel has it enabled for about
50% as an experiment from the Google side.
00:47:11.160 --> 00:47:16.110
And this is how our graphs looked
like when we first launched,
00:47:16.110 --> 00:47:21.560
when Firefox Nightly enabled it by default
and when Chrome Canary enabled it
00:47:21.560 --> 00:47:26.510
by default. These days we are stable,
around 700 requests per second
00:47:26.510 --> 00:47:30.640
carried over TLS 1.3.
And on our side we enabled it
00:47:30.640 --> 00:47:36.230
for millions of our
websites on Cloudflare.
00:47:36.230 --> 00:47:40.830
And, anyway, as we said,
the spec is a living document
00:47:40.830 --> 00:47:46.080
and it is open. You can see it on
Github. The Tris implementation is there
00:47:46.080 --> 00:47:50.860
even if it has this scary warning, and
the blog here is where we’ll probably
00:47:50.860 --> 00:47:56.210
publish all the follow-up research and
results of this. Thank you very much and
00:47:56.210 --> 00:47:59.990
if you have any questions please come
forward, I think we have a few minutes.
00:47:59.990 --> 00:48:11.770
applause
00:48:11.770 --> 00:48:15.690
Herald: Thank you, we have plenty
of time for questions. First question
00:48:15.690 --> 00:48:19.770
goes to the Internet.
00:48:19.770 --> 00:48:23.930
Signal Angel: The very first
question is of people asking if
00:48:23.930 --> 00:48:28.160
the decision of the 0-RTT going
on to the application, handing it
00:48:28.160 --> 00:48:32.450
off to the application developers,
if that is a very wise decision?
00:48:32.450 --> 00:48:34.130
Filippo: laughs
applause
00:48:34.130 --> 00:48:40.230
Filippo: Well… fair. So, as we said, this
is definitely breaking an abstraction.
00:48:40.230 --> 00:48:45.500
So it’s NOT broken by default.
If you just update Go
00:48:45.500 --> 00:48:50.791
and get TLS 1.3 you won’t
get any 0-RTT because
00:48:50.791 --> 00:48:54.800
indeed it requires collaboration by the
application. So unless an application
00:48:54.800 --> 00:48:59.980
knows what to do with it it just can not
use that and have all the security benefits
00:48:59.980 --> 00:49:06.920
and the one round trip full
handshake advantages, anyway.
00:49:06.920 --> 00:49:09.570
Herald: Ok, next question
is from microphone 1.
00:49:09.570 --> 00:49:12.680
Question: With your early testing of the
protocol have you been able to capture
00:49:12.680 --> 00:49:17.610
any hard numbers on what those
performance improvements look like?
00:49:17.610 --> 00:49:21.170
Filippo sighs
00:49:21.170 --> 00:49:24.580
Nick: One round trip! laughs
Depends how much a round trip is.
00:49:24.580 --> 00:49:28.000
Filippo: Yeah, exactly. One round trip
is… I mean, I can’t tell you a number
00:49:28.000 --> 00:49:33.250
because of course if you live in
San Francisco with a fast fiber it’s,
00:49:33.250 --> 00:49:39.120
I don’t know, 3 milliseconds, 6…?
If you live in, I don’t know,
00:49:39.120 --> 00:49:43.260
some country where EDGE is the only type
of connection you get that’s probably
00:49:43.260 --> 00:49:47.700
around one second. I think we have an
average that is around… between 100
00:49:47.700 --> 00:49:55.100
and 200 milliseconds, but we haven’t
like formally collected these numbers.
00:49:55.100 --> 00:49:57.630
Herald: Ok, next question
from microphone 3.
00:49:57.630 --> 00:50:01.720
Question: One remark I wanted to make is
that another improvement that was made
00:50:01.720 --> 00:50:07.350
in TLS 1.3 is that they added
encryption to client certificates.
00:50:07.350 --> 00:50:11.330
So the client certificates are transmitted
encrypted which is important
00:50:11.330 --> 00:50:17.670
if you think about that a client will
move, and a dragnet surveillance entity
00:50:17.670 --> 00:50:23.120
could track clients with this. And
another remark/question which might…
00:50:23.120 --> 00:50:27.080
Herald: Questions are ended with a question
mark. So can you keep it please a bit short?
00:50:27.080 --> 00:50:31.820
Question: Yeah…
That might be stupid so…
00:50:31.820 --> 00:50:36.400
Does the fixed Diffie-Hellman
groups… wasn’t that the problem
00:50:36.400 --> 00:50:42.890
with the LogJam attack, so… does
this help with LogJam attacks?
00:50:42.890 --> 00:50:46.660
Nick: Are you referencing the
proposal for the banks?
00:50:46.660 --> 00:50:49.590
Question: No no, just in general,
that you can pre-compute…
00:50:49.590 --> 00:50:54.430
Nick: Right, yes, so in Logjam there was
a problem where there was a DH group
00:50:54.430 --> 00:50:57.940
that was shared by a lot of different
servers by default. The Apache one,
00:50:57.940 --> 00:51:03.800
which was 1024 [bit].
In TLS 1.3 it was restricted to
00:51:03.800 --> 00:51:09.190
a pre-computed DH group, that’s
over 2000 bits, as the smallest one,
00:51:09.190 --> 00:51:14.600
and even with all the pre-computation in
the world if you have a 2000 bit DH group
00:51:14.600 --> 00:51:20.140
it’s not feasible to pre-compute
enough to do any type of attack.
00:51:20.140 --> 00:51:21.990
But, yeah, that’s a very good point.
00:51:21.990 --> 00:51:24.950
Filippo: …and since they are fixed there
is no way to force the protocol to use
00:51:24.950 --> 00:51:28.940
anything else that would not be as strong.
Question: Okay, thanks!
00:51:28.940 --> 00:51:32.720
Herald: Next question for microphone 4.
00:51:32.720 --> 00:51:37.120
Question: Thanks for your talk! In the
abstract you mentioned that another
00:51:37.120 --> 00:51:41.550
feature that had to be killed was SNI,
00:51:41.550 --> 00:51:45.920
with the 0-RTT but there are ways to still
implement that, can you elaborate a bit?
00:51:45.920 --> 00:51:49.670
Filippo: Yeah. So, we gave this talk
internally twice, and this question came
00:51:49.670 --> 00:51:55.590
both of the times. So… laughs
00:51:55.590 --> 00:52:01.790
So, SNI is a small parameter
that the client sends to the server
00:52:01.790 --> 00:52:06.210
to say which website it is trying to
connect to. E.g. Cloudflare has
00:52:06.210 --> 00:52:11.250
a lot of websites behind our machines, so
you have to tell us “Oh I actually want
00:52:11.250 --> 00:52:17.230
to connect to blog.filippo.io”. Now
this is of course a privacy concern
00:52:17.230 --> 00:52:22.550
because someone just looking at the bytes
on the wire will know what specific website
00:52:22.550 --> 00:52:29.450
you want to connect to. Now the unfortunate
thing is that it has the same problem as
00:52:29.450 --> 00:52:35.270
getting forward secrecy for the early
data. You send SNI in the ‘Client Hello’,
00:52:35.270 --> 00:52:39.620
and at that time you haven’t negotiated
any key yet, so you don’t have anything
00:52:39.620 --> 00:52:44.960
to encrypt it with. But if you
don’t send SNI in the first flight
00:52:44.960 --> 00:52:49.140
then the server doesn’t know what
certificate to send, so it can’t send
00:52:49.140 --> 00:52:53.050
the signature in the first flight! So you
don’t have keys. So you would have to do
00:52:53.050 --> 00:52:59.030
a 2-round trip, and now we would
be back at TLS 1.2. So, alas.
00:52:59.030 --> 00:53:03.180
That doesn’t work with
1-round trip handshakes.
00:53:03.180 --> 00:53:08.820
Nick: That said, there are proposals in
the HTTP2 spec to allow multiplexing,
00:53:08.820 --> 00:53:14.210
and this is ongoing work. It could be
possible to establish one connection
00:53:14.210 --> 00:53:19.700
to a domain and then establish another
connection within the existing connection.
00:53:19.700 --> 00:53:21.950
And that could potentially
protect your SNI.
00:53:21.950 --> 00:53:25.520
Filippo: So someone looking would think
that you are going to blog.filippo.io but
00:53:25.520 --> 00:53:29.480
then, once you open the connection,
you would be able to ask HTTP2 to also
00:53:29.480 --> 00:53:33.200
serve you “this other website”. Thanks!
00:53:33.200 --> 00:53:38.170
Herald: Okay, next
question, microphone 7,
00:53:38.170 --> 00:53:41.240
or actually 5, sorry.
00:53:41.240 --> 00:53:47.440
Question: You mentioned that there
was formal verification of TLS 1.3.
00:53:47.440 --> 00:53:54.350
What’s the software that was used
to do the formal verification?
00:53:54.350 --> 00:53:59.030
Nick: So there were several software
implementations and protocols…
00:53:59.030 --> 00:54:02.650
Let’s see if I can go back… here.
00:54:02.650 --> 00:54:06.600
So, Tamarin[Prover] is a piece of software
developed by Cas Cremers and others,
00:54:06.600 --> 00:54:11.810
at Oxford and Royal Holloway.
miTLS is in F# I believe,
00:54:11.810 --> 00:54:18.430
this is by INRIA.
And NQSB-TLS is in OCAMAL.
00:54:18.430 --> 00:54:22.970
So several different languages were used
to develop these and I believe the authors
00:54:22.970 --> 00:54:27.490
of NQSB-TLS are here…
00:54:27.490 --> 00:54:30.960
Herald: Okay, next question, microphone 8.
00:54:30.960 --> 00:54:36.440
Question: Hi! Thanks. Thank you for
your informative presentation.
00:54:36.440 --> 00:54:42.690
SSL and TLS history is riddled with “what
could possibly go wrong” ideas and moments
00:54:42.690 --> 00:54:48.810
that bit us in the ass eventually. And so
I guess my question is taking into account
00:54:48.810 --> 00:54:52.740
that there’s a lot of smaller organisations
or smaller hosting companies etc. that
00:54:52.740 --> 00:54:59.600
will probably get this 0-RTT thing
wrong. Your gut feeling? How large
00:54:59.600 --> 00:55:04.180
a chance is there that this will indeed
bite us in the ass soon? Thank you.
00:55:04.180 --> 00:55:09.990
Filippo: Ok, so, as I said I’m
actually vaguely sceptical
00:55:09.990 --> 00:55:16.460
on the impact on HTTP because browsers
can be made to replay requests already.
00:55:16.460 --> 00:55:21.610
And we have seen papers
and blog posts about it. But
00:55:21.610 --> 00:55:25.830
no one actually went out
and proved that that broke
00:55:25.830 --> 00:55:30.620
a huge percent of the internet. But to
be honest, I actually don’t know how to
00:55:30.620 --> 00:55:35.990
answer you how badly we will be bit by it.
But remember that on the other hand
00:55:35.990 --> 00:55:41.650
of the balance is how many still say
that they won’t implement TLS
00:55:41.650 --> 00:55:45.670
because it’s “slow”. Now, no!
00:55:45.670 --> 00:55:51.620
It’s 0-RTT, TLS is fast! Go
out and encrypt everything!
00:55:51.620 --> 00:55:57.940
So those are the 2 concerns that
you have to balance together.
00:55:57.940 --> 00:56:01.910
Again, my personal opinion
is also worth very little.
00:56:01.910 --> 00:56:07.310
This was a decision that was made by
the entire community on the mailing list.
00:56:07.310 --> 00:56:12.900
And I can assure you that everyone has
been really conservative with everything,
00:56:12.900 --> 00:56:18.630
thinking even… indeed, if the name
would have mislead people. So,
00:56:18.630 --> 00:56:23.910
I can’t predict the future. I can only
say that I hope we made the best choice
00:56:23.910 --> 00:56:28.520
to make the most part of the
web the most secure we can.
00:56:28.520 --> 00:56:32.490
Herald: Next question is from the internet.
00:56:32.490 --> 00:56:34.610
Signal Angel, do we have another
question from the internet?
00:56:34.610 --> 00:56:37.760
Signal Angel: Yes we do.
00:56:37.760 --> 00:56:43.060
What are the major implementation
incompatibilities that were found
00:56:43.060 --> 00:56:45.800
now that the actual spec is fairly close?
00:56:45.800 --> 00:56:47.910
Herald: Can you repeat that question?
00:56:47.910 --> 00:56:53.250
Signal Angel repeats question
00:56:53.250 --> 00:56:59.290
Filippo: Okay. As in
during the drafts period?
00:56:59.290 --> 00:57:03.450
So, some of the ones that had version
intolerance were mostly, I think,
00:57:03.450 --> 00:57:06.750
middle boxes and firewalls.
00:57:06.750 --> 00:57:12.690
Nick: There were some very large sites.
I think Paypal was one of them?
00:57:12.690 --> 00:57:18.310
Filippo: Although during the process we
had incompatibilities for all kinds of
00:57:18.310 --> 00:57:23.540
reasons, including one of
the 2 developers misspelled
00:57:23.540 --> 00:57:28.110
the variable number.
laughs
00:57:28.110 --> 00:57:32.420
During the drafts sometimes compatibility
broke, but there was a lot of
00:57:32.420 --> 00:57:37.970
collaboration between client implementations
and server implementations on our side.
00:57:37.970 --> 00:57:44.040
So I’m pretty happy to say that the
actual 1.3 implementations had a lot of
00:57:44.040 --> 00:57:50.980
interoperability testing, and all the
issues were pretty quick to be killed.
00:57:50.980 --> 00:57:54.050
Herald: Okay, next question
is from microphone number 1.
00:57:54.050 --> 00:57:59.300
Question: I have 2 quick questions
concerning session resumption.
00:57:59.300 --> 00:58:02.951
If you store some data on a server
from a session, wouldn’t that be
00:58:02.951 --> 00:58:08.010
some kind of supercookie?
Is that not privacy-dangerous?
00:58:08.010 --> 00:58:13.990
And the second question would be: what
about DNS load balancers or some other
00:58:13.990 --> 00:58:21.070
huge amounts of servers where your request
is going to different servers every time?
00:58:21.070 --> 00:58:28.150
Filippo: Ok, so, these are details about
deploying session tickets effectively.
00:58:28.150 --> 00:58:32.950
TLS 1.3 does think about the privacy
concerns of session tickets; and indeed
00:58:32.950 --> 00:58:37.650
it allows the server to send multiple
session tickets. So the server will still
00:58:37.650 --> 00:58:42.470
know what client is sending it if it
wants to. But at least anyone looking
00:58:42.470 --> 00:58:47.460
at the connection since they are
sent encrypted, not like in 1.2, and
00:58:47.460 --> 00:58:53.171
there can be many. Anyone looking at the
connection will not be able to link it
00:58:53.171 --> 00:58:57.600
back to the original connection. That’s
the best you can do, because if the server
00:58:57.600 --> 00:59:02.560
and the client have to reuse some shared
knowledge the server has to learn about
00:59:02.560 --> 00:59:08.240
who it was. But session tickets in 1.3
can’t be tracked by a passive observer,
00:59:08.240 --> 00:59:13.010
by a third party, actually. And… when you
do load balancing… there is an interesting
00:59:13.010 --> 00:59:18.750
paper about deploying session tickets,
but the gist is that you probably want
00:59:18.750 --> 00:59:24.960
to figure out how clients roam between
your servers, and strike a balance between
00:59:24.960 --> 00:59:30.340
having to share the session ticket
key so that it’s more effective, and
00:59:30.340 --> 00:59:35.500
not sharing the session ticket key which
makes it harder to acquire them all.
00:59:35.500 --> 00:59:41.610
You might want to do geographically
located, or in-a-single-rack…
00:59:41.610 --> 00:59:44.540
it’s really up to the deployment.
00:59:44.540 --> 00:59:47.480
Herald: Okay, final question
goes to microphone 3.
00:59:47.480 --> 00:59:51.750
Question: I have a question regarding the
GREASE mechanism that is implemented
00:59:51.750 --> 00:59:57.110
on the client side. If I understood
it correctly you are inserting
00:59:57.110 --> 01:00:02.350
random version numbers of
not-existing TLS or SSL versions
01:00:02.350 --> 01:00:08.640
and that way training
the servers to
01:00:08.640 --> 01:00:14.480
conform to the specification. What
is the result of the real-world tests?
01:00:14.480 --> 01:00:18.490
How many servers actually
are broken by this?
01:00:18.490 --> 01:00:22.780
Filippo: So you would expect none because
after all they are all implementing 1.3
01:00:22.780 --> 01:00:28.070
now, so that all the clients they would
see would already be doing GREASE. Instead
01:00:28.070 --> 01:00:33.100
just as Google enabled GREASE I think
it broke… I’m not sure so I won’t say
01:00:33.100 --> 01:00:38.330
which specific server implementation, but
one of the minor server implementations
01:00:38.330 --> 01:00:41.860
was immediately detected
as… the Haskell one!
01:00:41.860 --> 01:00:43.890
Nick: Right!
Filippo: I don’t remember the name,
01:00:43.890 --> 01:00:47.450
I can’t read Haskell, so I don’t know what
exactly they were doing, but they were
01:00:47.450 --> 01:00:49.590
terminating connections because of GREASE.
01:00:49.590 --> 01:00:53.480
Nick: And just as a note, GREASE is also
used in cipher negotiation and anything
01:00:53.480 --> 01:00:58.800
that is a negotiation in TLS 1.3.
So this actually did break
01:00:58.800 --> 01:01:03.020
a subset of servers, but
a small enough subset
01:01:03.020 --> 01:01:06.600
that people were happy with it.
01:01:06.600 --> 01:01:08.670
Question: Thanks!
Nick: 2% is too high!
01:01:08.670 --> 01:01:11.430
Herald: Thank you very much.
Filippo: Thank you!
01:01:11.430 --> 01:01:20.010
applause
01:01:20.010 --> 01:01:39.080
33C3 postroll music
01:01:39.080 --> 01:01:43.981
subtitles created by c3subtitles.de
in the year 2017. Join, and help us!