16  TLS/DTLS Transport Security for IoT

16.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Explain TLS Handshake: Describe how TLS establishes secure connections using certificates and key exchange
  • Compare TLS and DTLS: Select the appropriate protocol based on transport layer (TCP vs UDP)
  • Configure IoT-Optimized TLS: Apply session resumption, pre-shared keys, and connection keep-alive for constrained devices
  • Implement Certificate Validation: Verify server certificates and handle certificate pinning
In 60 Seconds

TLS (for TCP) and DTLS (for UDP) provide mutual authentication and encrypted channels between IoT devices and services, forming the foundation of secure IoT transport-layer communications.

MVU: TLS/DTLS Selection Framework

Core Concept: Transport layer security choice is determined by three factors: underlying protocol (TCP vs UDP), device constraints (RAM/flash), and network conditions (latency/loss). TLS 1.3 for TCP-based protocols (MQTT, HTTPS), DTLS 1.3 for UDP-based protocols (CoAP, LwM2M).

Why It Matters: Using TLS over UDP-based CoAP fails because TLS requires TCP’s reliable delivery. Conversely, forcing CoAP over TCP just to use TLS adds 10-20 KB RAM overhead and defeats CoAP’s lightweight design. Smart thermostat vendors who chose wrong spent 18 months redesigning firmware.

Key Takeaway: Match security protocol to transport: TCP protocol = TLS, UDP protocol = DTLS. For devices under 32 KB RAM, consider DTLS with PSK (no certificate parsing needed, saves ~5 KB code space).

Transport layer security (TLS/DTLS) creates encrypted tunnels for IoT data traveling across networks. Think of it as an armored truck for your data – even if someone intercepts the truck on the highway, they cannot access the valuable contents inside.

TLS is the “S” in HTTPS – it provides encrypted, authenticated connections over TCP. DTLS (Datagram TLS) does the same for UDP-based protocols like CoAP. When your smart thermostat connects to the cloud, TLS/DTLS ensures: (1) data is encrypted so eavesdroppers cannot read it, (2) the server is authenticated so you are not talking to an imposter, and (3) messages cannot be modified in transit.

Hey there, future inventor! Ever wonder how your smart devices prove they’re talking to the right server?

Meet the Security Squad:

  1. Tina TLS - The master of secret handshakes for reliable messages
  2. Danny DTLS - Tina’s brother who works with quick, short messages
  3. Certie Certificate - Carries the official ID card that proves who you are
  4. Krypto Key - Holds the secret codes that scramble messages

The Secret Handshake Story:

When your smart light bulb wants to talk to the cloud:

  1. Light bulb: “Hi! I want to talk securely. Here are some secret codes I know.”
  2. Cloud server: “Hello! I pick this code. Here’s my ID card (certificate) to prove I’m really the cloud.”
  3. Light bulb: “Let me check that ID card… looks real! Here’s our secret key.”
  4. Both: Now they share a secret code that only they know!

After the handshake, all their messages are scrambled with the secret code. Even if a sneaky hacker listens in, they just hear gibberish!

Think of it like this: When you meet your best friend, you might have a secret handshake. TLS is like a super-complicated secret handshake that proves: (1) You’re really you, (2) They’re really them, and (3) Only you two understand what you’re saying!

Fun Challenge: Next time you see “https://” in a web address (with the “s” for secure), you know TLS is doing its secret handshake!


16.2 TLS vs DTLS Overview

How It Works: TLS/DTLS Handshake Process

Understanding the handshake is crucial to understanding why TLS and DTLS differ:

Step 1: ClientHello - The client (IoT device) proposes cipher suites and sends its ECDHE public key share. This is where the device says “I support these encryption methods.”

Step 2: ServerHello - The server (cloud endpoint) selects the cipher suite and sends its own ECDHE public key share. Both sides now have enough information to compute a shared secret.

Step 3: Certificate Exchange - The server sends its X.509 certificate to prove its identity. The device verifies this certificate against its trust store.

Step 4: Key Derivation - Both sides independently compute the same symmetric encryption keys from the ECDHE shared secret using HKDF. No attacker observing the exchange can derive these keys.

Step 5: Finished Messages - Both sides send encrypted “Finished” messages containing a MAC of the entire handshake transcript. This proves they both derived the same keys and prevents tampering.

