Chapter 2: DTLS 1.3 over CoAP

TLS Lite — WIA-TLS-LITE — Author: Dr. Yeon Sam-heum

2.0 Motivation: Why DTLS 1.3 over CoAP

Traditional TLS 1.3 (RFC 8446) is engineered to run over TCP, but IoT, LPWAN, and industrial sensor networks cannot afford TCP's connection-keeping cost: a three-way SYN/SYN-ACK/ACK handshake, sliding window state, and FIN-driven teardown. RFC 7228 Class 0 devices (no more than 10 KiB RAM and 100 KiB Flash) routinely exhaust their memory budget on TCP state machines alone. The IETF therefore standardised DTLS (Datagram TLS) on top of UDP, and RFC 9147 brings TLS 1.3's security properties to the datagram setting as DTLS 1.3.1

This chapter covers the second architectural layer of the TLS Lite (WIA-TLS-LITE) standard: DTLS 1.3 over CoAP. CoAP (Constrained Application Protocol, RFC 7252) is the IoT-targeted application-layer protocol that compresses HTTP's REST semantics into UDP. CoAP itself permits a NoSec mode, but RFC 7252 §9 mandates DTLS as the secure mode. In practice, DTLS 1.3 over CoAP is the de-facto secure stack for IoT, and TLS Lite aligns the option matrix so that Class 1 and Class 2 devices can implement it within the octet budget available to them.2

An operator typically arrives at this chapter from one of these scenarios. First, a gateway that bridges LTE-M, NB-IoT, or Wi-Fi 6 to the public Internet, with BLE, LoRa, Thread, or Zigbee sensors hanging beneath it. Second, sensor nodes running on Class 1 microcontrollers such as ESP32-C3, nRF52840, or STM32L4, embedding mbedTLS, wolfSSL, or tinydtls as the cryptographic stack. Third, nodes that emit PUT, POST, or GET requests to cloud-side CoAP resource servers through that gateway, with every byte of traffic sealed under DTLS 1.3.

The critical design decisions in this scenario are (a) key-exchange mode, (b) connection_id length, (c) whether 0-RTT/early_data is permitted, (d) record sequence number compression, (e) HelloRetryRequest avoidance, and (f) the mapping between CoAP message types (CON/NON) and DTLS records. The chapter walks each decision in turn and presents the normative requirements of RFC 9147, 9146, 7252, 8323, and 8613 together with TLS Lite's recommended option matrix across six tables.

2.1 DTLS 1.3 vs TLS 1.3 — handshake comparison

TLS 1.3 standardised the 1-RTT handshake, and DTLS 1.3 preserves that target. The datagram setting nevertheless adds machinery to cope with UDP's unordered, lossy delivery: message sequence numbers (MSN), handshake-message fragmentation (fragment_offset and fragment_length), retransmission timers with exponential backoff, and a new ACK record (RFC 9147 §7).3

Table 2-1 summarises the round-trip cost for each key-exchange mode. PSK_KE (pre-shared key only, no ECDHE) is 1-RTT in both TLS 1.3 and DTLS 1.3. PSK_DHE_KE (PSK plus ECDHE forward secrecy) is also 1-RTT but adds ECDHE cost. The 0-RTT/early_data mode is exactly zero round-trip but introduces an anti-replay trade-off.

Table 2-1. TLS 1.3 vs DTLS 1.3 handshake round-trip comparison
Key-exchange mode TLS 1.3 RTT DTLS 1.3 RTT Forward secrecy Recommended use
PSK_KE1-RTT1-RTT (+ MSN recovery)NoFactory-provisioned PSK on closed networks
PSK_DHE_KE1-RTT1-RTT (+ ECDHE cost)YesDefault recommended for Class 1 and 2 devices
DHE_KE (cert)1-RTT1-RTT (+ X.509 verification)YesClass 2 gateways, cloud-side endpoints
0-RTT/early_data0-RTT0-RTTLimitedIdempotent PUT/GET only — anti-replay required
RPK (RFC 7250)1-RTT1-RTTYesWhen avoiding certificate-chain overhead

TLS Lite recommends PSK_DHE_KE as the default. The pre-shared key is injected at manufacturing time into a Secure Element (SE) or derived from a PUF (Physically Unclonable Function), and forward secrecy is delivered at runtime by X25519 ECDHE. ECDHE curve selection accepts both P-256 (NIST FIPS 186-5) and X25519 (RFC 7748), but on low-power cores such as ARM Cortex-M0+, X25519's constant-time implementation gives better side-channel immunity at lower code size.

