Datagram Transport Layer Security Version 1.2
obsoleted by
- rfc-9147 — The Datagram Transport Layer Security (DTLS) Protocol Version 1.3
obsoletes
- rfc-4347 — Datagram Transport Layer Security
updated by
Extracted elements (29)
DTLS bans stream ciphers (including RC4) because stream ciphers maintain cryptographic context between records and cannot be randomly accessed. DTLS records must be independently decryptable, which is incompatible with stream cipher operation. Explicit sequence numbers solve the complementary implicit-sequence-number problem.
DTLS is deliberately designed to be as similar to TLS as possible to minimize new security invention and maximize code/infrastructure reuse. All changes are presented as deltas from TLS 1.2 rather than as a new protocol.
DTLS version numbers are the 1's complement of TLS version numbers (DTLS 1.2 = {254, 253}), and future DTLS versions decrease numerically while conceptual version numbers increase. This maximal spacing between TLS and DTLS version values ensures records from the two protocols are easily distinguished on the wire.
There is no DTLS version 1.1; the version number was skipped to harmonize DTLS version numbers with TLS, so that DTLS 1.2 aligns with TLS 1.2. DTLS 1.0 was originally defined as a delta from TLS 1.1.
DTLS 1.2 servers SHOULD use DTLS version 1.0 in the HelloVerifyRequest server_version field to avoid version negotiation during the initial handshake. Clients MUST treat the version in HelloVerifyRequest only as a packet-format indicator, not as a signal of the server's DTLS version or the version that will be negotiated.
DTLS records do not contain association identifiers; applications must multiplex associations themselves (typically using host/port for UDP). When carried over transports with their own sequence numbers (e.g., DCCP), both DTLS and transport sequence numbers will be present simultaneously.
DTLS servers SHOULD perform a cookie exchange whenever a new handshake is being performed. Clients MUST be prepared to do a cookie exchange with every handshake. The server MAY skip the exchange when resuming a session or when amplification is not a threat.
Each DTLS record MUST fit within a single datagram. Records may not span datagrams. Multiple DTLS records may be placed in one datagram, encoded consecutively, but the first byte of the datagram payload must be the beginning of a record.
For anti-replay, a minimum sliding window size of 32 MUST be supported; a window size of 64 is SHOULD be employed as the default. The receiver packet counter MUST be initialized to zero when the session is established, and duplicate sequence numbers MUST be rejected.
Implementations MUST either abandon an association or rehandshake prior to allowing the record sequence number to wrap. Additionally, implementations MUST NOT allow the epoch to wrap; instead they MUST establish a new association.
Implementations MUST either discard or buffer all application data packets for a new epoch until they have received the Finished message for that epoch, preventing use of keying material before the handshake completes.
Implementations MUST NOT allow the same epoch value to be reused within two times the TCP maximum segment lifetime, to ensure that any given sequence/epoch pair is unique across cipher state changes.
In the FINISHED state, the node that transmits the last flight MUST respond to a retransmit of the peer's last flight with a retransmit of its own last flight, for at least twice the default MSL. This prevents deadlock when the final flight is lost.
Invalid records (bad MAC, formatting, length, etc.) SHOULD be silently discarded rather than triggering connection termination. If an implementation generates an alert for an invalid record, it MUST use a fatal-level alert; sending non-fatal alerts is prohibited to avoid error oracle attacks.
New TLS cipher suites, upon registration, MUST indicate whether they are suitable for DTLS usage and what adaptations must be made. IANA has added a DTLS-OK flag to all TLS parameter registries.
RC4 MUST NOT be used with DTLS. More broadly, stream ciphers are banned because they cannot be randomly accessed, which is required for DTLS's per-record independent decryption.
Retransmission timer values SHOULD start at 1 second (not the RFC 6298 default of 3 seconds) and SHOULD double at each retransmission up to a maximum of no less than 60 seconds. The timer SHOULD be retained until a lossless transmission occurs.
The DTLS MAC uses a 64-bit sequence number formed by concatenating the epoch and the sequence_number in wire order, replacing TLS's implicit sequence number. If a DTLS implementation chooses to generate an alert on bad MAC, it MUST generate a fatal bad_record_mac alert.
The Finished MAC MUST be computed as if each handshake message had been sent as a single fragment, removing sensitivity to handshake message fragmentation. DTLS-specific header fields (message_seq, fragment_offset, fragment_length) are included in hash calculations for CertificateVerify and Finished.
When a server receives an epoch=0 ClientHello on an existing association, it SHOULD proceed with a new handshake but MUST NOT destroy the existing association until the client has demonstrated reachability by completing a cookie exchange or delivering a verifiable Finished message.
When responding to a HelloVerifyRequest, the client MUST use the same parameter values (version, random, session_id, cipher_suites, compression_method) as in the original ClientHello, allowing the server to use those values when generating and verifying the cookie.
The ClientHello message is extended with an opaque cookie<0..2^8-1> field. On the first ClientHello the cookie field is empty (zero length); on subsequent ClientHellos it carries the cookie received from the server's HelloVerifyRequest.
The HelloVerifyRequest message contains a server_version field and an opaque cookie<0..2^8-1>. It is sent by the server in response to an initial ClientHello to enable a stateless cookie exchange that counters DoS and amplification attacks. The cookie size limit is 255 bytes (increased from 32 in DTLS 1.0).
No new IANA registries are created; DTLS uses the same identifier space as TLS. All existing TLS parameter registries have been updated with a DTLS-OK flag indicating whether each parameter may be used with DTLS. The hello_verify_request(3) HandshakeType value was assigned.
DTLS servers that do not use the cookie exchange are vulnerable to being used as DoS amplifiers: an attacker sends ClientHellos with a forged source address, causing the server to send large Certificate messages to the victim. Servers SHOULD use the cookie exchange unless amplification is clearly not a threat.
Unlike TLS, DTLS implementations SHOULD NOT respond to invalid records by terminating the connection. Generating fatal alerts in response to forged or invalid records over UDP makes the implementation highly susceptible to DoS attacks because UDP source addresses are trivially spoofable; this practice is NOT RECOMMENDED over UDP.
The DTLS handshake retransmission state machine has three states: PREPARING (compute next flight, buffer messages), SENDING (transmit flight, set retransmit timer), and WAITING (await response). Exits from WAITING occur on: timer expiry (→ SENDING), receipt of retransmitted flight from peer (→ SENDING), or receipt of the next expected flight (→ PREPARING or FINISHED).
The DTLS handshake message header adds three fields to the TLS 1.2 handshake header: uint16 message_seq (for reordering), uint24 fragment_offset (bytes in prior fragments), and uint24 fragment_length (length of this fragment). These support fragmentation, reassembly, and loss recovery.
The DTLSPlaintext record adds two fields to the TLS 1.2 record: a uint16 epoch (incremented on every cipher state change) and a uint48 sequence_number. Version is encoded as {254, 253} for DTLS 1.2, the 1's complement of the TLS 1.2 version, ensuring TLS and DTLS records are easily distinguished.