Why DTLS is different: UDP packets can arrive out of order or be lost. DTLS adds epoch numbers, sequence numbers, and retransmission timers to handle this unreliability while maintaining the same security guarantees.

Decision flowchart for choosing between TLS and DTLS based on transport protocol, showing TCP protocols flowing to TLS and UDP protocols flowing to DTLS

16.2.1 Protocol Comparison

Feature TLS 1.3 DTLS 1.3
Transport TCP (reliable, ordered) UDP (unreliable, unordered)
Use Case MQTT, HTTPS, HTTP/2 CoAP, LwM2M, real-time
Handshake RTTs 1-RTT (0-RTT with PSK) 1-RTT + cookie exchange
Record Overhead ~29 bytes/record ~25 bytes/record (unified header)
Retransmission TCP handles it DTLS must handle it
Connection State Persistent Can be stateless after handshake

16.2.2 When to Use Each

Choose TLS when:

  • Using HTTP/HTTPS, MQTT, or TCP-based protocols
  • Reliability is critical (firmware updates, commands)
  • Network supports persistent connections
  • Device has memory for TCP stack (~10-20 KB)

Choose DTLS when:

  • Using CoAP, LwM2M, or UDP-based protocols
  • Network is lossy or high latency (satellite, LoRaWAN backhaul)
  • Device memory is severely constrained (<32 KB RAM)
  • Real-time data where occasional loss is acceptable
  • Multicast communication needed


16.3 TLS 1.3 Handshake

Detailed TLS 1.3 handshake sequence showing ClientHello, ServerHello, Certificate, CertificateVerify, and Finished messages with key derivation points

16.3.1 Handshake Components

Step Purpose Size Impact
ClientHello Propose cipher suites, send ECDHE key share ~200 bytes
ServerHello Select cipher, send key share ~100 bytes
Certificate Server’s identity proof 500-2000 bytes
CertificateVerify Signature proving private key ownership 64-256 bytes
Finished MAC of handshake transcript 48 bytes

16.4 IoT Optimizations

Diagram showing four IoT TLS optimization techniques: Session Resumption, Pre-Shared Keys, Certificate Compression, and Connection Keep-Alive

16.4.1 1. Session Resumption (0-RTT)

After the first handshake, subsequent connections can skip key exchange:

Benefits:

  • Reduces connection time from ~200 ms to ~0 ms
  • Saves battery on frequent reconnections
  • Critical for sleepy IoT devices
0-RTT Replay Risk

Caution: 0-RTT data can be replayed by attackers. The server has no way to distinguish a legitimate 0-RTT message from one replayed by an attacker who recorded it.

Safe for 0-RTT:

  • Read-only queries (GET sensor data)
  • Idempotent operations

NOT safe for 0-RTT:

  • Actuator commands (unlock door, dispense medicine)
  • Financial transactions
  • Any state-changing operation

16.4.2 2. Pre-Shared Keys (PSK)

Mode Key Exchange Authentication Use Case
Certificate ECDHE X.509 Certificate Standard TLS
PSK PSK Pre-shared key Constrained devices
PSK + ECDHE ECDHE + PSK Both Maximum security with forward secrecy

PSK Benefits:

  • No certificate parsing (saves ~5 KB code)
  • Faster handshake (no signature verification)
  • Works with symmetric-only hardware

PSK Drawbacks:

  • Key management complexity
  • No perfect forward secrecy in PSK-only mode (use PSK+ECDHE to retain it)
  • Must provision keys securely during manufacturing

16.4.3 3. Certificate Compression

TLS 1.3 supports certificate compression (RFC 8879):

Format Typical Size Compressed
X.509 RSA-2048 1,500 bytes ~800 bytes
X.509 ECDSA-256 500 bytes ~300 bytes

16.4.4 4. Connection Keep-Alive

Keep TLS connections alive instead of reconnecting:

Without keep-alive:
  Connect -> Handshake (200ms) -> Send -> Disconnect
  Connect -> Handshake (200ms) -> Send -> Disconnect
  Total: 400ms + 2 handshakes

With keep-alive:
  Connect -> Handshake (200ms) -> Send -> Keep-alive -> Send
  Total: 200ms + 1 handshake