2.2 CoAP message types and DTLS transport

CoAP defines four message types (RFC 7252 §4). Confirmable (CON) requests reliable delivery and demands an ACK or RST in response. Non-confirmable (NON) is fire-and-forget and tolerates loss. Acknowledgement (ACK) is the explicit response to a CON. Reset (RST) signals that the recipient rejects the message.4

When CoAP runs over DTLS 1.3, CoAP's reliability machinery (CON/ACK) and DTLS's record-sequence machinery are orthogonal. Application-layer recovery in CoAP is independent of record-layer recovery in DTLS. In operation, the two timer regimes must nevertheless be coordinated. RFC 7252 §4.8.2 sets CoAP's default ACK_TIMEOUT to 2 s with ACK_RANDOM_FACTOR 1.5 and MAX_RETRANSMIT 4. RFC 9147 §7.7 sets the DTLS 1.3 handshake initial RTO to 1 s with exponential backoff. TLS Lite recommends following both, and additionally requires that CoAP traffic be deferred until the DTLS handshake has completed so the two timers do not interleave on a single node.

Table 2-2. CoAP message types (CON/NON/ACK/RST) mapped to DTLS records
CoAP type Reliability DTLS record type Recommended scenario Loss behaviour
CONReliableapplication_data (23)Control commands, firmware update triggerCoAP ACK_TIMEOUT retransmit
NONUnreliableapplication_data (23)Periodic telemetry, sensor streamApplication layer ignores
ACKResponseapplication_data (23)Acknowledging CON (piggyback or separate)Triggers CON retransmit
RSTRejectionapplication_data (23)Unknown token, malformed ObserveSender correction

2.3 connection_id (RFC 9146) — NAT rebinding

IoT devices are frequently reassigned an IP address and port behind NAT: LTE-M devices return from sleep mode, NB-IoT devices exit PSM (Power Saving Mode), and Wi-Fi devices renew DHCP. Each event mutates the device's external 4-tuple. Classical DTLS identified sessions by the (src_ip, src_port, dst_ip, dst_port) 4-tuple, so any change in that tuple forced a handshake from scratch. RFC 9146 connection_id (CID) solves this problem.5

A CID is a variable-length identifier of 0–255 octets, negotiated bidirectionally during the handshake and carried in every subsequent application_data record header. Receivers look up the session by CID, so the session survives a 4-tuple change. TLS Lite recommends 4 octets for Class 1 devices (64-bit collision resistance security margin) and 8 octets for Class 2 gateways.

Table 2-3. connection_id length vs NAT compatibility and octet cost
CID length (octets) Collision resistance Header overhead NAT rebinding Recommended class
0 (CID disabled)N/A0 octetsNot supported (4-tuple)Closed-network Class 0 only
216 bits (weak)+2 octetsPossible, collision riskClass 0 experimental
432 bits+4 octetsPossible, generally safeClass 1 recommended
864 bits+8 octetsPossible, collision-safeClass 2 gateway recommended
16128 bits+16 octetsPossible, overkillLarge cloud endpoints

2.4 Record sequence number compression

The most octet-budget-relevant addition in DTLS 1.3 is record sequence number (SN) compression. DTLS 1.2 transmitted the 64-bit SN in plaintext, whereas DTLS 1.3 §4.2.2 masks the SN with the record-protection key and compresses it to 8 or 16 bits. A 16-bit SN allows 65,536 records per epoch, so a device emitting 17 telemetry messages per hour exhausts an epoch after roughly 4,096 hours (170 days), aligned with typical firmware-update cycles.6

SN compression delivers two benefits. First, the record header shrinks from 13 octets to 5–7 octets. Second, SN masking complicates traffic analysis. TLS Lite recommends an 8-bit SN for Class 1 devices (256 records per epoch, mandating short epoch rotation) and a 16-bit SN for Class 2 devices by default.

2.5 Short header — the 1-octet type

RFC 9147 §4 defines two record-header forms: the unified header (1-octet type field) and the ciphertext header (carrying epoch, SN, and CID). The unified header's type octet encodes, bit-by-bit: bits 7–5 = 001 (fixed prefix), bit 4 = CID present, bit 3 = SN length (0 = 8-bit, 1 = 16-bit), bit 2 = length field present, bits 1–0 = epoch low 2 bits.

