Security is an important part when communicating through the Internet. Despite the fact that without proper security practices, bad actors could break into our network infrastructures and cause severe damage to parties involved, there are still numerous devices, IoT appliances in particular, that expose themselves on the Internet without having any proper security measures in place.
Datagram Transport Layer Security (DTLS) [RFC-6347] is a protocol for traffic encryption on top of UDP [RFC-768]. It is based on the concepts of TLS [RFC-8446] and provides equivalent security guarantees. DTLS guarantees reliable transport during the handshake process but maintains UDP transport properties during application data transfer. The protocol is deliberately designed to be as similar to TLS as possible, both to minimize new security inventions and to maximize the amount of code and infrastructure reuse.
RIOT [bghkl-rosos-18] is an open source real-time OS, based on a modular architecture built around a lightweight micro-kernel, and developed by a worldwide community of developers. The modular approach enables easy prototyping and development to test new ideas and deploy applications. Its default network stack GNRC follows a cleanly layered, recursive design that easily allows for stacking and exchanging protocol layers or implementations.
In this paper, we describe how we built the DTLS abstraction layer on top of existing components in the RIOT networking architecture. This layer provides an API that can be implemented using third-party DTLS libraries. It is designed to be independent of the underlying DTLS implementation, therefore allows the DTLS stack to be exchanged without altering the applications that uses it. We also introduce a new RIOT module credman to manage the credentials used for the handshake.
The remainder of this paper is structured as follows. In Section II, we introduce the existing networking stack of RIOT. In Sections III, we describe the new secure network stack, and Section IV presents experiments that assess its performance. In Section V, we draw conclusions with an outlook on future work.
Ii RIOT networking subsystem
The RIOT networking subsystem is designed to follow a modular architecture with clean interfaces for abstracting all layers [lkhpg-cwemr-18]. This facilitates the creation and integration of new protocols, different implementations, or additional layers such as a new encryption layer to the existing stack. It consists of the two external APIs netdev, sock, and a single internal API for communication between layers, netapi. It is noteworthy that the RIOT networking subsystem simultaneously supports multiple interfaces with different protocol stacks, which makes it capable of running gateway services. An architectural overview is visualized in Figure 1.
The Device Driver API: netdev. Individual network devices in RIOT are abstracted via netdev, which allows networking stacks access to the devices via a common, portable interface. netdev remains neutral in that it does not enforce implementation details regarding memory allocation, data flattening, and threading. These decisions are delegated to the users of the interface.
The Internal Protocol Interface: netapi. Internal protocol layers in the RIOT networking subsystem can be recursively composed via the netapi. The interface is kept simple so that even an exotic networking protocol could be implemented against it. Message passed between layers are typed as following: two asynchronous message types (MSG_TYPE_SND, MSG_TYPE_RCV) and two synchronous message types (MSG_TYPE_GET, MSG_TYPE_SET) that expects a reply in form of MSG_TYPE_ACK typed message. No further semantic are built into the messages of netapi, but certain preconditions on packets or option values handed to netapi can be set as requirements to implement more complex behavior that goes beyond these plain specification.
The User Programming API: sock. This module provides a network API for applications and libraries in RIOT. It provides a set of functions to establish connections or send and receive datagrams using different types of protocols. In comparison to POSIX sockets, sock does not require complex and memory expensive implementation and therefore more suited for use in constrained hardware. Only common type and definitions from either libc or POSIX. This ensures that sock is easy to port to other target OS.
GNRC is the native IPv6 networking stack for RIOT. It takes full advantage of the multi-threading model supported by RIOT to foster a clean protocol separation via well-defined interfaces and IPC. Each network protocol is encapsulated in its own thread and uses RIOT thread-targeted IPC with a message queue in each thread to communicate between layers. Other stacks that introduce different networking protocols such as ICN also integrate via the same interfaces. Various experimental evaluations and benchmarks [lkhpg-cwemr-18, gklp-ncmcm-18] have proven the feasibility and efficiency of this flexible approach to networking in RIOT.