16.5 Certificate Validation

Flowchart showing certificate validation process: receive certificate chain, verify signatures up to trusted root, check expiration dates, verify hostname, and make final trust decision

16.5.1 Certificate Pinning

Pinning Type What’s Pinned Flexibility Security
None Trust any valid certificate High Lower
CA Pin Specific root/intermediate CA Medium Medium
Leaf Pin Server’s exact certificate Low Higher
SPKI Pin Server’s public key Low Highest
Certificate Pinning Risks

Bricking risk: If pinned certificate expires or is rotated, devices cannot connect. Always implement:

  1. Backup pins (next certificate in rotation)
  2. Pin update mechanism (OTA update path)
  3. Pinning bypass for emergencies (with strong authentication)

16.6 Cipher Suite Selection

TLS 1.3 simplified cipher suites to only secure options:

Cipher Suite Encryption Hash IoT Suitability
TLS_AES_128_GCM_SHA256 AES-128-GCM SHA-256 Recommended (HW-accelerated on most MCUs)
TLS_AES_256_GCM_SHA384 AES-256-GCM SHA-384 High security requirements
TLS_CHACHA20_POLY1305_SHA256 ChaCha20-Poly1305 SHA-256 Devices without AES hardware

In TLS 1.3, key exchange is negotiated separately from the cipher suite. All three cipher suites above use ECDHE for key exchange, typically with Curve25519 or P-256.

IoT Recommendation: Use TLS_AES_128_GCM_SHA256 with ECDHE (Curve25519 or P-256) for best balance of security and performance.


16.7 Worked Example: TLS Performance on Constrained Devices

Scenario: Compare TLS handshake performance across three common IoT platforms to determine which optimizations are necessary for battery-powered deployments.

16.7.1 Measured Handshake Times

Platform CPU RAM Full TLS 1.2 (RSA-2048) Full TLS 1.3 (ECDHE-P256) PSK Resumption 0-RTT
ESP32 240 MHz dual-core 520 KB 1,200 ms 450 ms 35 ms ~0 ms
nRF52840 64 MHz Cortex-M4 256 KB 3,800 ms 1,200 ms 80 ms ~0 ms
STM32L4 80 MHz Cortex-M4 128 KB 4,500 ms 1,600 ms 95 ms ~0 ms

16.7.2 Energy Cost Per Handshake

# Calculate battery impact of TLS handshakes for a sensor
# reporting every 15 minutes over 2-year battery life

reports_per_day = 96  # every 15 minutes
battery_capacity_mAh = 2400  # typical AA lithium x2
device_voltage = 3.3  # volts

# Current draw during TLS handshake (measured)
handshake_current_mA = {
    "ESP32": 160,       # Wi-Fi + crypto
    "nRF52840": 8,      # BLE + crypto
}

# Energy per handshake (mAh)
for platform, current in handshake_current_mA.items():
    # Full handshake
    full_time_s = 0.45 if platform == "ESP32" else 1.2
    full_energy = current * (full_time_s / 3600)  # mAh per handshake
    full_daily = full_energy * reports_per_day
    full_yearly = full_daily * 365
    full_pct = (full_yearly / battery_capacity_mAh) * 100

    # PSK resumption
    psk_time_s = 0.035 if platform == "ESP32" else 0.08
    psk_energy = current * (psk_time_s / 3600)
    psk_daily = psk_energy * reports_per_day
    psk_yearly = psk_daily * 365
    psk_pct = (psk_yearly / battery_capacity_mAh) * 100

    print(f"\n{platform}:")
    print(f"  Full handshake: {full_energy*1000:.2f} uAh/handshake")
    print(f"    Annual energy: {full_yearly:.1f} mAh ({full_pct:.1f}% of battery)")
    print(f"  PSK resumption: {psk_energy*1000:.2f} uAh/handshake")
    print(f"    Annual energy: {psk_yearly:.1f} mAh ({psk_pct:.1f}% of battery)")
    print(f"  Battery savings with PSK: {full_pct - psk_pct:.1f}% annually")

Key finding: On an nRF52840 BLE sensor reporting every 15 minutes, full TLS 1.3 handshakes consume ~3.9% of battery annually (93.4 mAh/year). PSK resumption reduces this to ~0.3% (6.2 mAh/year) – a 93% reduction in handshake energy, making 2+ year battery deployments feasible.

