Subject: [TLS] PR for anti-downgrade mechanism

From: Eric Rescorla <[email-masked]>
Date: Fri, 9 Oct 2015 14:23:30 +0200

Hi folks,

Please take a look at the following PR which documents a suggestion
made by Karthik Bhargavan about how to prevent protection against
downgrade against downgrade from TLS 1.3 to TLS 1.2 and below.

  https://github.com/tlswg/tls13-spec/pull/284

The idea is that if a TLS 1.3 server receives a TLS 1.2 or below
ClientHello, it sets the top N bits of the ServerRandom to be a
specific fixed value. TLS 1.3 clients which receive a TLS 1.2 or below
ServerHello check for this value and abort if they receive it. This
allows for detection of downgrade attacks over and above the Finished
handshake as long as ephemeral cipher suites are used (because the
signature on the ServerKeyExchange covers the random values). No
protection is provided for static RSA cipher suites, but this still
has some value if you have an attack which only affects (EC)DHE.

I've written this up with 48 bits and a specific fixed value (03 04 03
04 03 04) but that's just a strawman and we can bikeshed on that if
people think this is a good idea.

Thanks,
-Ekr

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Fri, 9 Oct 2015 14:48:38 +0200

A few more words on this proposal.

- The goal is to protect TLS 1.3 clients and servers from attacks on TLS 1.* ciphersuites.
   E.g. if a new attack on the MD5 | SHA1 concatenation in TLS 1.0 is announced, 
   connections between TLS 1.3 clients and servers would still be protected.
   Similarly, if the Apache default 1024-bit DHE group is broken, connections between
   TLS 1.3 clients and servers remain unaffected.
   (In the current TLS 1.3 design, an attacker could downgrade the connection and break
    it in both these cases. No, the fallback SCSV does not help.)

- We propose to fix the first N bits of the server random, but we can carry whatever information we want here.
   Protocol version + ciphersuite sounds like a good start to use up 4 bytes.
   (This would, for example, have protected TLS 1.2 against the Logjam attack on TLS 1.0.)

- The key idea is that the server random is signed even in older versions of TLS, and so
   we will get downgrade protection for free, without modifying these older versions in any way.
   (A protocol extension for TLS 1.* would not work, since the extension itself could be deleted by the attacker.)

- The first 4 bytes were traditionally used for a timestamp, so using (say) 4 bytes in a new way 
  does not lose entropy/replay-protection in comparison for servers that implement timestamps. 
  However, we do lose some replay-protection when compared to servers that use the full 32 bytes. 

- There is a 1/(2^N) chance that valid connections to TLS 1.2 servers will be dropped by
   TLS 1.3 clients, because of this proposal. This only happens for servers that do not 
   use the unix timestamp (the current timestamp is greater than 0304xxxx).
   Still, we need to carefully choose N so that this risk of connection dropping is acceptable.

- The proposed mechanism only protects TLS 1.3 clients and servers that exclusively support 	
   signature-based ciphersuites (DHE/ECDHE) even for older versions of TLS. E.g. it does not 
   protect against downgrade to RSA or PSK ciphersuites. 

- We note that RSA ciphersuites already provide a version downgrade mitigation, 
  although it has itself caused many headaches due to bleichenbacher attacks.
  But if a server implements good side-channel resistance to bleichenbacher attacks,
  TLS 1.3 can be protected from downgrades to both RSA and (EC)DHE ciphersuites in
  older protocol versions.

> On 09 Oct 2015, at 14:23, Eric Rescorla <[email-masked]> wrote:
> 
> Hi folks,
> 
>   https://github.com/tlswg/tls13-spec/pull/284 <https://github.com/tlswg/tls13-spec/pull/284>
> 
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

---

From: "Yngve N. Pettersen" <[email-masked]>
Date: Fri, 09 Oct 2015 13:02:20 -0000

>   TLS 1.3 can be protected from downgrades to both RSA and (EC)DHE  

For reference, the version field in the TLS premaster secret is not  
checked by many servers, IIRC some of them have large market shares.

-- 
Sincerely,
Yngve N. Pettersen

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Fri, 9 Oct 2015 15:09:36 +0200

> For reference, the version field in the TLS premaster secret is not checked by many servers, IIRC some of them have large market shares.

That’s good to know. It would be tempting to recommend that TLS 1.3 servers disable RSA (encryption) ciphersuites for all protocol versions, but I guess this is not likely to happen for backwards compatibility reasons?

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 9 Oct 2015 15:16:49 +0200

