Connection Identifier for DTLS 1.2
updated by
- rfc-9853 — Return Routability Check for DTLS 1.2 and 1.3
updates
- rfc-6347 — Datagram Transport Layer Security Version 1.2
Extracted elements (29)
Adding the CID to the ciphertext record presented an opportunity to encrypt the real content type and add padding, following TLS 1.3 best practices. This improves privacy over the original DTLS 1.2 record format.
CIDs in DTLS 1.2 are negotiated only at handshake time; there is no mid-session CID update message because DTLS 1.2 does not support TLS 1.3-style post-handshake messages. This is the simplest design achievable within DTLS 1.2 constraints.
The MAC construction for CID records uses seq_num_placeholder (0xff * 8) followed by tls12_cid to ensure MAC inputs for CID-carrying records are structurally distinct from non-CID records, where a sequence number is always followed by a content type other than tls12_cid.
The connection_id extension (value 54) supersedes an earlier early-allocation at value 53, which is incompatible with this document and has been deprecated. Implementations MUST use value 54.
When a DTLS session is resumed or renegotiated, the 'connection_id' extension is negotiated afresh. The CID negotiated for the previous session does not carry over.
A receiver MUST NOT replace the peer address on receiving a CID record with a new source address unless: (1) the datagram passed cryptographic verification, (2) it is newer than the most recently received datagram (by epoch and sequence number), and (3) a strategy confirms the new address can receive DTLS records.
DTLS implementations MUST silently discard records with bad MACs or that are otherwise invalid.
If peers have not negotiated CID use, or a zero-length CID has been advertised for a given direction, then the RFC 6347 record format and content type MUST be used for that direction.
Implementations that use a deployment-specific fixed CID length MUST still be able to send CIDs of different lengths to other parties. Variable-length CID implementations are responsible for making CID values self-delineating since length is not carried in the record.
Once encryption is enabled and a non-zero-length CID has been negotiated for a given direction, the sender MUST use the DTLSCiphertext record format with content type tls12_cid. Plaintext payloads never use the CID record format.
When receiving a datagram with tls12_cid content type, the new MAC computation defined in Section 5 MUST be used; for RFC 6347 format records, the MAC from RFC 6347 Section 4.1.2 MUST be used.
When receiving without tls12_cid content type, if the 5-tuple lookup retrieves an association for which a non-zero-length CID is expected, the datagram MUST be treated as invalid per RFC 6347 Section 4.1.2.1.
Endpoints could encode arbitrary per-connection metadata in CID values, potentially leaking information to on-path observers. Implementations concerned about this SHOULD refuse to use CIDs.
In multihoming environments, a passive attacker can correlate communication over multiple paths using the CID. The absence of a CID update mechanism makes DTLS 1.2 CIDs unsuitable for mobility; deployments concerned about correlation SHOULD refuse to use CIDs in DTLS 1.2 and switch to DTLS 1.3.
The CID is a persistent identifier across the lifetime of a DTLS connection, introducing linkability risk. An on-path adversary can correlate all payloads carrying the same CID pair, just as with the 5-tuple in classical DTLS.
This specification introduces optional record padding (via DTLSInnerPlaintext.zeros) in CID-enhanced records, allowing senders to inflate ciphertext size to impede traffic analysis. This privacy feature was not available in the original DTLS 1.2 specification.
For AEAD ciphers, the additional_data is seq_num_placeholder + tls12_cid + cid_length + tls12_cid + version + epoch + sequence_number + cid + length_of_DTLSInnerPlaintext. The modified algorithm MUST NOT be applied to non-tls12_cid records.
For block ciphers, the MAC input for CID records begins with seq_num_placeholder (8 bytes of 0xff) followed by tls12_cid twice, separating it from non-CID MACs where a valid sequence number always precedes a non-tls12_cid content type.
For block ciphers with Encrypt-then-MAC (RFC 7366), the MAC covers seq_num_placeholder + tls12_cid + cid_length + tls12_cid + version + epoch + sequence_number + cid + DTLSCiphertext.length + IV + ENC(content + padding + padding_length).
The 'connection_id' extension (type 54) is included in ClientHello and ServerHello messages. Each party sends the CID value it wishes to receive; a zero-length CID indicates willingness to send with CID but unwillingness to receive one.
The tls12_cid(25) content type signals three things: the CID field is present with one or more bytes, the modified MAC calculation applies, and the real content type is inside the encryption envelope.
IANA added a 'DTLS-Only' column to the 'TLS ExtensionType Values' registry, with value 'Y' for extensions applicable only to DTLS and 'N' otherwise. All pre-existing entries receive value 'N'.
IANA allocated connection_id(54) in the 'TLS ExtensionType Values' registry, marked DTLS-Only=Y and Recommended=N, applicable to ClientHello and ServerHello. The earlier early-allocation value 53 is deprecated as incompatible.
IANA allocated tls12_cid(25) in the 'TLS ContentType' registry. This content type is only applicable to DTLS 1.2.
An attacker who can observe DTLS traffic may replay datagrams with modified IP addresses and port numbers. The three-condition check in Section 6 (cryptographic verification, recency, reachability) limits but does not fully eliminate this attack surface.
An on-path adversary can mount reflection attacks against third parties by triggering peer address updates, since a DTLS peer cannot distinguish a genuine NAT rebinding from a malicious address change. This is especially dangerous when requests are small and responses large.
DTLSCiphertext adds an opaque cid[cid_length] field after the sequence_number and before the length field. outer_type is always tls12_cid(25); enc_content is the encrypted DTLSInnerPlaintext. All other fields match RFC 6347.
DTLSInnerPlaintext wraps the plaintext content with its real ContentType and optional zero-padding: struct { opaque content[length]; ContentType real_type; uint8 zeros[length_of_padding]; }. The real content type is encrypted inside the record.
The ConnectionId structure carries an opaque CID of variable length 0..255 bytes in the extension_data of the 'connection_id' extension.