Exercise: Measure the TLS handshake time on your development board and calculate battery impact.

What you’ll need: ESP32 or nRF52840, mbedTLS library, millisecond-precision timer

Steps:

  1. Implement a basic TLS client connecting to a test server
  2. Measure time from mbedtls_ssl_handshake() start to completion
  3. Measure current draw during handshake using a multimeter
  4. Calculate energy consumed: current (mA) x time (hours) = mAh
  5. Multiply by daily connection frequency to get annual impact

What to observe:

  • Full handshake time: 300-1500 ms depending on device
  • PSK resumption time: 20-100 ms (10-15x faster)
  • Current draw spike during crypto operations
  • Battery life extension from PSK resumption

Expected result: PSK resumption saves 90-95% of handshake energy, making battery-powered IoT devices feasible for 2-5 year deployments.

16.7.3 ESP32 mbedTLS Configuration

// Minimal TLS 1.3 configuration for ESP32 (mbedTLS)
// Optimized for IoT: PSK + session resumption

#include "esp_tls.h"

esp_tls_cfg_t tls_cfg = {
    // Use PSK instead of certificates (saves ~5KB RAM)
    .psk_hint_key = &psk_hint_key,

    // Enable session tickets for 0-RTT resumption
    .session_tickets = ESP_TLS_SESSION_TICKETS_ENABLED,

    // Restrict to TLS 1.3 cipher suites
    // AES-128-GCM recommended (hardware accelerated on ESP32)
    .ciphersuites_list = (const int[]){
        MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
        0  // null terminator
    },

    // Connection timeout (important for battery devices)
    .timeout_ms = 10000,

    // Skip hostname verification for IP-based connections
    // WARNING: Only use when connecting to known IP addresses
    .skip_common_name = false,
};

// Connect with optimized TLS
esp_tls_t *tls = esp_tls_init();
int ret = esp_tls_conn_new_sync(
    "iot-server.example.com", strlen("iot-server.example.com"),
    8883, &tls_cfg, tls
);

if (ret == 1) {
    // Connection established - send sensor data
    esp_tls_conn_write(tls, payload, payload_len);
}

Product: A major smart thermostat brand (2019 security audit)

Problem: Devices used TLS 1.2 with RSA-2048 certificates over CoAP/UDP. The TLS library silently fell back to unencrypted UDP when the handshake failed due to packet loss – which happened regularly on home Wi-Fi networks.

Root cause analysis:

Issue Impact
TLS over UDP (should be DTLS) Handshake fails on packet loss – TLS expects TCP reliability
Silent fallback to plaintext 15-30% of connections were unencrypted without user knowledge
No certificate pinning MITM attacks possible even on encrypted connections
4,500 ms handshake on MCU Battery drain forced aggressive timeout, increasing fallback rate

Fix timeline: 18 months to redesign firmware from TLS/UDP to DTLS/UDP with PSK mode. During that time, millions of devices transmitted temperature schedules (occupancy patterns) in plaintext.

Lesson: Always match the security protocol to the transport layer. TLS = TCP. DTLS = UDP. There is no shortcut.

16.8 Implementation Libraries

Library Platforms Size Features
mbedTLS Embedded, Linux 60-100 KB TLS 1.3, DTLS 1.2, PSK
wolfSSL Embedded, RTOS 20-100 KB TLS 1.3, DTLS 1.3, FIPS
BearSSL Embedded 25-75 KB TLS 1.2, minimal footprint
OpenSSL Linux, desktop 500+ KB Full-featured

IoT Recommendation: Use mbedTLS for most ESP32/STM32 projects. Consider wolfSSL for DTLS 1.3 or FIPS compliance. BearSSL is a good choice for extremely constrained devices needing a minimal TLS 1.2 stack.


16.9 Concept Relationships

How TLS/DTLS Concepts Connect
Concept Builds On Enables Related To
TLS 1.3 TCP reliability Secure HTTP/MQTT Encryption Principles
DTLS 1.3 UDP datagram model Secure CoAP/LwM2M UDP Protocol Basics
Session Resumption PSK derivation 0-RTT connections Key Management
Certificate Pinning X.509 PKI MITM prevention Authentication Methods
Cipher Suites Symmetric + asymmetric crypto Secure channel establishment Cryptographic Algorithms

