Subject: [TLS] Tickets and cross protocol attacks

From: Subodh Iyengar <[email-masked]>
Date: Tue, 29 Mar 2016 16:48:13 +0000

Recent attacks like SLOTH, DROWN, PCKS1.5 padding oracles have shown that attacks on previous version of TLS can be used to attack new version of TLS.

One thing that is not mandated by TLS 1.3 is separation of session tickets and session ids between TLS protocols. For example a client could use a ticket negotiated with a previous version of TLS with TLS1.3. This could result in interesting situations:

1. Bypassing client auth
If a server restricts a super-secure resource only over TLS1.3 with client auth and also shares ticket keys across TLS1.2 and TLS1.3. If an attacker has a SLOTH client impersonation attack against TLS1.2, they can get a TLS ticket from TLS1.2 connection issued by a server. The ticket would have the original client auth encrypted in it. The attacker could then use the ticket with TLS1.3 PSK resumption and authenticate as the original client.

2. PSK 0-RTT
If the client agrees to use the ticket negotiated over a previous TLS1.2 connection in a subsequent handshake as the PSK for 0-RTT TLS1.3. An attacker that has a SLOTH attack for server impersonation could inject their own TLS ticket into the connection with a client in a TLS1.2 handshake. The 0-RTT data would be encrypted with an attacker known key and they could decrypt the 0-RTT data. If the connection continues to use PSK, the attacker can decrypt more data, however if the connection uses PSK + (EC)DHE then the attackers capability will be limited to decrypting the 0-RTT data.

3. Using DROWN style attacks
The ticket from a TLS1.3 handshake can be used in the context of a TLS1.0 - TLS1.2 handshake. This might cause interesting new attacks to open up where a TLS1.3 ticket is forwarded to a TLS1.0 - TLS1.2 server.

Even if a server enforces strict key separation between different TLS versions (which is very difficult), if tickets or session ids are reusable across TLS versions either on the client or the server, I believe these types of attacks remain possible.

We could consider adding a section detailing the requirements for tickets for security. Even though there is a recommended construction, we could require a few things for the security of TLS 1.3:
1. Adding original TLS version to the ticket, so that TLS1.3 server can reject tickets issued by previous versions to prevent client authentication forgeries
2. Restricting 0-RTT data to only be encrypted with PSKs issued during a previous TLS 1.3 handshake, so that 0-RTT and other data cannot be decrypted
3. If a PSK is set via a ticket or session id, PSK modes for both normal PSK as well as 0-RTT should be only used with the protocol it was first negotiated with and prevent fallback. For example if a client received a PSK from TLS1.3, it should not allow either 0-RTT or resumed handshakes using that ticket to fallback back to lower protocols.

Before a client knows that a server supports TLS1.3 and if a client allows TLS1.2 fallbacks, I don't think there's anything we can do to prevent that downgrade to TLS1.2 (apart from naming TLS 1.3 resources differently), however once TLS1.3 is negotiated, the above things will prevent downgrade to TLS1.2.

Cheers,
Subodh Iyengar

---

From: David Benjamin <[email-masked]>
Date: Tue, 29 Mar 2016 18:00:56 +0000

On Tue, Mar 29, 2016 at 12:57 PM Subodh Iyengar <[email-masked]> wrote:

> Recent attacks like SLOTH, DROWN, PCKS1.5 padding oracles have shown that
> attacks on previous version of TLS can be used to attack new version of
> TLS.
>
> One thing that is not mandated by TLS 1.3 is separation of session tickets
> and session ids between TLS protocols. For example a client could use a
> ticket negotiated with a previous version of TLS with TLS1.3. This could
> result in interesting situations:
>

I agree that the spec should clearly forbid cross-version resumption. I
filed https://github.com/tlswg/tls13-spec/issues/136 some time ago about
this. It got closed since session resumption was reworked for 1.3, but it
doesn't look like the clarifications on matching versions ever happened,
just the removal of the bad client advice.

On the server, OpenSSL already includes the version in the SSL_SESSION
structure, and recent enough versions of it will not accept sessions at the
wrong version:
https://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=9e189b9dc10786c755919e6792e923c584c918a1

No client implementation which I tested allowed a server to do this either.
They treated it as a fatal connection error. (Which also means there is no
reason for a server to do it because it will not work anyway.)