On Fri, Oct 9, 2015 at 3:09 PM, Karthikeyan Bhargavan <
[email-masked]> wrote:

> That’s good to know. It would be tempting to recommend that TLS 1.3
> servers disable RSA (encryption) ciphersuites for all protocol versions,
> but I guess this is not likely to happen for backwards compatibility
> reasons?

This seems like RFC 6919 Territory:
https://tools.ietf.org/html/rfc6919#section-1

-Ekr

---

From: "Short, Todd" <[email-masked]>
Date: Fri, 9 Oct 2015 13:23:18 +0000

On Oct 9, 2015, at 8:48 AM, Karthikeyan Bhargavan <[email-masked]<mailto:[email-masked]>> wrote:

I’m thinking this chance can be reduced to 0.
Wouldn’t a TLSv1.3 client be able to recognize that it’s connecting to a TLSv1.2 server, and not parse the first N bits of the server random?

--
-Todd Short
// [email-masked]<mailto:[email-masked]>
// "One if by land, two if by sea, three if by the Internet."

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 9 Oct 2015 15:42:24 +0200

On Fri, Oct 9, 2015 at 3:23 PM, Short, Todd <[email-masked]> wrote:

>
>
> On Oct 9, 2015, at 8:48 AM, Karthikeyan Bhargavan <
> Wouldn’t a TLSv1.3 client be able to recognize that it’s connecting to a
> TLSv1.2 server, and not parse the first N bits of the server random?
>

The idea is to distinguish this case from the case where they are
connecting to
an attacker pretending to be a TLS 1.2 server.

-Ekr

--
> // [email-masked]

---

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 9 Oct 2015 16:49:02 +0000

> has some value if you have an attack which only affects (EC)DHE.

I think this is "too clever" (a "hack" not a design) and offers
incomplete protection (does nothing to protect RSA key transport).
So I do not support adoption of this proposal.

If new attacks against TLS 1.0--1.2 emerge that enable MITM via
version downgrade combined with use of weaker algorithms, then
we'll just have to prohibit those weaker algorithms in TLS 1.3
servers (and possibly also clients).

-- 
	Viktor.

---

From: Dave Garrett <[email-masked]>
Date: Fri, 9 Oct 2015 16:14:05 -0400

> I think this is "too clever" (a "hack" not a design) and offers

Every fix to an issue in this 20 year old protocol will be a hack.

> incomplete protection (does nothing to protect RSA key transport).

Better than none, for a very low cost.

> servers (and possibly also clients).

Those changes are harder to make than they should be, unless we want to do that now.

Dave

---

From: Dave Garrett <[email-masked]>
Date: Fri, 9 Oct 2015 16:15:54 -0400

On Friday, October 09, 2015 08:23:30 am Eric Rescorla wrote:
> specific fixed value.
[...]
> people think this is a good idea.

I support this, though I would like to know why 6 bytes was chosen instead of just 4. I don't object; I would just like to know the reasoning here.

Dave

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 9 Oct 2015 22:23:09 +0200

It's largely arbitrary, but the reasoning is as follows. There are
apparently
some TLS 1.2 servers which randomly generate the entire server random
(and https://tools.ietf.org/html/draft-mathewson-no-gmtunixtime-00 would
encourage more to do so). The chance of a false positive between such
a server and a TLS 1.3 client is 2^{-32}, which seemed a bit high.

-Ekr

On Fri, Oct 9, 2015 at 10:15 PM, Dave Garrett <[email-masked]>
wrote:

> I support this, though I would like to know why 6 bytes was chosen instead
> of just 4. I don't object; I would just like to know the reasoning here.
>
>
> Dave
>

---

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 9 Oct 2015 20:38:00 +0000

On Fri, Oct 09, 2015 at 10:23:09PM +0200, Eric Rescorla wrote:

> apparently some TLS 1.2 servers which randomly generate the entire server
> random (and https://tools.ietf.org/html/draft-mathewson-no-gmtunixtime-00 would

Yes, law of large numbers.  While any one session is unlikely to
fail, the chance of some sessions failing needlessly becomes
appreciable, and some of failures may be have high criticality and
be latency sensitive.  

Of course packet corruption undetected by TCP checksums is perhaps
more likely, and the client should treat this like as data corruption,
rather than a MITM attack, and just reconnect and try again.

The problem is that reconnecting is not something the TLS layer
can do.  And applications might not be instrumented to recover as
quickly or as gracefully as they should.  Plus, not all use of TLS
is over unreliable network transports.  TLS is also used over Unix
domain sockets, where one does not expect either MITM attacks or
data corruption.

So even 2^{-48} is perhaps not quite low enough.  I still think
we're better off fixing serious problems in TLS 1.2 as we find
them regardles of whether the server and client happen to also
support 1.3.

-- 
	Viktor.

---

From: Dave Garrett <[email-masked]>
Date: Fri, 9 Oct 2015 16:49:45 -0400

On Friday, October 09, 2015 04:38:00 pm Viktor Dukhovni wrote:
> So even 2^{-48} is perhaps not quite low enough.

Going to a full 64-bit looks like a good idea to me. The loss of those 4 bytes of entropy for old versions isn't likely to matter at all, though, please correct me if someone thinks otherwise.

On a related note, I think it might be a good idea to add a note somewhere stating that TLS 1.3 now only uses the hello random values indirectly, but they're still used via the session hash.

On a tangential note, if anyone sees the need to increase the entropy introduced in the hellos, a supplemental random extension sent by both endpoints would be trivial to create with the current design. (questioning the size of the randoms here is an explicit question in the current TLS WG charter, as is the topic of additional downgrade mechanisms)

Dave

---

From: "Salz, Rich" <[email-masked]>
Date: Fri, 9 Oct 2015 20:59:05 +0000

> It's largely arbitrary, but the reasoning is as follows.

And so that we can put "TLS1.3" as the six bytes in UTF-8.

---

From: Brian Smith <[email-masked]>
Date: Fri, 9 Oct 2015 12:40:58 -1000

> ClientHello, it sets the top N bits of the ServerRandom to be a

1. Why would the server ever receive a TLS 1.2 or below ClientHello from a
client that supports TLS 1.3? Why doesn't the already-standardized
downgrade SCSV mechanism work for those cases?

2. My understanding is that every TLS 1.3 ClientHello contains a
ClientKeyShare extension and that no TLS 1.2 or below ClientHello contains
a ClientKeyShare extension. Therefore, the presence or absence of the
ClientKeyShare extension already signals whether the client is attempting a
TLS 1.3 handshake, or a handshake for a lower TLS version. Thus, also
specifying ClientHello.client_version = 0x0304 is redundant. And, we've
already seen clear evidence that ClientHello.client_version = 0x0304 leads
to severe compatibility issues. So, why not just use
ClientHello.client_version = 0x0303 and rely on the presence of the
ClientKeyShare extension to disambiguate TLS 1.3 vs TLS 1.2 or below?

Cheers,
Brian

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Sat, 10 Oct 2015 03:01:48 +0200

> 1. Why would the server ever receive a TLS 1.2 or below ClientHello from a client that supports TLS 1.3? Why doesn't the already-standardized downgrade SCSV mechanism work for those cases?

The attack we’re protecting against is the following:
- a TLS 1.3 client sends a client hello and the MitM changes the version field to TLS 1.0 (say) with some weak signature-based ciphersuite (e.g. DHE/DHE-EXPORT + AES-CBC)
- for good measure, the MitM also drops any protocol extensions that are inconvenient (e.g. FFDHE/extended master secret/…)
- the TLS 1.3 server thinks the client does not support TLS 1.3 and so falls back to the requested protocol
- in TLS 1.0, the server signature does not include the version, ciphersuite, or extensions, so the client accepts the server flight and computes a master secret and finished message

Now, the crucial step is that if the downgraded protocol is so weak that the attacker can (with some computational effort) forge the server’s finished message, the connection will complete.
There are some instances in which the attacker may be able to achieve this: by breaking SHA-1, or a weak DHE group, by redoing some variation of the triple handshake attack, or by 
exploiting some software bug in a rarely used low-preference ciphersuite. Note that the client did not fallback, the server did, so Fallback SCSV does not apply.

The key observation is that downgrade protection in TLS 1.2 (and below) relies on the Finished MAC, but the elements that go into computing this MAC (DH group, hash algorithm)
are themselves negotiated within the handshake and may be downgraded. This is a fundamental protocol limitation that is addressed by TLS 1.3. Now, our goal is to protect TLS 1.3 itself
from older protocol versions.

From an academic researcher’s viewpoint, there are two reasons to suggest such a countermeasure. 
1) Historically, signalling the ciphersuite in the server signature would have prevented high-profile attacks like FREAK, Logjam, and the cross-protocol attack between ECDHE/DHE in 2012.
    I agree that trying to protect from potential attacks may seem speculative, but the idea is to provide some additional protection against future attacks even if all TLS clients and servers are not immediately patched.
