Subject: [TLS] TLS 1.3 supported versions and downgrade protection

From: Daniel Van Geest <[email-masked]>
Date: Thu, 5 Dec 2019 17:30:10 +0000

Hi all,

I think there might be ambiguity or an interoperability issue with the TLS 1.3 ServerHello Random value downgrade protection and some (possibly?) legitimate negotiation of TLS 1.2 using the supported_versions extension.  Looking through RFC 8446 and the mail archives I don’t see anything that addresses this, maybe I’ve missed something?

RFC 8446 Section 4.1.3:

   TLS 1.3 has a downgrade protection mechanism embedded in the server's
   random value.  TLS 1.3 servers which negotiate TLS 1.2 or below in
   response to a ClientHello MUST set the last 8 bytes of their Random
   value specially in their ServerHello.

   If negotiating TLS 1.2, TLS 1.3 servers MUST set the last 8 bytes of
   their Random value to the bytes:

     44 4F 57 4E 47 52 44 01

   If negotiating TLS 1.1 or below, TLS 1.3 servers MUST, and TLS 1.2
   servers SHOULD, set the last 8 bytes of their ServerHello.Random
   value to the bytes:

     44 4F 57 4E 47 52 44 00

   TLS 1.3 clients receiving a ServerHello indicating TLS 1.2 or below
   MUST check that the last 8 bytes are not equal to either of these
   values.  TLS 1.2 clients SHOULD also check that the last 8 bytes are
   not equal to the second value if the ServerHello indicates TLS 1.1 or
   below.  If a match is found, the client MUST abort the handshake with
   an "illegal_parameter" alert.

So whenever a TLS 1.3-capable server negotiates a TLS 1.2 or lower session it MUST set the appropriate Random values.

And a TLS 1.3 client MUST check for these values and abort if found. Future TLS versions aren’t mentioned so perhaps one of the use cases I’ll mention below is not a concern until the next version is defined and the behavior can be adjusted then.

Consider the potential cases for the ClientHello supported_versions values:

  1.  supported_versions = { 0x0305 (TLS 1.4), 0x0303 (TLS 1.2) }
Okay, TLS 1.4 doesn’t exist so maybe this can be addressed in the future.  If the server supports TLS 1.2 and TLS 1.3, it will negotiate TLS 1.2 and add the TLS 1.2 downgrade protection Random value.  The Client will see the TLS 1.2 version, check the downgrade protection and abort the connection.  But this is not a downgrade issue, this is the only mutually acceptable TLS version.

  2.  supported_versions = { 0x0303 (TLS 1.2), 0x0304 (TLS 1.3) }
The supported_versions list is in order of client preference, but it’s not required that the server respect the preference.  I’ve seen implementations which respect the client’s preference and ones which pick the highest mutually acceptable version.  If a server supports TLS 1.2 and TLS 1.3 and respects the client’s preference it will negotiate TLS 1.2 and add the downgrade protection random value.  The client would then abort the connection even though this would seem to be a legitimate non-downgrade situation  Or can we wave our hands at this and say if a client doesn’t prefer TLS 1.3 above TLS 1.2 then it’s not really a true Scotsman TLS 1.3 client and those MUSTs don’t really apply to it?.

And so, are these legitimate cases which should be addressed?

Thanks,
Daniel Van Geest

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 5 Dec 2019 09:35:53 -0800

> Okay, TLS 1.4 doesn’t exist so maybe this can be addressed in the future.  If the server supports TLS 1.2 and TLS 1.3, it will negotiate TLS 1.2 and add the TLS 1.2 downgrade protection Random valu…

This is analogous to the case of wanting to support TLS 1.0 and 1.2 but not 1.1, which did (IIRC) get a little bit of discussion including from Andrei Popov.  My recollection is that we didn't really feel a need to support "gaps" in supported versions for this downgrade-protection scheme.

> The supported_versions list is in order of client preference, but it’s not required that the server respect the preference.  I’ve seen implementations which respect the client’s preference and ones…