This 1-octet type encoding is the central octet-saving mechanism in RFC 9147 §4.1. Transmitting a 16-octet payload (a CoAP GET response with a single option) under classical DTLS 1.2 costs 13 (header) + 16 (payload) + 16 (AEAD tag) = 45 octets. Under DTLS 1.3 with the short header, the same payload costs 7 (header) + 16 (payload) + 16 (AEAD tag) = 39 octets — a 13% reduction. Given that LoRaWAN SF12 (spreading factor 12) caps a single frame payload at 51 octets, this 13% determines whether the response fits a single airtime slot.

// DTLS 1.3 unified header — pseudo-code (RFC 9147 §4.1)
struct DtlsCiphertext {
    uint8_t type;            // 1 octet: 001 C S L E E (bit field)
                             //   C = CID present (1 bit)
                             //   S = SN length (0=8bit, 1=16bit)
                             //   L = length present (1 bit)
                             //   E = epoch low 2 bits
    opaque connection_id[CID_LEN];   // optional (when C=1)
    uint8_t sequence_number[1 or 2]; // 1 or 2 octets per S
    uint16_t length;         // optional (when L=1)
    opaque encrypted_record[length]; // AEAD-protected payload + tag
};

// Minimum header: 1 (type) + 1 (SN) = 2 octets
// Maximum header: 1 + 8 (CID) + 2 (SN) + 2 (length) = 13 octets

2.6 0-RTT/early_data — security trade-off

DTLS 1.3 supports 0-RTT in the same shape as TLS 1.3. The client uses a PSK from a previous session (or from a fresh NewSessionTicket) to send application_data alongside the ClientHello in the early_data extension. The absolute appeal is zero round-trips. The trade-off is that anti-replay guarantees weaken.7

RFC 8446 §8 and RFC 9147 §7.1 recommend two anti-replay mechanisms for 0-RTT traffic. (a) Single-use tokens: the NewSessionTicket's ticket_age_add carves an acceptance window, and early_data outside this window is rejected. (b) Idempotent operations only: 0-RTT carries GET and idempotent PUT, while POST and non-idempotent PUT are rejected. TLS Lite permits 0-RTT for IoT scenarios only on GET (telemetry polling) and idempotent PUT (state toggles).

Table 2-4. 0-RTT enabled/disabled scenarios — security rating
Scenario 0-RTT permitted Replay risk Mitigation Recommended rating
GET polling (sensor read)YesLow (idempotent)ticket_age_add window ±10 sOK
Idempotent PUT (switch ON/OFF)ConditionalMediumnonce + single-use tokenCaution
POST (event log)NoHigh (duplicate record)1-RTT requiredForbidden
Firmware update triggerNoVery high1-RTT + signed payloadForbidden
Credential issue/renewalNoCritical1-RTT + nonceForbidden

2.7 Attack vectors and mitigations

The attack vectors commonly cited against DTLS 1.3 over CoAP fall into five categories: replay, downgrade, DoS amplification, KRACK-style nonce reuse, and side-channel leakage. Each can be mitigated either intrinsically in DTLS 1.3 or by operational option choice.

Replay attacks resend ciphertext records to repeat the underlying action. The first line of defence is the anti-replay window in DTLS 1.3 §4.5.1 (default 64, recommended 128), and the second line is the AEAD per-record nonce. Downgrade attacks coerce a weaker cipher_suite during the handshake; RFC 8446 §4.1.3's random downgrade sentinel (the server marks ServerHello.random's last 8 bytes with a fixed pattern when delivering TLS 1.3) detects the attempt. DoS amplification spoofs the source IP in ClientHello to make the server emit a large ServerHello/Certificate; HelloRetryRequest with a cookie (RFC 9147 §5.1) is the primary mitigation.

Table 2-5. Attack vectors and mitigations in CoAP over DTLS operations
Attack vector RFC reference Primary mitigation Secondary mitigation Class 0 feasibility
Replay (record resend)RFC 9147 §4.5.1Anti-replay window (64+)AEAD per-record nonceFeasible
Downgrade (cipher weakening)RFC 8446 §4.1.3Random downgrade sentinelSignatureScheme whitelistFeasible
DoS amplification (spoofed Hello)RFC 9147 §5.1HelloRetryRequest cookieRate limit per CID/IPLimited
KRACK nonce reuseRFC 8446 §5.3Per-record nonce uniquenessMandatory epoch rotationFeasible
Side-channel (timing/power)NIST SP 800-90BConstant-time ECDHEX25519 recommendedLimited