2) Looking forward, a number of researchers would like to give a strong security theorem for TLS 1.3, but at present we would not be able to guarantee security for any TLS 1.3 implementation 
    that also implements older protocol versions, because we would then also have to prove secure all the ciphersuites used in these old versions (some of which are certainly broken from the
    point of view of provable security). For our proofs, we’d like nothing better than to be able to assume that older versions of TLS have been disabled, but I guess that is unlikely to happen soon.

It would have been nice not to rely on a “clever” trick, but we could not see how else to add any mechanism that could itself not be deleted by an attacker in older versions. 
TLS has a long history of signalling downgrades in strange ways.  The RSA PMS still includes the protocol version due to an old SSL3->SSL2 downgrade attack. 
The Fallback SCSV is a signal encoded in a bogus ciphersuite, because SSL3 does not support extensions. 
These are all unfortunate hacks, made necessary by the limited handshake protections in older versions.
The chief benefit is that we can then protect clients and servers that implement our brand new protocol version.

Best,
Karthik

---

From: Dave Garrett <[email-masked]>
Date: Fri, 9 Oct 2015 22:44:55 -0400

There is one problem with the current proposed sentinel value, 0x030403040304. It limits what can be done with future versions. It's not as simple as just making that use 0x030503050305, because we want 1.3 clients to be able to recognize sentinel values from all future versions, not just this one. Thus, for future proofing, (just) using the version number isn't a great idea. It's probably safest to just pick one static value and be done with it forever.

And now, for my proposed bikeshed color:

0x0b501e7e5e1ec7ed
("obsoleteselected"; 64-bit value)

I'd like to say I was clever enough to come up with neat hex words, but I Googled for a list and found 2 to put together. ;)

Dave

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 10 Oct 2015 16:30:57 +0200

On Sat, Oct 10, 2015 at 4:44 AM, Dave Garrett <[email-masked]>
wrote:

> There is one problem with the current proposed sentinel value,
> 0x030403040304. It limits what can be done with future versions. It's not
> as simple as just making that use 0x030503050305, because we want 1.3
> clients to be able to recognize sentinel values from all future versions,
> not just this one. Thus, for future proofing, (just) using the version
> number isn't a great idea. It's probably safest to just pick one static
> value and be done with it forever.
>

That may be true, but then this value is as good as any other.

An alternative would be to burn N-8 bits on a sentinel and then
8 bits on the version number. E.g.,

01 02 03 04 05 34  [0]

BTW, I'm basically indifferent between 48 and 64 bits.

-Ekr

[0] I didn't use 00 00 00 00 00 as the sentinel because I have some vague
memory
that there are implementations which use 0s in the timestamp.

And now, for my proposed bikeshed color:
> I'd like to say I was clever enough to come up with neat hex words, but I
> Googled for a list and found 2 to put together. ;)
>
>
> Dave
>

---

From: Brian Smith <[email-masked]>
Date: Fri, 16 Oct 2015 09:22:06 -1000

Karthikeyan Bhargavan <[email-masked]> wrote:

> [snip]

The key observation is that downgrade protection in TLS 1.2 (and below)
> relies on the Finished MAC, but the elements that go into computing this
> MAC (DH group, hash algorithm)
> are themselves negotiated within the handshake and may be downgraded. This
> is a fundamental protocol limitation that is addressed by TLS 1.3. Now, our
> goal is to protect TLS 1.3 itself

Thanks for explaining. I think this is a good idea.

Why only protect TLS 1.3 from such a downgrade? I think it is worthwhile to
protect TLS 1.2 from the downgrade too, in a similar way. Or, is there
something specific about TLS 1.3 that makes the downgrade worse?

> 2) Looking forward, a number of researchers would like to give a strong
> security theorem for TLS 1.3, but at present we would not be able to
> guarantee security for any TLS 1.3 implementation
>     that also implements older protocol versions, because we would then
> also have to prove secure all the ciphersuites used in these old versions
> (some of which are certainly broken from the
>     point of view of provable security). For our proofs, we’d like nothing
> better than to be able to assume that older versions of TLS have been
> disabled, but I guess that is unlikely to happen soon.
>

