Build secure IoT applications with open source
Locked Down
The Internet of Things (IoT) is a game-changer for healthcare, connected homes and cities, ground transportation, and many other domains. From a technical point of view, IoT is very challenging, given such elements as hardware design and certification, embedded software on resource-limited targets, Internet-scale management servers, and ground-breaking user interfaces. In this article, I will look at one of the most challenging and sensitive areas: IoT security. I will explore different topics – from hardware to cloud servers – and discuss applicable open source projects.
Hardware security is very difficult to master. Why? Because when you deal with hardware security, you need to deal with physics. The real world has much more stringent rules than the digital world.
A common reaction is: Why should I care? Physically accessing one device should not compromise the whole system, right? True. But, it is a big deal. In a nutshell, anyone can buy or physically access the device and inject a firmware back door and resell the product. A back door in a IoT device makes a nice gateway for sending spam or spying on houses. Hopefully, hardware security features like secure boot, secure debug, secure flash storage are more common.
To leverage secure boot, for example, you can use the U-Boot [1] "verified boot" feature. It will verify a booted Linux kernel or the boot image if you are not using Linux. Your kernel will need to be signed and hashed with a RSA public/private key. The device should securely store the public RSA key used for the signature. Those different features can be chained; your device can contain a Trusted Platform Module (TPM) in charge of verifying the U-Boot binary before booting it. Then, U-Boot will be in charge of verifying the booted Linux OS, and the Linux OS will be in charge of verifying the installed application packages.
If your hardware is booting only trusted firmware to keep your end users safe, you will probably block firmware customization projects like OpenWrt for your device. It's a difficult problem to solve. Everything in hardware is a matter of compromise: Do I need to enforce the firmware booted? Can I leave some customization possibilities? Anyway, you now have some options for choosing how secure your boot sequence can be.
Secure Communications
If you are building an IoT product, you want to give it some Internet communication capabilities. Because of the specific nature of such products, you want to use compact communication protocols – embedded and wireless-friendly. You now have really efficient standard protocols for IoT, such as MQTT [2] or CoAP [3]. They are simple and compact enough to be implemented on 8-bit processors that have only a few kilobytes of RAM and flash memory.
Additionally, IoT applications tend to manipulate sensitive personal data, so you will want to authenticate and encrypt those communications. For that, you don't have a lot of options. The most popular approach is to use TLS and DTLS (TLS for UDP datagrams). Actually, most 8-bit processors are not really able to run a modern TLS implementation, nor are some 32-bit processors when they have limited flash or RAM available. However, compact and embedded-friendly open source implementations exist:
- Mbed TLS [4]: The new name of PolarSSL after the acquisition by ARM. It's an embedded-friendly TLS (DTLS since version 2.0) library. Implemented in C and easy to port to new targets.
- TinyDTLS [5]: A very compact implementation of DTLS (TLS is not supported), which is very easy to run on Linux or Contiki and is well tested on constrained wireless networks like 6LoWPAN. TinyDTLS is very compact in memory usage and also supports new cipher suites for resource-limited network nodes based on AES-128-CCM-8, soon to be an Eclipse IoT project [6].
- OpenSSL, LibreSSL, GnuTLS: If your device is not so constrained (e.g., a Raspberry Pi), you can use good, well-known security libraries like OpenSSL, LibreSSL, and GnuTLS. They just suck more flash and are difficult to run on non-Linux hardware.
If you are using MQTT, the lightweight messaging protocol for IoT applications, you can take a look at the Eclipse IoT Paho project [7]. It shows examples on how to use MQTT with security on several hardware platforms.
Now that I've discussed how to run a secured communication stack, I'll look at the possible authentication schemes. If you consider TLS, there are basically three possible security schemes:
- Pre-Shared-Key (PSK): The two peers share a common secret, which has been provisioned securely – thus, most likely offline. Security is accomplished using symmetric ciphers like AES and SHA-1 [8], with the same secret used for both encrypting or decrypting the communications. The general idea is that you will store a secret key in your device and store the same secret on the server. Usually, the key will be stored in a "write-only" secured chip that won't allow the key be read afterwards. An implementation of TLS based on a pre-shared key is not difficult to fit in an ARM Cortex M3 or M4 microcontroller, especially because those architectures already have hardware support for AES. You can find RAM/flash estimates for TinyDTLS online [9].
- Raw Public Key (RPK): The next level of security is to use asymmetric cryptography (public/private key). It's a better scheme because you don't have to move sensitive secrets like PSK around; you just need to exchange public keys.
- Certificates (X.509): Another level exists, with, of course, more complexity: public key certificates. This is added on top of asymmetric cryptography. The idea is to chain cryptographic signatures of different third parties for authenticating an identity. The price in code size is higher, but you can delegate the certificate provisioning to trusted third parties. You need to parse the whole certificate, check the signature chain, and check for possible revocation, which is not a simple matter [10].
Device Management
Securing the communication is not enough; you need to some device management facilities, too. The idea is to manage, operate, monitor, and update your devices directly on the Internet (also called over the air, or OTA). For executing device management operations in a consistent way across different hardware platforms, some standards exist, such as OMA-DM or TRS-69. My favorite one is OMA Lightweight M2M [11]. It standardizes the way you communicate with your device for performing common operations such as monitoring, upgrading, and configuring, as well as how you can extend it for your own application needs.
Two Eclipse IoT open source projects can help you to build your device management stack. The first one, Wakaama [12] is a C embedded-friendly implementation of OMA Lightweight M2M. It's very easy to port and is known to run on Spark, Arduino, and mbed.org targets. It can be secured using any DTLS implementation, such as TinyDTLS, mbed TLS, and others.
For the server counterpart, you have project Leshan [13]. It's a Java client/server implementation, and it can be used for building IoT device management servers for monitoring very large device fleets. For example, it can upgrade the firmware of your device each time an outdated device connects to the Internet (Figure 1). Today, Leshan supports pre-shared key, raw public key, and certificate security schemes on top of DTLS.
Additionally, OMA Lightweight M2M contains a bootstrap mechanism for privacy. Thus, Leshan can be used for distributing and rotating your device secrets (private keys, passwords, or certificates). You need to think about how you are going to change the keys, because inevitably one day your secrets will be outdated or the crypto you use will be proven flawed. Just like backup restorations, device credential rotations must be tested on a regular basis.
Updates
The best way to be sure you can change the credentials is to do it for every device, at least once. A good practice, for example, is to replace the factory-provided credentials on your device right after the first connection. With an OMA Lightweight M2M device management stack, you will be able to configure and update your fleet safely in the future!
In a nutshell, you can't secure what you can't update! If you only have time for one security feature, it must be this one. This is the key for pushing new security features or simply for patching holes in the future. But it must be bulletproof: Power supply, batteries, networks, and NAND flash are not reliable; you need to mitigate all those risks in your design. Consider, for example, that a 0.1 percent failure rate on a fleet of 1 million means 1,000 devices to fix.
Updates are data intensive. Even a small radio firmware for a 3G or 4G cellular modem can be 10 to 20MB, and embedded Linux root filesystems are becoming larger and larger. Thus, patch or delta updates make a lot of sense; a smaller download is a faster and more robust download.
For Linux-based systems, U-Boot can simplify your life. Download the update image for userland into some reserved flash space and do an ext reboot with a good custom script, U-Boot will safely flash your device. Also your software updates can be based on opkg or a similar embedded package manager; it will handle the verification of the packet signature based on GPG.
If you are targeting a device that is not able to use Linux, you can leverage other nice open source embedded operating systems for IoT. For example, Contiki [14] was built for IoT and low-power microcontrollers and includes firmware upgrade features. Riot [15] also targets IoT but focuses on providing a higher level of POSIX compliance by providing nice features like POSIX threads. The project is working to provide remote firmware updates.
Buy this article as PDF
(incl. VAT)