By Loïc Dalmasso, PhD, Cybersecurity Software Engineer
The International Telecommunication Union (ITU) defined the Internet of Things (IoT) as “a global infrastructure for the information society, enabling advanced services by interconnecting objects (physical and virtual) using existing or evolving interoperable information and communication technologies”.
In other words, the IoT operates the information gathering, processing, action, and communication capabilities of autonomous entities with the aim of creating new services and applications. Many industries benefit from IoT capabilities, including metering (e.g., electrical, gas, water), smart city, automotive, healthcare, and environmental, to name just a few. It is straightforward to imagine an IoT use case: the interconnection of several temperature, humidity, and pressure sensors spread over a geographical area (e.g., region, country, etc.) to create a weather service. More recently, the Tesla Model X’s owner can control the car with its smartphone to lock/unlock the vehicle, control heating or air conditioning, collect the car’s information, etc. By connecting anything to the global network, the scientific community also extends the concept of IoT to the Internet of Everything (IoE). Even if the IoT/IoE services create important economies of scale disrupting existing processes, they bring huge security and privacy challenges.
As the name suggests, objects are the main element in an IoT ecosystem. They are physical elements, integrating one or more sensors and/or actuators with data processing and communication capacities. By definition, IoT devices are deployed everywhere, and they are subject to various constraints in terms of size, memory, computing power, and energy consumption. In addition, because of the sensitive nature of data (e.g., healthcare, bank information …), IoT devices are key targets for hackers. Indeed, in 2020, a COSIC (Computer Security and Industrial Cryptography Group) team showed how to exploit vulnerabilities in the Tesla Model X’s entry system to steal the vehicle: the team was able to rewrite the firmware of the Tesla key fob from Bluetooth connection to get an unlock code and then enter in the vehicle, in just a matter of minutes. We can then look ahead and imagine that such an attack could go even further, for example, by re-programming the Tesla’s firmware for malicious purposes. This is a perfect example of IoT vulnerabilities: use a weak point in the ecosystem to get access to the most sensitive system. With the emergence of cyber-attacks, devices must embed security mechanisms ensuring both confidentiality and integrity of exchanges, as well as communication authentication, while taking into account their resource constraints.
One of the most important features of an IoT device is its ability to communicate (inbound and outbound). In the Tesla scenario, the two critical vulnerabilities are the lack of authentication and authentication during the firmware update of the key fob and during the paring between the fob and the Tesla. Nevertheless, standard solutions already exist: TLS protocol (Transport Layer Security) [3] to secure exchange over TCP (Transmission Control Protocol), and DTLS [4] to secure exchange over UDP (User Datagram Protocol). Have a look at our previous articles [5–6] on TCP/UDP and TLS/DTLS for complementary information. TLS/DTLS protocols ensure host-to-host authentication, confidentiality, and communication integrity between two entities, also known as `hop-by-hop` security.
Ensuring security in an IoT ecosystem is a real challenge because of its high heterogeneity and dynamic nature. As we explained before, any kind of devices are deployed in the environment, and they are in a perpetual state of flux (i.e., connected/disconnected), mainly for energetic reasons. To collect data from the device to the server/cloud, there may be many intermediaries (e.g., proxy, gateway, other device …), introducing many security issues. Therefore, it is decisive to set up a mechanism that provides security from the device to the server/cloud. This is the so-called `end-to-end` security.
The notion of `end-to-end` refers to the ability of the protocol to secure communication from the very beginning of the transmission (i.e., the sender) to its termination (i.e., the receiver).
Let’s simplify the following scenario to highlight the main difference between `hop-by-hop` and `end-to-end` security: You want to send a letter to a friend to make an appointment at a specific time and location.
If you don’t care about security, you simply write your letter, indicate your friend’s address, and mail it off. The postman will pick up the letter and get your friend’s address, but he can also read the contents of your letter, a.k.a. the appointment time and location (cf. Figure 1).
Now you don’t want anyone to be able to read your letter. So you write your letter, indicate your friend’s address, put it in a blank envelope, and mail it off. At this stage, everyone can see your envelope but no one can read what’s inside without opening it. However, for your letter to reach its destination, the postman will have to open it to retrieve your friend’s address. He, in turn, can put your letter back in its blank envelope and send it to your friend. Once again, no one will be able to read the contents of the letter while it’s in transit to your friend. However, you have no guarantee that the postman has not read the contents of your letter (the appointment time and location) before sending it to your friend (cf. Figure 2).
To fully ensure confidentiality of the appointment time and location, you decide to write your letter, put it in an envelope, write on it your friend’s address and then seal the envelope with a wax seal. Once again, everyone can see your envelope but now no one can neither read what’s inside nor open it, even the postman. In addition, the latter doesn’t even have to open it, because your friend’s address is printed on the envelope. He just needs to forward your letter to the right destination. In this configuration, only you and your friend know the appointment time and location. Congratulations, you’ve just set up your first end-to-end security system! (cf. Figure 3).
As explained above, TLS/DTLS protocols work at the Transport Layer in a `hop-by-hop` scheme: communication between two entities is secured, as shown in Figure 4.
In this specific configuration, TLS/DTLS performs the `end-to-end` security: the device-to-server communication is secured. No one except the device and the server can access the data.
Now let’s take a basic IoT scenario: the device has a limited communication range (e.g., Bluetooth), and it has to send its data to the server. An intermediary node (e.g., proxy) has to be placed between the device and server; both collect device data and send it to the server (cf. Figure 5).
In such a scenario, TLS/DTLS secure communications through two distinct TLS/DTLS channels, device-to-proxy and proxy-to-server. This leads to a double encryption process: the client encrypts and sends data to the proxy. Then, the proxy decrypts the data, re-encrypts it, and sends it to the server. So here, the device-to-server communication is NOT secured; TLS/DTLS does not ensure end-to-end security since the proxy has access to all data (in the clear). This is a security point of failure.
Another security protocol must be used to ensure the `end-to-end` security from device to server/cloud.
OSCORE [7] (Object Security for Constrained RESTful Environments) is an application layer security protocol protecting CoAP [8] (Constrained Application Protocol), a web transfer protocol designed for constrained nodes and networks. OSCORE is also designed for constrained nodes and networks, providing end-to-end security (i.e., confidentiality, integrity, and message authenticity) thanks to the AEAD encryption (Authenticated Encryption with Associated Data) and its several protection modes, depending on the criticality of each part of a message: while confidentiality and integrity are applied to the payload (most sensitive data), some options can be integrity protected only, and non-sensitive data are kept visible (e.g. CoAP Token, CoAP URI-Host, etc.). Due to these capabilities, OSCORE prevents alterations/access of any message field by intermediary nodes, such as proxies, while allowing them to perform operations (e.g., forwarding and scheduling CoAP requests/responses, translation between protocols).
In addition, it is important to note that since OSCORE operates at the application layer, it can be used with any transport layer security, such as TLS/DTLS protocols. In such a configuration, the application data are secured by OSCORE, while TLS/DTLS secures the whole data exchange (e.g., CoAP headers and options). When the intermediate node receives the OSCORE-TLS/DTLS message, it can only access the TLS/DLS-secured message part but not the OSCORE-secured message part (a.k.a application data). Only the recipient can access this part.
Also, OSCORE is compatible with any transport layer protocol such as TCP, UDP, or non-IP transports.
OSCORE transforms a CoAP message into an OSCORE message before sending, and vice versa after receiving (cf. Figure 6).
The CoAP message is divided into three classes:
- Class U: unprotected part (most of the CoAP header fields and some options)
- Class I: integrity protected only (currently no header/option field)
- Class E: encrypted and integrity protected (the CoAP code, some options, and the payload)
The header/options fields of the OSCORE message include Class U elements. They are not protected and are visible by intermediary nodes, facilitating proxy operations, and they are directly mapped to the header and option fields of the OSCORE message.
Figure 7 shows the introduced “OSCORE option” has to be formatted, as shown in Figure 18. This option indicates that the CoAP message is in OSCORE form and provides the necessary elements to the receiver to correctly handle the message.
Opposite class U and class I, class E (payload, CoAP Code, and some options) is encrypted by the AEAD algorithm before being included in the OSCORE message. Future options could be integrity-protected only as additional data of the AEAD algorithm.
To enable secured communication with OSCORE, the client and server have to set up a shared configuration, a.k.a OSCORE context, which is the set of information elements necessary to carry out the cryptographic operations. The security context of OSCORE is composed of 3 contexts, detailed in Figure 8 and Table 1:
- Common Context: shared configuration
- Sender Context: used to protect messages to send
Each endpoint has to embed the three contexts. Since OSCORE uses symmetric cryptography only, the Sender Context (used to send a message) and the Recipient Context (used to verify the message) of two endpoints are mirrored, as shown in Figure 9: the Sender Context of the client is linked to the Recipient Context of server, and vice versa.
The OSCORE context configuration requires setting the Master Secret, the Sender ID, and the Recipient ID. Other elements, such as Master Salt, ID Context, and algorithms, are optional. If they are not set, the OSCORE RFC defines the default values.
The Sender Key et Recipient Key are always derived from the current OSCORE configuration (i.e., Master Secret, Master Salt, ID Context, Sender/Recipient ID), as shown in Figures 10 & 11.
Since OSCORE relies on symmetric-key cryptography only, the most important requirement is to ensure Sender Key uniqueness for each endpoint. Indeed, if several endpoints use the same sender key, OSCORE cannot ensure the confidentiality, integrity, or message authenticity. To ensure this unicity, the quartet (Master Secret, Master Salt, ID Context, and Sender ID) has to be unique, as shown in Figure 12.
However, OSCORE allows clients and servers to share the same Master Secret and Master Salt. Consequently, to ensure the Sender Key’s uniqueness, the couple ID Context — Sender ID has to be unique. Note that this requirement does not prohibit using the same Sender ID with multiple ID Context and vice-versa. For example, (ID Context A — Sender ID 1), (ID Context A — Sender ID 2), (ID Context B — Sender ID 3), and (ID Context C — Sender ID 3) are all unique couples. Finally, it is also possible to share Master Secret, Master Salt, and ID Context between all endpoints. In this case, the uniqueness of the Sender Key relies on the uniqueness of the Sender ID.
Note that the Sender ID’s uniqueness implicitly sets up the Receiver ID and Receiver Key’s uniqueness on the receiver side. As a reminder, the Sender ID/Key on the sender endpoint corresponds to the Receiver ID/Key on the receiver endpoint.
Another critical security requirement is related to the AEAD algorithm. The latter requires a unique key–nonce pair, meaning that a nonce has not to be used more than once for the same key. To handle this property, OSCORE uses the Sender Sequence Number to construct the nonce: The most straightforward implementation is a counter incremented before each message is sent. OSCORE provides rules to handle the unexpected Sender Sequence Number loss (e.g., reboot) by storing the latter in non-volatile memory
TLS, DTLS, and OSCORE rely on the same cryptography algorithms (e.g., AES-CCM), depending on the used cipher suites. Therefore, they intrinsically provide the same security requirements, such as confidentiality, integrity, and authenticity. However, they differ in their securing approach. TLS and DTLS encrypt the entire CoAP message, while OSCORE encrypts only some parts (e.g., payload). This implies a higher cryptography overhead of TLS/DTLS since it requires more encryption processes than OSCORE to encrypt the whole application message.
Also, since all fields are encrypted, TLS and DTLS are not optimized for proxy operation. Therefore, each intermediary has to decrypt-then-encrypt the received message before forwarding it to the next node, potentially exposing sensitive data at the proxy. This is the so-called Hop-by-Hop security scheme. In contrast, OSCORE leaves some parts of the CoAP message unencrypted, facilitating proxy operations while keeping sensitive data protected all the way to the recipient (i.e., End-to-End security scheme).
Another advantage of OSCORE is its higher compatibility compared to TLS/DTLS. TLS is used only over the TCP transport layer, while DTLS can be used over specific transport layers such as UDP or SMS. In contrast, OSCORE is an application-layer security protocol, meaning that it can be used over any transport layer and even in conjunction with TLS or DTLS.
[9] provides a fair comparison between TLS, DTLS, and OSCORE in terms of message size overhead for a plaintext of 6 bytes (and the sequence number ‘05’), shown in Table 2:
Results highlight that DTLS 1.2 and TLS 1.2 have the largest overhead. Using the Generic Header Compression (6LoWPAN-GHC) allows to reduce the overhead, but their 1.3 version remains smaller. The lightweight options are DTLS 1.3 and OSCORE. It is interesting to note that even if DTLS 1.3 is smaller (only 2 bytes) than OSCORE when the Connection/Sender ID is empty, thanks to the OSCORE structure, the response overhead is fixed independently of the sequence number or Sender ID. As a consequence, OSCORE overhead becomes more profitable than DTLS 1.3 with increasing Connection/Sender ID. In a realistic scenario, these ids are seldom empty. Indeed, for DTLS, as discussed in our previous blog [5], the Connection ID is composed of, at most, a 32-byte value, and the DTLS Server generates it. Regarding OSCORE, the Sender ID is at most 7 bytes.
Also, Gunnarsson et al. [10] emphasize the lower execution overheads of OSCORE against DTLS 1.2 in terms of message size (-45% of request-response exchange), transmission time (-29%), CPU computation time (-50%), memory utilization (-15% RAM; -15% ROM) and energy consumption (-30%).
Even if previous elements show OSCORE as a lightweight alternative to TLS and DTLS. However, OSCORE is a new protocol and does not benefit from a large user community like TLS/DTLS. Today, many IoT devices contain embedded TLS libraries, facilitating implementation, whereas OSCORE must be added. The most significant limitation of OSCORE is its lack of a handshake mechanism to facilitate key exchanges and endpoint authentication: before any application data exchange, two endpoints have to authenticate each other and reach an agreement on the cryptographic algorithms used in the following communication channel.
Because OSCORE has no such procedure to set up the keying materials, both endpoints must agree on all cryptographic elements and and identities. Otherwise, no application data exchange will be possible (e.g., impossible to decrypt the message if endpoints do not use the same algorithm, same secret, etc.). One possibility is to use the TLS/DTLS handshake protocol to set up an OSCORE key exchange. However, this approach requires the implementation of TLS/DTLS handshake and OSCORE side-by-side. Also, as mentioned above, TLS and DTLS were not designed for constrained devices. Recently, efforts have paid off since the release of RFC 9528 Ephemeral Diffie-Hellman Over COSE (EDHOC) [11]. This approach, based on Diffie-Hellman, is a very compact and lightweight key exchange mechanism providing mutual authentication and perfect forward secrecy. This makes up for the lack of handshake protocol for OSCORE.
Another in-progress effort is the “OSCORE Profile of the Authentication and Authorization for Constrained Environments Framework” [12]. The principle is to generate a client’s token via an authorization server, bind the client’s cryptographic key and establish client access rights to resource server resources/data. The latter uses the token to authenticate the client, and finally, both the client and resource server use the OSCORE protocol to derive a new security context. Mutual authentication is only achieved at the end of the derivation context.
One of the main characteristics of an IoT device is its ability to communicate with its counterparts and servers to exchange data and for management purposes. Since communications can transport sensitive information or can be used to manage devices, security is paramount but must be addressed in a way that addresses device resource constraints (e.g., computing power, memory, energy). To this end, some dedicated communication protocols have been created, such as CoAP. For security, the well-known TLS and DTLS (for its datagram equivalent) are used. However, TLS/DTLS were not designed for IoT devices. OSCORE, is an interesting approach to provide a dedicated security protocol for constrained devices, using CoAP. This article provides an overview and comparison between TLS, DTLS, and OSCORE protocols (summarized in Table 3).
OSCORE is more performant than TLS/DTLS in terms of message size, computing, and memory overhead, leading to corresponding energy-efficiency gains. Additionally, OSCORE provides end-to-end security, optimizing proxy operations, incompatible with the hop-by-hop scheme of TLS/DTLS. In addition, thanks to its application-layer approach, OSCORE is compatible with any transport layer and transport layer security, including TLS/DTLS. The main drawback of OSCORE was its lack of handshake protocol, but the release of EDHOC RFC in March 2024 fills the gap and should increase the OSCORE spread out. EDHOC will be the subject of a future article.
Join us on GitHub and let's discuss: https://github.com/ioterop