2.8 HelloRetryRequest avoidance

HelloRetryRequest (HRR) is the server's reply when the client failed to guess the server's preferred curve and key_share. HRR turns a 1-RTT handshake into 2-RTT. In IoT scenarios where wake/sleep duty cycles are tight, frequent HRR is expensive. TLS Lite recommends two avoidance strategies. First, the client offers key_share for every curve the server is likely to accept (X25519 and P-256 simultaneously). Second, the server pre-announces its preferred curve through the client cache (a KEM hint inside the NewSessionTicket).8

Empirically, an mbedTLS 3.5 client on ESP32-C3 that offers X25519 and P-256 key_shares concurrently sees a 0% HRR rate, while offering only X25519 to a server that mandates P-256 causes 100% HRR, and matching X25519 on both ends yields 0% HRR. These figures are captured in §B.7 of the TLS Lite conformance suite.

2.9 RFC 7228 class-specific recommended option matrix

Table 2-6. RFC 7228 Class 0/1/2 device-specific recommended DTLS 1.3 options
Option Class 0 (≤10K RAM) Class 1 (≤50K RAM) Class 2 (≤250K RAM) Rationale
Key exchangePSK_KEPSK_DHE_KE (X25519)PSK_DHE_KE + certRAM/Flash budget
cipher_suiteTLS_AES_128_CCM_8_SHA256TLS_AES_128_GCM_SHA256TLS_AES_128_GCM_SHA256 or TLS_CHACHA20_POLY1305_SHA256AEAD standard
connection_idDisabled (closed network)4 octets8 octetsNAT rebinding
SN compression8-bit16-bit16-bitOctet budget
0-RTTDisabledIdempotent onlyIdempotent only + replay windowRFC 8446 §8
OSCORE bindingOptionalRecommended (app-layer defence)Recommended + DTLS endpointRFC 8613
AuthenticationPSK onlyPSK + RPKPSK + RPK + X.509Key management cost
Epoch rotationDailyHourlyPer requestNonce-collision avoidance

2.10 Simulator deep-link

Every option combination discussed in this chapter is demonstrable in the reference simulator. Opening Simulator Panel 1 (DTLS handshake trace) visualises every record from the moment the client sends ClientHello with TLS_AES_128_GCM_SHA256 and X25519 key_share until the server Finished. Panel 0 (procedure overview) walks the operator checklist step by step, and Panel 2 (CoAP CON/ACK pairing) visualises the CoAP request flow.

// CoAP GET over DTLS 1.3 — record sequence
// Client → Server
DTLS_record(type=app_data, epoch=2, SN=0x0001, CID=0xAB12CD34):
    encrypted(
        CoAP {
            ver=01, type=0 (CON), token_len=2, code=0.01 (GET),
            message_id=0x1234, token=0x5678,
            options: [Uri-Path: "sensor"; Accept: 60 (cbor)],
            payload: 
        }
    ) || AEAD_tag(16)

// Server → Client (piggyback ACK)
DTLS_record(type=app_data, epoch=2, SN=0x0001, CID=0xEF56AB78):
    encrypted(
        CoAP {
            ver=01, type=2 (ACK), token_len=2, code=2.05 (Content),
            message_id=0x1234, token=0x5678,
            options: [Content-Format: 60 (cbor)],
            payload: CBOR(temperature=22.5, humidity=45)
        }
    ) || AEAD_tag(16)

Note on Korean Edition

The Korean edition of this chapter (chapter-02.html under /ebook/ko/) carries an additional section, Korean IoT and CoAP infrastructure alignment, that maps RFC 7252 and RFC 9147 onto Korea-specific frameworks: the Information and Communications Network Act (정보통신망법) Article 45-2, the KISA IoT Security Certification Programme, TTA standard TTAK.OT-12.0148/R1, the KCMVP cryptographic-module validation regime, KS X ISO/IEC 29167-19, ETRI reference implementations, the NIPA Smart City Integrated Platform v2.0, and operational profiles on the SK Telecom, KT, and LG U+ LTE-M and NB-IoT networks. International readers can skip this section without losing the normative argument, since the recommendations in Tables 2-1 through 2-6 are presented in jurisdiction-neutral form throughout the rest of the chapter.

2.11 Cross-standard composition recap