No doubt it is more interesting to work on TLS 1.3. But, I think that it
would also be useful to have such work done, insofar as it is possible, for
at least a subset of TLS 1.2--e.g. the subset that is used in DICE, which
prescribes TLS 1.2. I understand that the people working on proofs for TLS
1.3 may not be the same ones that might undertake the work for TLS 1.2.

Cheers,
Brian
-- 
https://briansmith.org/

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Oct 2015 13:04:23 -0700

> something specific about TLS 1.3 that makes the downgrade worse?

Given that we can't expect TLS 1.2 servers to implement the hack, I'm
not sure that this is of great utility, but if we can bake a version
number in there, I'm not opposed to the notion.

---

From: Brian Smith <[email-masked]>
Date: Fri, 16 Oct 2015 10:39:24 -1000

> number in there, I'm not opposed to the notion.

I think TLS 1.2 servers would implement the mechanism, if it were
documented in an update to the downgrade-scsv document. I mean, this
mechanism is basically a replacement for the downgrade-scsv mechanism,
because the downgrade-scsv mechanism doesn't (at least, can't be proven) to
work, right? That would be especially true for an implementation that does
False Start for TLS 1.2.

Cheers,
Brian
-- 
https://briansmith.org/

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Oct 2015 15:12:18 -0700

On 16 October 2015 at 13:39, Brian Smith <[email-masked]> wrote:
> That would be especially true for an implementation that does False Start
> for TLS 1.2.

I don't see how false start plays into this.  We could have clients
reject false start if they see this sentinel value.  But don't we want
to just treat this as an attack and abort instead?

---

From: Brian Smith <[email-masked]>
Date: Fri, 16 Oct 2015 12:34:28 -1000

> to just treat this as an attack and abort instead?

Yes. The client needs the sentinel to know to abort the connection, if its
willing to false start with TLS 1.2 when it also support TLS 1.3, right?

Cheers,
Brian
-- 
https://briansmith.org/

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Sat, 17 Oct 2015 08:23:29 +0200

Hi Brian, yes, the mechanism proposed here could also be used by TLS 1.2
implementations to signal each other about their preferred connection parameters.

To make most use of the bytes provided, one could use the sentinel value to indicate 
support for an extension, which then carries a signed server configuration of arbitrary size. 
The attacker would then be unable to downgrade the connection by deleting this extension.

False Start is an interesting use case, because 
(a) it sends data before the server has confirmed the chosen version/ciphersuite/etc and 
(b) it already tries to prevent downgrades by whitelisting versions and ciphersuites. 
Some downgrade attacks fail because of (b), but others are easier to exploit because of (a).
For example, Logjam was easier to mount on False Start clients since the attacker could 
collect the False Start data and decrypt it at leisure.  

Extended master secret (EMS) provides some additional protection to False Start, because the encryption
keys implicitly include the full handshake transcript and, so if the MitM tampers with the connection,
the False Start data would not be accepted by a server. (However, that this would not have prevented Logjam.)
Moreover, even the EMS extension can be deleted by a MitM. 
The current proposal could protect EMS from downgrade by indicating support for it in the server hello.

To sum up, we’re focusing on TLS 1.3 because we have a chance to bake in strong downgrade protection
into its implementations from the very beginning. I think this could be useful for older versions too, as an optional
mechanism which protects clients and servers that both implement it, and does not affect others.

-Karthik

> On 17 Oct 2015, at 00:34, Brian Smith <[email-masked]> wrote:
> 
> On Fri, Oct 16, 2015 at 12:12 PM, Martin Thomson <[email-masked] <mailto:[email-masked]>> wrote:
> On 16 October 2015 at 13:39, Brian Smith <[email-masked] <mailto:[email-masked]>> wrote:
> Yes. The client needs the sentinel to know to abort the connection, if its willing to false start with TLS 1.2 when it also support TLS 1.3, right?
> 
> Cheers,
> Brian
> -- 
> https://briansmith.org/ <https://briansmith.org/>
>

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 11:35:35 -0700

Trying to close the loop on this, I think people are generally in favor of
this
mechanism, so we just need a concrete construction.

I propose we use an N bit field divided as follows

- N - 8 bits of fixed sentinel.
- 8 bits of version number with the semantics being the highest TLS version
  number supported by the server, encoded with the high nibble being
  the major version and the low version being the minor version. So,
  concretely a TLS 1.3 implementation would use 0x34 here.

I imagine people have opinions about N and the sentinel, but for
concreteness
I suggest that N = 64 bits, and that we use the ASCII string
'DOWNGRD' as the sentinel.