> 1. Bypassing client auth
> If a server restricts a super-secure resource only over TLS1.3 with client
> auth and also shares ticket keys across TLS1.2 and TLS1.3. If an attacker
> has a SLOTH client impersonation attack against TLS1.2, they can get a TLS
> ticket from TLS1.2 connection issued by a server. The ticket would have the
> original client auth encrypted in it. The attacker could then use the
> ticket with TLS1.3 PSK resumption and authenticate as the original client.
>
> 2. PSK 0-RTT
> If the client agrees to use the ticket negotiated over a previous TLS1.2
> connection in a subsequent handshake as the PSK for 0-RTT TLS1.3. An
> attacker that has a SLOTH attack for server impersonation could inject
> their own TLS ticket into the connection with a client in a TLS1.2
> handshake. The 0-RTT data would be encrypted with an attacker known key and
> they could decrypt the 0-RTT data. If the connection continues to use PSK,
> the attacker can decrypt more data, however if the connection uses PSK +
> (EC)DHE then the attackers capability will be limited to decrypting the
> 0-RTT data.
>
> The ticket from a TLS1.3 handshake can be used in the context of a TLS1.0
> - TLS1.2 handshake. This might cause interesting new attacks to open up
> where a TLS1.3 ticket is forwarded to a TLS1.0 - TLS1.2 server.
>
> Even if a server enforces strict key separation between different TLS
> versions (which is very difficult), if tickets or session ids are reusable
> across TLS versions either on the client or the server, I believe these
> types of attacks remain possible.
>
> We could consider adding a section detailing the requirements for tickets
> for security. Even though there is a recommended construction, we could
> require a few things for the security of TLS 1.3:
> 1. Adding original TLS version to the ticket, so that TLS1.3 server can
> reject tickets issued by previous versions to prevent client authentication
> forgeries
> 2. Restricting 0-RTT data to only be encrypted with PSKs issued during a
> previous TLS 1.3 handshake, so that 0-RTT and other data cannot be decrypted
> 3. If a PSK is set via a ticket or session id, PSK modes for both normal
> PSK as well as 0-RTT should be only used with the protocol it was first
> negotiated with and prevent fallback. For example if a client received a
> PSK from TLS1.3, it should not allow either 0-RTT or resumed handshakes
> using that ticket to fallback back to lower protocols.
>
> Before a client knows that a server supports TLS1.3 and if a client allows
> TLS1.2 fallbacks, I don't think there's anything we can do to prevent that
> downgrade to TLS1.2 (apart from naming TLS 1.3 resources differently),
> however once TLS1.3 is negotiated, the above things will prevent downgrade
> to TLS1.2.
>

I disagree with point #3 and think the "prevent fallback" portion would be
a mistake. Possession of a TLS 1.3 session to offer should not disable TLS
1.2 if the client would have accepted this without that session.

It's the same as my complaint about RFC 5246 E.1's paragraph in the bug
linked earlier. While it is enticing to do away with TLS 1.2 this way, the
reality is deployments are messy and can be heterogeneous. The service may
be in the middle of deploying (or rolling back!) a change across many
machines. Or perhaps it's not as well-managed and simply has two completely
different machines behind it.

We've seen problems in Chrome due to version-locking behavior in OpenSSL
against real services with, say, one TLS 1.0 machine and one TLS 1.2
machine. They did not cross-resume sessions, but it doesn't matter. By the
time you find that out, the version has been locked. (This prompted a
rewrite in BoringSSL. The problem has also recently been fixed on OpenSSL
master.)

