In Part 1 of this series, we looked at UDP vs TCP for IoT applications and the pros and cons of choosing one protocol over the other.

In Part 2 we looked at communications using raw UDP packets to work out the theoretical efficiency that could be achieved.

In Part 3 we compared CoAP to Raw UDP and concluded that CoAP added very little overhead compared to Raw UDP but added a lot of features and opened an ecosystem of pre-build libraries and integrations.

One of the open questions from part 3 was how to secure CoAP communications. There is more than one answer to this question and is worthy of a blog post all of its own. The two options available are DTLS and OSCORE.

DTLS

DTLS stand for Datagram Transport Layer Security, is the UDP version of TLS, which is used for TCP connections.

TLS works by setting up a connection between the client and the server using a series of back-and-forth handshakes. A TLS session is only valid while the connection is open. Once the connection drops, a new TLS session needs to be established. The TLS handshaking process can consume a fair bit of data, depending on the size of the certificates used. TLS also relies on decrypting the packets in order, but as UDP packets do not have the concept of ordering or retransmission of lost packets this breaks one of the core foundations on which TLS is based.

In an IoT scenario where the device wakes up, opens a connection, sends a packet, and goes back to sleep again the TLS handshaking can consume 95% of the data transmitted which negates why data-efficient UDP is used in the first place.

DTLS uses similar principles to TLS except that instead of the session being constrained to a single connection, the session persists for a much longer period. DTLS credentials are stored in the device's memory and are only changed when the device physically resets, or the credentials expire (typically 2 weeks in a CoAP scenario). DTLS is designed to encrypt an entire UDP packet and acts as a wrapper around the payload.

The CoAP standard states that DTLS should be used for encrypting CoAP packets.

DTLS Drawbacks

There are some drawbacks to using DTLS for the security layer. The first of these is the amount of data needed for handshaking. While handshaking should not perform often, it can consume a fair bit of data if it needs to happen too often.

The second downside is that it is point-to-point encryption. Point-to-point encryption means that data is encrypted at one point and remains encrypted until it is decoded by the destination. The downside of this is that if a packet needs to go through a proxy (for instance moving from one network to another) then there is no way of introspecting the packet to work out its true destination without first decrypting the packet and encrypting it for the next leg of the journey. The CoAP standard allows for proxying, but without deciphering this feature is useless.

The proxying issue also means that load-balancing DTLS packets becomes very difficult. In a load-balanced UDP load balanced situation, all packets from a specific destination must be routed to one server otherwise, packet fragmentation resolution becomes insanely difficult if multiple servers have to keep coordinating with each other. UDP load balancing cannot occur until packets have been decrypted, which must happen before the load balancer, defeating the point of the load balancer in the first place.

OSCORE

Enter OSCORE. OSCORE is a newer standard for encrypting COAP packets. It was formalised as a standard in 1999. The OSCORE standard takes the COAP standard as its base and makes some modifications that enable encryption which is more appropriate to an IoT scenario.

OSCORE

The basic concept of OCORE is to add an extra Option header to the COAP packet that says, “I am an OSCORE packet”. Included in this options header is just enough security information to allow the packet to be decoded. The premise of OSCORE is to only encrypt sensitive information. So, Options headers like proxying information can be sent in clear text while other headers are encrypted along with the payload.

OSCORE also provides device authentication capabilities to CoAP which are otherwise missing. OSCORE works by first having provisioning devices with a SenderID and a Secret. This must be done in a secure environment such as in the factory. The SenderID and Secret are stored on both the device and the server.

There is no handshaking involved with OSCORE. Each COAP packet contains the SenderID and a PartialIV. The message is then encrypted using a standard known as COSE.

OSCORE adds minimal overhead to COAP packets (about 9 bytes) but provides encryption and device authentication, two key aspects of a robust IoT solution.

One of the other benefits of OSCORE is that it is designed for low-power devices. The encryption is easy for an MCU to perform.

As with any standard, there are software tools and libraries which make implementation much easier. That being said since OSCORE was only made a standard in 2019 so the ecosystem of tools and libraries still has a way to mature.

Conclusion

Resource-constrained devices which need to use the UDP protocol to communicate are best served by using CoAP OSCORE. CoAP/OSCORE is the most lightweight protocol for IoT devices, it includes all the key things needed for IoT communications such as security and device identification.