Let the bikeshedding begin!

-Ekr

On Fri, Oct 16, 2015 at 11:23 PM, Karthikeyan Bhargavan <
[email-masked]> wrote:

> into its implementations from the very beginning. I think this could be
> useful for older versions too, as an optional
> On Fri, Oct 16, 2015 at 12:12 PM, Martin Thomson <[email-masked]
> > wrote:
>

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 17 Oct 2015 19:00:37 +0000

> Let the bikeshedding begin!

IIRC for TLS >= 1.3 the entire server hello (as part of a session
transcript digest that includes it) is signed with the key exchange.
So TLS 1.3 already protects against rollbacks from 1.4 to 1.3.

If so, is it necessary to have a variable high octet?  Just a single
fixed patter signalling ">= 1.3" would then suffice.

I must admit to not have looked closely, so perhaps wrong end of
the stick...  If the above is however correct, I think simpler is
better, over-engineering this work-around "side-channel" is I think
unwise.  This seems to be a protection against rollback to TLS <
1.3, for TLS >= 1.3, the protocol should solve any issues more
naturally than by overloading the server-random.

-- 
	Viktor.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 12:03:32 -0700

> So TLS 1.3 already protects against rollbacks from 1.4 to 1.3.

Hopefully, yes.

If so, is it necessary to have a variable high octet?

Note: I am proposing this in the low octet. Not that it's that
important either way.

> Just a single

If you wanted to cover 1.2 -> 1.1, then you would want this.

-Ekr

---

From: Martin Thomson <[email-masked]>
Date: Sat, 17 Oct 2015 12:10:18 -0700

> If you wanted to cover 1.2 -> 1.1, then you would want this.

The observation is still valuable in the sense that prohibiting values
> 1.3 would reduce the likelihood of a false positive by some
miniscule amount.  In other words, I agree with ekr here, though we
could cap the value to 1.3.

Maybe we could just define two values: one for TLS 1.3 (and greater,
presumably) and one for TLS 1.2.  I don't see any value in protecting
1.1 or 1.0 from downgrade any more given relative prevalence of those
protocols and their age.

---

From: Dave Garrett <[email-masked]>
Date: Sat, 17 Oct 2015 17:08:16 -0400

> 1.1 or 1.0 from downgrade any more given relative prevalence of those

Two values seems like a good compromise to me if one isn't considered sufficient. I don't particularly want them changing in the future so old (e.g. TLS 1.3, in a future with TLS 1.4+) implementations don't need to worry about seeing something new here and making a mistake. Checks would be for one of two 64-bit values, rather than 56-bit values with a byte with a possibly unknown value.

Dave

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 14:16:49 -0700

On Sat, Oct 17, 2015 at 2:08 PM, Dave Garrett <[email-masked]>
wrote:

> Two values seems like a good compromise to me if one isn't considered
> sufficient. I don't particularly want them changing in the future so old
> (e.g. TLS 1.3, in a future with TLS 1.4+) implementations don't need to
> worry about seeing something new here and making a mistake. Checks would be
> for one of two 64-bit values, rather than 56-bit values with a byte with a
> possibly unknown value

My assumption here was that the client would do the following:

1. Look to see if the server negotiated its highest version. If so, then
all is good.
2. If the server did not negotiate the highest version, then look for the
sentinel.
    If it's set, you have a downgrade.
3. (Optional) If you have a downgrade, parse the last byte to see the
server's actual version.
    In any case, abort.

What have I missed?

-Ekr

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 17 Oct 2015 21:28:06 +0000

>From my perspective, there's not much benefit to knowing the actual
version, and an unnecessary loss of 7 to 8 bits of protection
against false positives with actually random input from legacy
peers.

If it is "in any case abort", why waste bits on the version.  If
56 bits are enough FP-protection, use the rest for real randomness
in the server-random.  If just to be safe the FP protection is 64
bits, fix those bits, except perhaps 1 to indicate 1.2 vs. >= 1.3
(if this mechanism is intended to be "backported" to TLS 1.2
systems).

-- 
	Viktor.

---

From: Dave Garrett <[email-masked]>
Date: Sat, 17 Oct 2015 17:34:26 -0400

> 3. (Optional) If you have a downgrade, parse the last byte to see the

A 64-bit sentinel can be trivially checked as a 64-bit uint. If we have an open-ended series, we could have implementations checking for a set of 64-bit integers rather than a 56-bit followed by another byte to be inspected. I'm being paranoid, yes, but it's simpler just to have a round number bits value or two and I don't think you get much by encoding further information.