TLS client session caches are caches. Entries may be dropped from them at
any point. It would be a mistake to use this kind of volatile state for
downgrade protection. Further, some implementations will drop sessions on
fatal alerts ("Upon transmission or receipt of a fatal alert message, both
parties immediately close the connection. Servers and clients MUST forget
any session-identifiers, keys, and secrets associated with a failed
connection. Thus, any connection terminated with a fatal alert MUST NOT be
resumed."), so this could easily be bypassed.

Instead, TLS 1.3 adds this mechanism which I think is much preferable:
https://github.com/tlswg/tls13-spec/pull/284

David

> Cheers,
> Subodh Iyengar
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 30 Mar 2016 12:29:17 +1100

On 30 March 2016 at 05:00, David Benjamin <[email-masked]> wrote:
> wrong version

NSS too.  This is the right thing, I think.

I have no objection to making this a requirement in the spec.

---

From: Subodh Iyengar <[email-masked]>
Date: Wed, 30 Mar 2016 16:29:07 +0000

>I disagree with point #3 and think the "prevent fallback" portion would be a mistake. Possession of a TLS 1.3 session to offer should not disable TLS 1.2 if the client would have accepted this without that session.

@David, for #3, I'm referring to fallback in 0-RTT mode. In the normal operation case I don't think fallbacks work at all in this mode, so it should be fine to reject it to prevent attacks like I mentioned below.

For example let's say a client sends a 0-RTT packet and the server only supports TLS1.2, the server will return a server hello with TLS1.2. However when it reads data from the session buffer expecting a ClientKeyExchange message, it will start getting the 0-RTT data. 

In a case where the server is smart enough to discard all this data (maybe its a special TLS1.2  + TLS1.3 server), the behavior when this happens on the client side is unspecified, should the client supply the data again in the normal TLS stream? should it not resend that data?

It's probably better to reject this fallback when the client has chosen to explicitly use a TLS 1.3 feature with 0-RTT in general.

Subodh
________________________________________
From: Martin Thomson [[email-masked]]
Sent: Tuesday, March 29, 2016 6:29 PM
To: David Benjamin
Cc: Subodh Iyengar; [email-masked]
Subject: Re: [TLS] Tickets and cross protocol attacks

---

From: David Benjamin <[email-masked]>
Date: Wed, 30 Mar 2016 17:54:07 +0000

On Wed, Mar 30, 2016 at 12:29 PM Subodh Iyengar <[email-masked]> wrote:

> >I disagree with point #3 and think the "prevent fallback" portion would
> be a mistake. Possession of a TLS 1.3 session to offer should not disable
> TLS 1.2 if the client would have accepted this without that session.
>
> @David, for #3, I'm referring to fallback in 0-RTT mode. In the normal
> operation case I don't think fallbacks work at all in this mode, so it
> should be fine to reject it to prevent attacks like I mentioned below.
>
> For example let's say a client sends a 0-RTT packet and the server only
> supports TLS1.2, the server will return a server hello with TLS1.2. However
> when it reads data from the session buffer expecting a ClientKeyExchange
> message, it will start getting the 0-RTT data.
>

Oh, I see. Yeah, that TLS 1.3 is backwards incompatible here is
unfortunate, for the same heterogeneous-deployment reasons as session
resumption. As things stand, enabling 0-RTT on one machine in a fleet is a
promise that *all* machines have deployed TLS 1.3 and that TLS 1.3 will
*never* be rolled back (unless turn off 0-RTT on all machines and then wait
for things to expire first, but typically one needs to roll something back
because it is broken and needs attention). Deployments that just ship
pre-packaged server software will not get this right. TLS 1.3 should not
require TLS experts guiding deployment.

(I understand that this backwards incompatibility is necessary for TLS 1.3
clients to stream 0-RTT data. I think this is a mistake for TLS over TCP
(though it is, of course, fine for other profiles like QUIC or DTLS), but
I've probably lost that one.)

> In a case where the server is smart enough to discard all this data (maybe
> its a special TLS1.2  + TLS1.3 server), the behavior when this happens on
> the client side is unspecified, should the client supply the data again in
> the normal TLS stream? should it not resend that data?
>

If the server responds with a != TLS 1.3 ServerHello with an indication
that it accepted the early data then, agreed, that should be a fatal error.
This is for the same reasons as forbidding cross-version session resumption.

If the server responds with a < TLS 1.3 ServerHello and *doesn't* indicate
early data, that's a different question. If the client does accept it, the
client should supply the data again, as it would have with TLS 1.3. But,
actually, I think I may buy this too should be a fatal error, but not for
security reasons. I think trying to use this as version downgrade
protection in so narrow of a scope does not make sense.

Rather, because TLS 1.3 0-RTT is currently backwards-incompatible, TLS 1.3
forces a connection retry fallback[0]. Clients offering 0-RTT need to retry
without 0-RTT enabled[1]. Using "server sent a < TLS 1.3 ServerHello to a
ClientHello with 0-RTT data" as a fallback trigger is at least a reliable
one. If we must have a fallback (I would rather we didn't), it shouldn't be
a flaky one.

David

[0] We seem to have several meanings of the word "fallback" here. :-) One
to mean where we accept a ServerHello at lower version than the
ClientHello, and another to mean when you start a connection over from the
top with different parameters, akin to the insecure TLS version fallback
browsers do/did. I'm referring to the second one.

[1] Without lowering the ClientHello version, of course. Though TLS 1.3
intolerance, sadly, seems to exist, so that might also happen again
independently.

> It's probably better to reject this fallback when the client has chosen to
> explicitly use a TLS 1.3 feature with 0-RTT in general.
>