Datagram Transport Layer Security (DTLS)

Cover Image for Datagram Transport Layer Security (DTLS)

Introduction

Datagram Transport Layer Security (DTLS) is a protocol that provides secure communication over UDP. It was adapted from the TLS protocol, which is TCP based. DTLS tries to reuse as much from TLS as possible and only adds in what is necessary to make TLS work over UDP. I will not cover the specific additions in this post, but details about them can be found here, in the RFC.

DTLS versions mirror TLS versions, and at the time of this writing, TLS is on version 1.3, while the DTLS 1.3 spec has not yet been finalized. For that reason, this post will primarily focus on DTLS 1.2. For details about the differences in DTLS 1.3 vs 1.2, you can read this article by WolfSSL.

DTLS is particularly useful for security in real-time applications, where TCP would introduce too much latency. For example, online gaming and video / audio streaming are good candidates for DTLS. Furthermore, WebRTC's data channels use DTLS.

DTLS Handshake

Every TLS session between a client and server goes through a handshake process at the start. The 1.2 full handshake process is done in the following manner:

Client                                          Server
------                                          ------

ClientHello             -------->                           Flight 1

                        <-------    HelloVerifyRequest      Flight 2
                                     (contains cookie)

ClientHello             -------->                           Flight 3
(with cookie)

                                           ServerHello    \
                                          Certificate*     \
                                    ServerKeyExchange*      Flight 4
                                   CertificateRequest*     /
                        <--------      ServerHelloDone    /

Certificate*                                              \
ClientKeyExchange                                          \
CertificateVerify*                                          Flight 5
[ChangeCipherSpec]                                         /
Finished                -------->                         /

                                    [ChangeCipherSpec]    \Flight 6
                        <--------             Finished    /

Every step in the handshake process is viewed as a flight, where each flight can consist of multiple UDP messages because of UDP message size restrictions. However, a flight is viewed as a single entity from the protocol's retry and retransmission perspective.

More specifically, the 6 flights do the following:

  1. Flight 1: The initial ClientHello lets the server know that a client wants to start a session. It contains things like the DTLS protocol version, a session identifier, its list of supported cipher suites, and a random array of bytes called the "client random".
  2. Flight 2: The HelloVerifyRequest is sent to the client with a stateless cookie, generated from the ClientHello data. This step is specific to DTLS and does not exist in TLS. The cookie is used to counter potential DoS attacks in the handshake process.
  3. Flight 3: The client then sends another ClientHello that is the same as the original but containing the server generated cookie this time. This is effectively the start of the normal TLS handshake process but with an extra step of validating the cookie.
  4. Flight 4: The server determines the cipher suite to use, based on what both the client and server support, and sends the information to the client as part of the ServerHello. This flight also starts the key excange process used to generate a symmetric key that will be used as the session key.
  5. Flight 5: The client completes the key exchange process and sends a Finished message encrypted with the session key.
  6. Flight 6: The server then completes the handshake process by sending its own Finished message encrypted with the session key.

Note: The detailed key exchange process in flight 4 and 5 varies a lot based on the agreed upon cipher suite.

Cipher Suites

DTLS / TLS cipher suites are mostly the same, but DTLS does not allow stream ciphers. Furthermore, DTLS / TLS 1.2 supports many more cipher suites than 1.3, including ciphers now considered insecure. A cipher suite definition for 1.2 is typically shown in the following format: <key_exchange_algorithm>-<authentication_algorithm>-<cipher_algorithm>-<hash_or_mac_algorithm>. A list of cipher suites and whether they work with DTLS or not can be found here.

Note: The TLS 1.3 cipher suite format was simplified and is not backwards compatible with 1.2. The above list appears to contain both 1.2 and 1.3 formats.

Wrapping Up

In summary, DTLS provides a way to securely message between client and server, while using UDP, in much the same way that TLS does for TCP. In a future post, I will be showing how Philips Hue uses this for its light effect streaming API, so stay tuned.

References