tlswg / tls13-spec

TLS 1.3 Specification
563 stars 159 forks source link

AEAD integrity limits for 0-RTT data #1249

Closed emanjon closed 2 years ago

emanjon commented 3 years ago

DTLS 1.3 introduces integrity limits for the AEAD algorithms, which is good. TLS 1.3 does not have any AEAD integrity limits, probably because the assumption that only a single AEAD forgery can be attempted. My understanding is that this is not true for 0-RTT data which works more like DTLS and where an attacker can attempt any number of forgery attempts on a single AEAD key.

RFC 8446 has relatively strong anti-replay protection: "The server MUST ensure that any instance of it (be it a machine, a thread, or any other entity within the relevant serving infrastructure) would accept 0-RTT for the same 0-RTT handshake at most once." but this does not stop an attacker from attempting an unlimited number of forgeries.

I think consideration / mitigation of this is missing from RFC8446. Some alternative suggestions:

  1. Should the 0-RTT requirement above be strengthen to: "The server MUST ensure that any instance of it (be it a machine, a thread, or any other entity within the relevant serving infrastructure) would process a 0-RTT handshake with the same PSK, ClientHello.random pair at most once."

  2. should RFC8446bis continue to ignore AEAD limits for 0-RTT? 0-RTT data already has lower security (weaker replay protection)? In this case I think some considerations should be added describing that the integrity protection of is weaker than for normal application data.

  3. should RFC8446bis introduce DTLS 1.3 type integrity limits for client_early_traffic_secret? This aligns the integrity limits of 0-RTT data in TLS with the normal application data in DTLS.

kaduk commented 3 years ago

My understanding is that this is not true for 0-RTT data which works more like DTLS and where an attacker can attempt any number of forgery attempts on a single AEAD key.

Could you say a bit more about how this would work in practice? I did not consult the spec just now, but I had the impression that 0-RTT still had only a single attempt at forgery (at least, per replay cache instance/backend server).

kaduk commented 2 years ago

Ah, the linked DTLS issue mentions long-lived external PSKs specifically. I agree that our story for those is less well specified and probably not great. Off the top of my head, I would suggest "don't use 0-RTT with long-lived PSKs".

martinthomson commented 2 years ago
  1. I think that the original is fine. I don't think that there is any meaningful distinction between 0-RTT handshake and the (PSK, ClientHello.random) tuple, at least as far as the derived keys go. Change the PSK, PSK identity, or random and you get a new key derivation.
  2. I had expected that early data was subject to the same constraints as later epochs. The only caveat being that it is impossible to update early data keys using KeyUpdate. The answer is to finish the handshake of course, so a hard error is fine. We might advise servers to cap max_early_data_size to help avoid any issues of overrun, though with certain perverse padding arrangements, that might not provide any real guarantee.
  3. As above integrity limits should also apply.
ekr commented 2 years ago

https://github.com/tlswg/tls13-spec/pull/1254 fixes (1)

The case for (3) is actually more subtle, as the problem is not client_early_traffic_secret but rather the trial decryption skipping phase. We might need to apply DTLS 1.3 like limits there.