Key insight: TLS/DTLS are protocol-layer compositions of fundamental cryptographic primitives. Understanding the building blocks (symmetric encryption, key exchange, certificates) is essential to understanding why TLS/DTLS work.

The total cost of establishing a TLS/DTLS session includes message size overhead, computational time, and energy consumption.

Handshake Message Overhead: \[\text{Total Bytes} = \text{ClientHello} + \text{ServerHello} + \text{Certificate} + \text{CertificateVerify} + \text{Finished}\]

Session Resumption Savings: \[\text{Savings Ratio} = \frac{\text{Full Handshake Cost} - \text{PSK Resumption Cost}}{\text{Full Handshake Cost}}\]

Working through an example:

Given: nRF52840 BLE sensor reporting every 15 minutes for 2 years

Full TLS 1.3 Handshake (ECDHE-P256):

  • Time: \(T_{\text{full}} = 1,200 \text{ ms}\)
  • Current draw: \(I = 8 \text{ mA}\)
  • Energy per handshake: \(E_{\text{full}} = I \times \frac{T_{\text{full}}}{3600 \text{ s/h}} = 8 \times \frac{1.2}{3600} = 0.00267 \text{ mAh}\)

Annual handshakes: \(96 \text{ per day} \times 365 \text{ days} = 35{,}040 \text{ handshakes/year}\)

Annual energy cost: \(E_{\text{annual}} = 35{,}040 \times 0.00267 = 93.5 \text{ mAh/year}\)

Battery fraction: \(\frac{93.5}{2400} = 3.9\%\) of battery per year for handshakes alone

PSK Resumption:

  • Time: \(T_{\text{PSK}} = 80 \text{ ms}\)
  • Energy per resumption: \(E_{\text{PSK}} = 8 \times \frac{0.08}{3600} = 0.000178 \text{ mAh}\)
  • Annual energy: \(35{,}040 \times 0.000178 = 6.2 \text{ mAh/year}\)
  • Battery fraction: \(\frac{6.2}{2400} = 0.26\%\) per year

Energy savings: \(93.5 - 6.2 = 87.3 \text{ mAh/year}\) (93.4% reduction)

Result: PSK session resumption reduces TLS handshake energy consumption by 93%, freeing up 87.3 mAh/year for other device functions. For a device where TLS handshakes are the dominant energy cost (e.g., a sensor that sleeps between reports), this savings can extend battery life from approximately 2 years to well over 5 years.

In practice: Without session resumption, devices performing 96 daily connections consume 3.9% of a 2400 mAh battery per year on handshakes alone. With other energy costs (radio, sensing, MCU), this can be the difference between meeting a 2-year battery target or falling short. PSK session resumption makes the handshake energy nearly negligible.

Common Pitfalls

Configuring TLS to accept self-signed or expired certificates removes all authentication guarantees. In IoT, use a private CA for device certificates and always validate the full chain.

Failed TLS handshakes should not result in falling back to unencrypted communication. Always treat handshake failure as a hard error and do not transmit data over unprotected channels as a fallback.

DTLS uses epoch numbers to separate key changes from packet loss. Mishandling epoch transitions causes devices to reject valid messages or accept replays. Test DTLS implementations specifically for epoch rollover scenarios.

Many embedded TLS libraries default to supporting older TLS versions for compatibility. Explicitly configure minimum TLS 1.2 (preferably 1.3) in all firmware configurations before shipping.

:

16.10 What’s Next

If you want to… Read this
Learn how TLS certificates are managed Key Management
Study E3/E4 transport encryption layers E3/E4 Transport Encryption
Explore cryptographic security properties Encryption Security Properties
Practice TLS in hands-on labs Encryption Labs

Continue to Key Management for IoT to learn how to securely generate, store, distribute, and rotate cryptographic keys throughout the device lifecycle.

Chapter Relationship
Encryption Principles Foundation: symmetric and asymmetric encryption used by TLS
ECC for IoT Key exchange: ECDHE curves used in TLS handshake
Key Management Next step: managing the keys TLS depends on
E3-E4 Transport Encryption Context: where TLS fits in the multi-layer encryption architecture