It also has a slightly better collision risk, though it's already down quite low.

Dave

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 14:53:57 -0700

On Sat, Oct 17, 2015 at 2:34 PM, Dave Garrett <[email-masked]>
wrote:

> A 64-bit sentinel can be trivially checked as a 64-bit uint.

And a 56-bit value can be trivially checked by masking off the last byte.
Or, memcmp().

If we have an open-ended series, we could have implementations checking for
> a set of 64-bit integers,rather than a 56-bit followed by another byte to
> be inspected.

As noted, nobody is making you check it.

> I'm being paranoid, yes, but it's simpler just to have a round number bits
> value or two and I don't think you get much by encoding further information.
>
> It also has a slightly better collision risk, though it's already down
> quite low

Given that the TCP checksum has a false negative rate far higher than
2^{-56} and
any TCP errors cause TLS handshake failures, this doesn't seem like much of
an argument.

-Ekr

---

From: Dave Garrett <[email-masked]>
Date: Sat, 17 Oct 2015 18:04:47 -0400

> And a 56-bit value can be trivially checked by masking off the last byte.

My point is that one is more trivial and someone might check for 64 when they shouldn't be. It's the same thought process that deals with bad user agent sniffing; developers come up with algorithms that are ideal now, not necessarily in the future.

It's not a world-ending complaint, but I do think it's simpler to just use a uint64 or 2.

> any TCP errors cause TLS handshake failures, this doesn't seem like much of

I'll concede the collision risk argument on that point, then. As I said, already smaller than it was in the first proposal.

Dave

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 17 Oct 2015 22:05:48 +0000

> any TCP errors cause TLS handshake failures, this doesn't seem like much of

This argument is not complete.  The false negative rate from TCP
is not by itself sufficient to determine the observed error rate.
One needs to combine that with the undetected error rate from
underlying network to obtain the frequency of TCP errors that
percolate up to the TLS layer.

There are of course also errors in the memory subsystem, or machine
crashes, ... that all interrupt TLS connections.

Indeed 2^{-64} is a very low error probability, it is I would guess
substantially smaller that any of the other possible error sources,
and this is a good thing.

The question is not so much whether 48, 56 or 64 bits is the right
amount of protection against random false positives, though if 64
bits is way overkill and the original 48 is more than enough, we
could look more closely at that.  Rather, I think the question is
whether this work-around should be as simple as possible, or should
be a more feature-full new sub-protocol.  I'm in the keep it simple
camp (if we should do this at all).

-- 
	Viktor.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 15:10:01 -0700

> percolate up to the TLS layer.

A bit old but see:
http://www.ir.bbn.com/documents/articles/crc-sigcomm00.pdf

"After an analysis we conclude that the checksum will fail to detect
errors for roughly 1 in 16 million to 10 billion packets".

-Ekr

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 17 Oct 2015 22:17:33 +0000

> errors for roughly 1 in 16 million to 10 billion packets".

That's all fine and good, but my point is that this is a distraction.
Though the specific numbers depend greatly on the underlying layer-2
networks traversed by the TCP frame, let's accept the 1:10^10
estimate, in which case anything better than ~2^{-40} is quite
enough.  If so, send a shorter sentinel.

> > camp (if we should do this at all).

However, the question of simplicity still remains...  I would go
with at most a 1 bit field for "TLS 1.2" vs. "TLS 1.3" in whatever
length sentinel is used.

-- 
	VIktor.

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 17 Oct 2015 15:20:08 -0700

> enough.  If so, send a shorter sentinel.

Sure, that's fine. I'm simply dispensing with arguments that we need to
avoid sending a version because we need the bits to avoid false
positives.

> with at most a 1 bit field for "TLS 1.2" vs. "TLS 1.3" in whatever

I don't feel strongly about this, but I don't see how what you suggest
is any simpler than the version number encoding I proposed.  Arguably,
it's more complicated since you can't implement the sentinel check with
memcmp().

-Ekr

---

From: Viktor Dukhovni <[email-masked]>
Date: Sat, 17 Oct 2015 23:02:58 +0000

> it's more complicated since you can't implement the sentinel check with

The simplicity I have in mind minimality of the design, not so much
the implementation.  

