@ -5,14 +5,14 @@ Requirements were clearly defined by Magrathea Laboratories' demands to provide
Such components include door sensors, power sockets, temperature sensors, projectors and screens who are all managed by a home-automation controller, which is driven by the software \textit{home-assistant}\cite{HASS}.
It provides direct control over all existing components using a web-based user interface and allows to define rules and automations on how these components interact.
For the component's hardware, boards based on the \textit{ESP8266} micro-controller are used.
For the component's hardware, boards based on the \textit{ESP8266}\cite{ESP8266}micro-controller are used.
These boards feature a small and robust design, achieve very low power consumption and integrate WiFi without requiring any extra components.
It integrates a Tensilica L106 32-bit micro controller unit (MCU) with a maximum CPU performance of 160 MHz, 64 kB instruction memory and another 96 kB of main memory.
According to the manufacturer, the ESP8266 is among the most integrated WiFi-capable chips in the industry.
While at the beginning of this research, mostly \textit{ESP-01s}\cite{ESP-01s} boards in combination with self-developed power supplies and use-case specific hardware components were deployed, \textit{Sonoff}\cite{sonoff} wireless smart switches product series offered by \textit{ITEAD} have been integrated quickly.
The firmware for all of the \textit{ESP8266}-based devices in the hackerspace has been implemented using a common software platform, referred to as \textit{ESPer}.
\textit{Sming}, which in turn is based on the open-source software development kit (SDK) for \textit{ESP8266}, provides the base library for this framework.
\textit{Sming}\cite{Sming}, which in turn is based on the open-source software development kit (SDK) for \textit{ESP8266}, provides the base library for this framework.
It integrates a lot of other software components and provides all kinds of functionality shared by all devices, allowing to reuse parts of the source code in multiple devices.
For communication with the controller, the \textit{Message Queue Telemetry Transport (MQTT)}\cite{MQTT} protocol is used.
\section{Concept for implementing \textit{OTA} updates}\label{concept}
To implement \textit{OTA} updates under the given requirements, we first define a topology that integrates our build infrastructure, firmware repository, and controller with the IoT WiFi network, which the devices are connected to.
For our reference implementation, we particularly chose lightweight and common software projects to allow for easy exchangeability of the individual components.
The base topology, as well as the specific components used is shown in Figure \ref{fig:topology}.
The base topology, as well as the specific components used is shown in Figure \ref{fig:topology}.
The source code of the \textit{ESPer} project is published into a \textit{Git}\cite{git} source code repository.
From there, the continuous integration (CI) system is responsible for automatically building and publishing the firmware image files, as soon as updated source code is available.
@ -16,6 +10,13 @@ The CI systems is described in detail in the following section.
Updates to the devices firmware are either triggered actively (i.e., manual or by the CI) or on a regular schedule by the devices themselves.
This process is described in Section \ref{flashlayout}.
For monitoring and maintenance purposes, each device publishes a set of information to a well-known \textit{MQTT} topic after connecting to the network.
Beside data like device type, chip and flash ID, the published data includes details about the bootloader, SDK and firmware version as well as relevant details from the bootloader configuration, like the currently booted ROM slot and the default ROM slot to boot from.
This allows administrators to find devices with outdated bootloaders and helps to find missing or failed updates.
@ -62,11 +63,9 @@ This standby ROM slot also acts as a safety mechanism if the download fails or i
\subsection{Cryptographically securing the firmware update}
To ensure only valid firmware is running on the devices, a cryptographic signature of the firmware images is calculated and checked as part of the update process.
For calculating and verifying the signatures of a firmware image, the \textit{SHA-256} hashing algorithm \cite{RFC6234} and an elliptic curve cipher based on \textit{Curve25519}\cite{bernstein2006curve25519} are used, which are both considered modern and secure methods for software signing (see \cite{barker2016nist, bsi}).
The cryptographic signature for each of the two firmware images is created by the continuous integration system during build time and is provided as meta-information along with the firmware images.
Therefore, the CI system must be equipped with the private key used to create the signatures.
In contrast, to be able to verify the cryptographic signature the micro controller only needs to know the according public key.
For the same reason as stated in Section \ref{flashlayout}, the signature of the new firmware image can not be verified before it is written to flash.
Therefore, the calculation of the \textit{SHA-256} checksum required for the signature check is done while the update is downloaded and written to flash.
After the download has succeeded, the checksum is verified against the signature and the bootloader gets reconfigured iff the signature is validated successfully.
@ -8,6 +8,9 @@ To keep secrets like the WiFi password and the private key unexposed, it is not
Instead, to include secrets into a build process while allowing to keep the configuration public, \textit{drone} allows to encrypt these with a repository specific key.
Using this method, the secrets are stored as \texttt{.drone.sec} file inside the repository from where they are injected into the build environment.
Also noticeable in Figure~\ref{lst:drone} is the firmware version, which is configured to be the first 8 letters of the \textit{Git} commit hash uniquely identifying a version of the source code.
For deployment, only the master branch is considered.
After a successful build, all distribution files (the firmware image and meta-information files) of all device types are copied to the repository server, from where they are served by a \textit{HTTP 1.1}\cite{HTTP_1.1} server.
The configuration file (\texttt{Configurion.mk.maglab}) references exactly this repository server as the source for updates.
\caption{The \textit{drone} configuration for the \textit{ESPer} project.}
\label{lst:drone}
\end{figure}
For deployment, only the master branch is considered.
After a successful build, all distribution files (the firmware image and meta-information files) of all device types are copied to the repository server, from where they are served by a \textit{HTTP 1.1}\cite{HTTP_1.1} server.
The configuration file (\texttt{Configurion.mk.maglab}) references exactly this repository server as the source for updates.
Support for multiple devices of different type is implemented in both, the \textit{ESPer} framework itself and the build system.
The framework keeps control over the application life-cycle.
It ensures that device unspecific code is executed at the right time and provides an API for device specific functionality.
@ -48,18 +39,13 @@ Figure~\ref{lst:create_device_socket} shows the complete device specific code us
\caption{Device specific code for a socket driver.}
\label{lst:create_device_socket}
@ -85,19 +71,15 @@ While the firmware is executed without any dynamic linking mechanism and the chi
This arises the need for building two firmware images, one for each target location.
To do so, a linker script for each of the two ROM slots was created, which is used to create two variations of the same firmware, only differing in ROM placement.
The two resulting firmware image files are both provided for download via \textit{HTTP 1.1} - which one to download depends on the target ROM slot and is selected by the device during the update process.
Figure~\ref{lst:linker_script} shows the only difference between the two linker scripts, where \texttt{\$\{SLOT\}}must be replaced with the slot number according to the current build.
Figure~\ref{lst:linker_script} shows the only difference between the two linker scripts, where \texttt{\$\{SLOT\}}is replaced with the slot number according to the current build.
@ -9,8 +9,7 @@ It consists of the version identifier and the cryptographic signatures of both o
The version identifier can be an arbitrary string as the content is not interpreted semantically but only compared to the version identifier used during build time.
The other two lines in the meta-information file provide the hexadecimal representation of the cryptographic signatures, one line for each firmware binary file.
These meta-information files are provided by the update server using \textit{HTTP 1.1}\cite{HTTP_1.1} under the following path pattern: \texttt{\$\{DEVICE\}.version} (whereas \texttt{\$\{DEVICE\}} gets replaced by the device type name).
Each device queries the update server regularly (initially when the boot process is finished and periodically once an hour) for the currently available firmware version.
Each device queries the update server regularly for the currently available firmware version.
It uses the \texttt{UPDATER\_URL} option to identify the update server.
After the meta-information file has been downloaded successfully, the version identifier is extracted and compared to the version identifier of the running firmware.
If the version identifiers differ, the update process is initialized.
@ -23,6 +22,8 @@ This allows faster roll-outs of updates and finer control for manual maintenance
The firmware files provided on the update server are the exact same ones as used to initially flash the chip for the according version.
Using the same files for flashing and updating allows better debugging by eliminating errors related to the update process itself and eases development and initial installation.
Figure~\ref{lst:choosing_rom} shows the algorithm used to determine the download address and reconfigure the bootloader.
The update server provides these files in the exact same way as it provides the meta-information files, but the path pattern differs: the suffixes \texttt{.rom\{0,1\}} are used to provide the firmware image files for the first and second slot respectively.
For installing a firmware update, the new firmware image file is downloaded using an \textit{HTTP 1.1}\texttt{GET} request.
@ -30,8 +31,6 @@ Figure~\ref{lst:choosing_rom} shows the algorithm used to determine the download
// Select rom slot to flash
const auto& bootconf = rboot_get_config();
// Add items to flash
if (bootconf.current_rom == 0) {
updater.addItem(bootconf.roms[1], URL_ROM("1"));
updater.switchToRom(1);
@ -44,13 +43,9 @@ if (bootconf.current_rom == 0) {
\label{lst:choosing_rom}
\end{figure}
The update server provides these files in the exact same way as it provides the meta-information files, but the path pattern differs: the suffixes \texttt{.rom\{0,1\}} are used to provide the firmware image files for the first and second slot respectively.
For installing a firmware update, the new firmware image file is downloaded using an \textit{HTTP 1.1}\texttt{GET} request.
\subsubsection{Verifying the cryptographic signature}
While the image is being downloaded, each chunk received in the download stream is used to update the \textit{SHA256} hash before it is written to the flash.
When the write has been finished, the next chunk is received and the process continues until all chunks have been processed.
After downloading the new firmware image has been finished successfully, the calculated hash is checked against the signature of the according firmware image.
Therefore, the cryptographically signed hash, which was provided in the meta-information file triggering the update, is verified against the \textit{Curve25519} public key stored as a constant in the running firmware.
Only if the checksum matches the provided signature, the firmware is considered valid and the process is continued.
@ -59,5 +54,4 @@ Only if the checksum matches the provided signature, the firmware is considered
For the bootloader, \textit{rBoot}\cite{rBoot} has been choosen as it is integrated within the \textit{Sming} framework and allows to boot to multiple ROM slots.
For configuration, an \textit{rBoot} specific structure is placed in the flash at a well-known location directly after the space reserved for the bootloader code.
This structure contains, among other things, the target offsets for all known ROM slots and the number of the ROM slot to boot on next startup.
To switch to the updated ROM slot after successful installation, the number ROM slot to boot on startup is changed in the configuration section and the device is restarted.