I think you're interpreting it right. If the cipher suite does not exactly match what you end up negotiating, you cannot accept early data.
> With the 0-RTT keys independent of the 1-RTT keys, why must the full > 0-RTT cipher suite match the 1-RTT cipher suite that comes into effect > only later? The unhelpful answer is "because the spec said so". But that is unhelpful. :-) More helpfully, I think the spec's choice is the right one. You're right that we *could* have defined it so that the cipher suite changes across 0-RTT and 1-RTT and it would (I think?) have been well-defined self-consistent at the TLS layer. Likewise, we also *could* have said that ALPNs change at this transition or whatever else. The question is whether these are good semantics to present to the application layer. *If* we said that the cipher suite changes, it would mean that the connection properties change partway through the lifetime of the connection. This breaks an invariant[*] of a TLS connection's lifecycle: 1. First you set up the connection. 2. Now connection properties are set and you can query ALPN, version, cipher suite, certificate, whatever else. 3. Read and write data as you wish. On 0-RTT accept, the 0-RTT data and 1-RTT logically form one contiguous connection. To have a core connection property change across the two means that boundary must flow up through every layer of the system that might be sensitive to it. ALPN is the most obvious case of this. If 0-RTT data were HTTP/1.1, you got half an HTTP POST through, then switched to 1-RTT data and it were suddenly HTTP/2, what would that even mean?? The cipher suite, sure, is less dire. But maybe your protocol has the client send something cipher-suite-dependent and then the server responds with something cipher-suite-dependent. Now what does that mean? Or maybe you just logged "the" with the connection somewhere and now you have to decide what "the" means and make sure that the client waited until the connection was confirmed, not merely writable, to log it. (Something your application probably isn't doing today.) And so it's much simpler, wherever we can, to just say "nope, 0-RTT is a prediction that this is how the connection will go and if the client mispredicted, cool but we'll reject 0-RTT and logically restart the application stream". Since you already have to make predictions on other fields like ALPN, doing that for cipher suites seems not much of a price to pay for this sanity. Plus the prediction is easy for resumption: it's the cipher suite you got on the original connection. I recognize that's not true for PSKs, but I'll note that if your PSKs are longer-lived and broader-scoped than resumption secrets doing 0-RTT (no forward secrecy) with them is probably not the best plan anyway. If your PSK is short-lived and narrowly-scoped (e.g. you're just importing the output secret of some TLS-external transaction like a PAKE), hopefully predicting a cipher suite is not such an ordeal. David [*] Yes, I'm aware that TLS 1.2 with renegotiation already broke this invariant. I doubt most applications handled it correctly. Disabling renegotiation is a pretty good idea. I've seen many a hard-to-diagnose crash and bug that happened because the wrong part of the application inspected the connection at the wrong time around a renegotiation. On Wed, Jul 8, 2026 at 3:30 PM Viktor Dukhovni <[email protected]> wrote: > I'm working on RFC9258 support in OpenSSL, and taking the time to try to > understand as much as I can about TLS 1.3 PSKs in general. > > One thing that's a bit puzzling is what appears to be a stricter > requirement around the PSK (slot 0) ciphersuite when early > data is being negotiated: > > https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.10 > ... > In order to accept early data, the server MUST have accepted a PSK > cipher suite and selected the first key offered in the client's > "pre_shared_key" extension. In addition, it MUST verify that the > following values are the same as those associated with the > selected PSK: > > - The TLS version number > > - The selected cipher suite > > - The selected ALPN [RFC7301] protocol, if any > > These requirements are a superset of those needed to perform a 1-RTT > handshake using the PSK in question. For externally established > PSKs, the associated values are those provisioned along with the key. > For PSKs established via a NewSessionTicket message, the associated > values are those negotiated in the connection during which the ticket > was established. > > Now the selected (1-RTT) ciphersuite does not actually come into effect > until after early_data has been consumed, and the 0-RTT cipher suite > could just be whatever was baked into the PSK (with just the digest > (KDF) needing to match the 1-RTT choice in order for the PSK to be > acceptable. > > With the 0-RTT keys independent of the 1-RTT keys, why must the full > 0-RTT cipher suite match the 1-RTT cipher suite that comes into effect > only later? Or am I misinterpreting the requirement? > > -- > Viktor. 🇺🇦 Слава Україні! > > _______________________________________________ > TLS mailing list -- [email protected] > To unsubscribe send an email to [email protected] >
_______________________________________________ TLS mailing list -- [email protected] To unsubscribe send an email to [email protected]