The bit in question could be the high bit of of the first octet of
server random.  The code doing the comparing would need a mutable
copy of the test value, and would clone the bit in question from
the input to the test value, then memcmp.

	tls13 = peerrand[0] & 0x80;
	sentinel[0] = tls13 | (sentinel[0] & 0x7f);
	if (memcmp(srand, test, len) == 0) {
	    if (tls13) {
		/* Peer indicates TLS >= 1.3 support */
		...
	    } else {
		/* Peer indicates TLS 1.2 support */
		...
	    }
	}

-- 
	Viktor.

---

From: "Short, Todd" <[email-masked]>
Date: Mon, 19 Oct 2015 14:37:50 +0000

Does the sentinel have to be the first N bytes?

RFC 5246 (S7.4.1.2) specifies Random as a combination of a uint32 time value and 28 random bytes.

Rather than risk breaking backwards compatibility by changing the definition of the first 4 bytes, perhaps the sentinel can be moved to another location within the ServerRandom field? Either the  second set of N bytes or the last set of N bytes? Where the sentinel is located shouldn’t really matter. Subsequently, the sentinel can be chosen with more freedom. As I recall, one reason (but not the only reason) the length was extended to 8 bytes due to the gmt_unix_time issue; is an 8-byte sentinel still needed if it’s not overlapping the gmt_unix_time (yes, I’m concerned about a reduction of entropy by 25%)?

In extending this, should the ClientHello random value also include the sentinel? (Yes, I know this again reduces entropy.) A MITM can implement a downgrade attack in either direction. The server can terminate the connection that much earlier. (Risk: ~2^{-64} that an older client might be rejected for having a mismatched sentinel/version.)

Viktor Dukhovni had proposed a ~5 byte sentinel:

struct {
    uint32 gmt_unix_time;
    opaque random_bytes[23];
    uint8 sentinel[5];
} Random;

On Oct 17, 2015, at 7:02 PM, Viktor Dukhovni <[email-masked]<mailto:[email-masked]>> wrote:

--
Viktor.

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

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 19 Oct 2015 08:08:32 -0700

On Mon, Oct 19, 2015 at 7:37 AM, Short, Todd <[email-masked]> wrote:

> Rather than risk breaking backwards compatibility by changing the
> definition of the first 4 bytes, perhaps the sentinel can be moved to
> another location within the ServerRandom field? Either the  second set of N
> bytes or the last set of N bytes? Where the sentinel is located shouldn’t
> really matter. Subsequently, the sentinel can be chosen with more freedom.
> As I recall, one reason (but not the only reason) the length was extended
> to 8 bytes due to the gmt_unix_time issue; is an 8-byte sentinel still
> needed if it’s not overlapping the gmt_unix_time (yes, I’m concerned about
> a reduction of entropy by 25%)?
>

Maybe it's because I haven't had my coffee yet, but ISTM that overloading
the time field
lowers the risk of false positives because we can choose a sentinel that
will never
collide with a conformant TLS 1.2 ServerHello. By contrast, a sentinel in
the
randomly generated portion always has a 2^{-n} chance of collision.

> In extending this, should the ClientHello random value also include the
> sentinel? (Yes, I know this again reduces entropy.) A MITM can implement a
> downgrade attack in either direction. The server can terminate the
> connection that much earlier
>

How does this help? The attacker will just rewrite the ClientHello.random.

-Ekr

---

From: David Benjamin <[email-masked]>
Date: Mon, 19 Oct 2015 15:31:26 +0000

> randomly generated portion always has a 2^{-n} chance of collision.

If I'm understanding things correctly, servers which expect to be the
target of tools like tlsdate (or aren't sure) will be unable to deploy this
mechanism if the sentinel collides with gmt_unix_time. If you're not sure
whether you care about tlsdate, you at least risk some compatibility
problems with anything that might have been making assumptions here.

It seems slightly strange to me to say the reason to do it this way is that
we don't risk collision with conformant TLS 1.2 ServerHellos. The reason
it's not a collision is because it means servers (supporting TLS 1.3) are
now required to produce non-conformant TLS 1.2 ServerHellos.

David

---

From: Martin Thomson <[email-masked]>
Date: Mon, 19 Oct 2015 10:05:02 -0700

On 19 October 2015 at 08:08, Eric Rescorla <[email-masked]> wrote:
> overloading the time field

Yes, this is right.  The marginal gain is that the proportion of
servers that generate a time here are immune to collisions.  If
servers all servers did that, we wouldn't have to worry about
collisions at all. Unfortunately, we do know that some generate random
values.