The DTLS 1.3 over CoAP layer is the operational bridge between TLS Lite Phase 1 (envelope) and Phase 3 (federation handshake). When an operator adopts the recommended option matrix in this chapter, the same device can reuse the credential store of WIA-OMNI-API, the runtime trust list of WIA-AIR-SHIELD, and the workload intent declaration of WIA-INTENT without a second handshake. The TLS Lite design lets one operator federate across many standards with one signing-key chain and one audit transport because IoT-class memory and power budgets cannot tolerate per-standard re-implementation.

The conformance suite for this chapter is specified in §B.2 through §B.7 of https://github.com/WIA-Official/wia-tls-lite-conformance. The suite automatically verifies that the operator's firmware satisfies every recommended option in Tables 2-1 through 2-6. Firmware that clears the suite earns the WIA Standards Conformance Mark (WIA-CM).

Chapter 2 Notes

  1. IETF RFC 9147, The Datagram Transport Layer Security (DTLS) Protocol Version 1.3, April 2022. https://www.rfc-editor.org/rfc/rfc9147
  2. IETF RFC 7252, The Constrained Application Protocol (CoAP), June 2014. https://www.rfc-editor.org/rfc/rfc7252
  3. IETF RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3, August 2018. https://www.rfc-editor.org/rfc/rfc8446
  4. IETF RFC 7252 §4 (Message Model), CoAP Confirmable/Non-confirmable/Acknowledgement/Reset semantics. https://www.rfc-editor.org/rfc/rfc7252#section-4
  5. IETF RFC 9146, Connection Identifier for DTLS 1.2 and 1.3, March 2022. https://www.rfc-editor.org/rfc/rfc9146
  6. IETF RFC 9147 §4.2 (Record Sequence Number Encryption), DTLS 1.3 SN masking. https://www.rfc-editor.org/rfc/rfc9147#section-4.2
  7. IETF RFC 8446 §8 (0-RTT and Anti-Replay), the 0-RTT security trade-off. https://www.rfc-editor.org/rfc/rfc8446#section-8
  8. IETF RFC 8446 §4.1.4 (HelloRetryRequest), the HRR mechanism. https://www.rfc-editor.org/rfc/rfc8446#section-4.1.4
  9. IETF RFC 7228, Terminology for Constrained-Node Networks, May 2014 — Class 0/1/2 device definitions. https://www.rfc-editor.org/rfc/rfc7228
  10. IETF RFC 8323, CoAP over TCP, TLS, and WebSockets, February 2018. https://www.rfc-editor.org/rfc/rfc8323
  11. IETF RFC 8613, Object Security for Constrained RESTful Environments (OSCORE), July 2019 — application-layer defence in depth. https://www.rfc-editor.org/rfc/rfc8613
  12. IETF RFC 7250, Using Raw Public Keys in Transport Layer Security (TLS) and DTLS, June 2014. https://www.rfc-editor.org/rfc/rfc7250
  13. IETF RFC 7641, Observing Resources in the Constrained Application Protocol (CoAP), September 2015. https://www.rfc-editor.org/rfc/rfc7641
  14. NIST SP 800-52 Rev.2, Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations, August 2019. https://csrc.nist.gov/publications/detail/sp/800-52/rev-2/final
  15. ISO/IEC 29167-19:2016, Information technology — Automatic identification and data capture techniques — Part 19: Crypto suite RAMON security services for air interface communications. https://www.iso.org/standard/70389.html
  16. OWASP IoT Top 10 (2018), Insecure Network Services / Lack of Secure Update Mechanism. https://owasp.org/www-project-internet-of-things/
  17. IETF RFC 8030, Generic Event Delivery Using HTTP Push, December 2016 — push notification layer interoperability. https://www.rfc-editor.org/rfc/rfc8030
  18. IETF RFC 7748, Elliptic Curves for Security, January 2016 — X25519 curve definition. https://www.rfc-editor.org/rfc/rfc7748
  19. NIST FIPS 186-5, Digital Signature Standard (DSS), February 2023 — P-256 curve definition. https://csrc.nist.gov/publications/detail/fips/186/5/final
  20. NIST SP 800-90B, Recommendation for the Entropy Sources Used for Random Bit Generation, January 2018. https://csrc.nist.gov/publications/detail/sp/800-90b/final
  21. GitHub: WIA-Official/wia-standards-public/tls-lite — chapter source, errata history, reproducible assets.