← Week 2: TLS 1.3 Handshake

Day 13: 0-RTT Early Data

Phase 1 · May 26, 2026

← Week 2: TLS 1.3 Handshake

Agenda (2–3 hours)

  • Read (60 min): RFC 8446 §2.3 (0-RTT), §8 (0-RTT and anti-replay), §C.4 (0-RTT security considerations)
  • Study (45 min): Early data mechanics, replay attack vectors, anti-replay strategies
  • Challenge (60 min): Threat model analysis for provisioning services
← Week 2: TLS 1.3 Handshake

How 0-RTT Works

Client presents PSK + sends encrypted application data before server responds.

Client → Server: ClientHello + early_data extension
                 + [application data encrypted with client_early_traffic_secret]

Server → Client: ServerHello + EncryptedExtensions (early_data accepted/rejected)
                 + Certificate + ... + Finished

Client → Server: EndOfEarlyData + Finished

Latency saving: data arrives at server on the same packet as the ClientHello.

← Week 2: TLS 1.3 Handshake

The Replay Problem

Early data has no replay protection by design.

An attacker who captures the ClientHello + early_data can re-send it to the server.
The server cannot distinguish a replayed ClientHello from a fresh one.

TLS 1.3 provides 0-RTT data with no forward secrecy and no replay protection.

RFC 8446 §8 requires servers to implement at least one anti-replay mechanism:

  • Single-use tickets: each ticket can only be used once (requires distributed state)
  • Client Hello recording: hash of ClientHello within a time window
  • One-RTT fallback: reject early data entirely
← Week 2: TLS 1.3 Handshake

What's Safe to Send as Early Data?

Safe (idempotent reads):

  • GET /status
  • GET /cert-status?serial=abc123

Unsafe (non-idempotent mutations):

  • Certificate issuance requests (replay = duplicate cert issued)
  • Revocation requests
  • Any state-modifying API call

For your team's provisioning service: almost certainly never use 0-RTT.
Certificate issuance is non-idempotent. A replayed issuance request could:

  • Trigger billing/quota charges twice
  • Create duplicate certs with the same key
  • Cause state inconsistency in DynamoDB
← Week 2: TLS 1.3 Handshake

Anti-Replay Mechanisms

Mechanism Tradeoff
Single-use tickets (DynamoDB/Redis) Strong, requires distributed state
ClientHello hash cache (time window) Approximate, bounded memory
Forward secrecy fallback (reject 0-RTT) Safest, small latency cost

For a provisioning service: reject 0-RTT entirely (max_early_data_size = 0).
The latency savings don't justify the complexity and risk.

← Week 2: TLS 1.3 Handshake

Challenge Assignment

Write a 1-page threat model for 0-RTT in the context of your team's provisioning service:

  1. Assets: what data/operations does the service expose?
  2. Threat actors: who might replay requests, and why?
  3. Attack scenarios: what specific harm could a replayed provisioning request cause? (Consider: duplicate cert issuance, quota exhaustion, audit log inconsistency)
  4. Recommendation: should the service ever enable 0-RTT? Under what conditions, if any?
  5. Decision: what max_early_data_size would you configure and why?

This is the kind of analysis you'll write in design docs at Amazon.

← Week 2: TLS 1.3 Handshake

Resources

  • RFC 8446 §2.3: 0-RTT data
  • RFC 8446 §8: Anti-replay countermeasures
  • RFC 8446 §C.4: Security considerations for 0-RTT
  • Cloudflare blog: "Even faster connection establishment with QUIC 0-RTT resumption" (shows 0-RTT in production context)