I had forgotten that we implied a potential for client preference of supported versions.  We could perhaps debate whether it's "legitimate" for a server to prefer 1.2 over 1.3, but I think it's clear that (assuming the negotiation is protected by a full transcript hash, as in 1.3 or 1.2 with extended master secret) a server negotiating 1.2 in this case should not apply the downgrade-protection scheme.

-Ben

---

From: David Benjamin <[email-masked]>
Date: Thu, 5 Dec 2019 12:48:11 -0500

On Thu, Dec 5, 2019 at 12:36 PM Benjamin Kaduk <[email-masked]> wrote:

> > I think there might be ambiguity or an interoperability issue with the
> TLS 1.3 ServerHello Random value downgrade protection and some (possibly?)
> legitimate negotiation of TLS 1.2 using the supported_versions extension.
> Looking through RFC 8446 and the mail archives I don’t see anything that
> addresses this, maybe I’ve missed something?
> >
> > RFC 8446 Section 4.1.3:
> >
> > So whenever a TLS 1.3-capable server negotiates a TLS 1.2 or lower
> session it MUST set the appropriate Random values.
> >
> > And a TLS 1.3 client MUST check for these values and abort if found.
> Future TLS versions aren’t mentioned so perhaps one of the use cases I’ll
> mention below is not a concern until the next version is defined and the
> behavior can be adjusted then.
> >
> > Okay, TLS 1.4 doesn’t exist so maybe this can be addressed in the
> future.  If the server supports TLS 1.2 and TLS 1.3, it will negotiate TLS
> 1.2 and add the TLS 1.2 downgrade protection Random value.  The Client will
> see the TLS 1.2 version, check the downgrade protection and abort the
> connection.  But this is not a downgrade issue, this is the only mutually
> acceptable TLS version.
>
> This is analogous to the case of wanting to support TLS 1.0 and 1.2 but
> not 1.1, which did (IIRC) get a little bit of discussion including from
> Andrei Popov.  My recollection is that we didn't really feel a need to
> support "gaps" in supported versions for this downgrade-protection scheme.
>

Prior to supported_versions we didn't have gaps at all. We can now do gaps,
but only starting at TLS 1.3. You're right that gaps which span TLS 1.3 are
problematic. This is related to why we couldn't ship the downgrade signal
in early draft deployments.

Note TLS is still downgrade-protected without this signal by way of the
transcript. The signal fixes some fragilities in the downgrade when you get
all the way down to TLS 1.2.

> > The supported_versions list is in order of client preference, but it’s
> not required that the server respect the preference.  I’ve seen
> implementations which respect the client’s preference and ones which pick
> the highest mutually acceptable version.  If a server supports TLS 1.2 and
> TLS 1.3 and respects the client’s preference it will negotiate TLS 1.2 and
> add the downgrade protection random value.  The client would then abort the
> connection even though this would seem to be a legitimate non-downgrade
> situation  Or can we wave our hands at this and say if a client doesn’t
> prefer TLS 1.3 above TLS 1.2 then it’s not really a true Scotsman TLS 1.3
> client and those MUSTs don’t really apply to it?.
>
> I had forgotten that we implied a potential for client preference of
> supported versions.  We could perhaps debate whether it's "legitimate" for
> a server to prefer 1.2 over 1.3, but I think it's clear that (assuming the
> negotiation is protected by a full transcript hash, as in 1.3 or 1.2 with
> extended master secret) a server negotiating 1.2 in this case should not
> apply the downgrade-protection scheme.
>

(FWIW, our server implementation uses server preference and doesn't pay
attention to the client order.)

Having the server sometimes omit the "PS: I support TLS 1.3" signal in TLS
1.2 ServerHellos would break the protection. The ServerHello random signal
is a hardening measure because TLS 1.2 failed to include the entire
handshake transcript in the ServerKeyExchange signature, only the randoms.
As a result the downgrade protection is rather fragile. This signal takes
advantage of the few pieces which are signed. But because the signature
does not include the ClientHello which triggered it, it's important that
*all* TLS 1.2 ServerHellos from the server include it.

I think a client which advertises something like (2) probably shouldn't
enforce the signal because it apparently doesn't actually prefer TLS 1.3
over TLS 1.2. Better yet, don't advertise (2). :-)

David