Remote firmware updates for embedded systems
Firmware updates are one of the most important factors to take into account very early in the process of starting the development of any IoT project. When the software is maintained by a development team, anything that goes wrong can be fixed on the field and new features can be deployed quickly, as long as remote updates are efficient, reliable and trusted.
Products can be pushed into production earlier, offering the possibility for a different strategy that involves remote updates when new features are ready, or when defects on the current version have been fixed. For this reason, it is in general a good idea to include a firmware update mechanism since the very early phases of your product or platform definition.
Microcontroller-based systems are quite challenging when it comes to firmware updates. On one hand, modern microcontrollers provide a wide range of features, a large choice of embedded operating systems, significantly reduced engineering costs for products based on a simpler design and the ability of running in ultra low-power environment, some even relying solely on energy-harvesting devices. On the other hand, embedded systems cannot relocate executable code at run-time. Even if a system is capable of multi-threading, threads are almost always defined at compile time, assigned a fixed stack space, and all the code is often linked together into a single executable firmware image.
Using a monolithic image makes impossible to update single components on the system without changing the layout of the code stored in flash. A bootloader can be helpful in this case.
A classic approach for updating the firmware of a running embedded system is by using a bootloader.
Chip manufacturers often provide very simple pre-installed bootloaders, that can be used to update the partition images on a running system. A very common strategy adopted by these bootloaders is to provide a “DFU mode” as an alternative boot stage to choose, where DFU is the acronym for “device firmware update”. This mechanism often allows to update all the software stored on the target flash, using local devices such as UARTs or the DFU-USB device class specification. Pre-installed bootloaders may result helpful during the development of a few prototypes to speed up the life-cycle, or when the number of targets and their geographical location allows for manually-activated updates.
Connected devices however have a different range of challenges to deal with. Updates must be fail-safe in order to prevent the node from being unreachable after a software failure. Security considerations arise whenever the firmware is transmitted using a public network, or over-the-air, about the authenticity and the integrity of firmware update images. How do IoT projects deal with this? Building your own bootloader may seem viable, but it may become as time and resource consuming as maintaining the firmware itself, and definitely does not help cutting down your time to market.
wolfBoot is an open source secure bootloader for all microcontrollers, designed to support remote firmware updates in embedded systems. It currently supports ARM Cortex-M and RISC-V architectures, and can be integrated in embedded systems using by partitioning of the non-volatile memory available on board.
Thanks to its in-place swapping mechanism, any memory support can be used by the application to store the firmware updates. The updates are then verified and authenticated by wolfBoot after the system reboots. A copy of the old firmware, overwritten only by a validated update, is temporarily stored into the update space to provide a fall-back mechanism in case of boot failures due to a defective firmware release. The image must in fact be confirmed after a valid update.
By using wolfCrypt’s DSA and ECDSA algorithms, wolfBoot includes a cryptography-grade signature verification mechanism that relies on public key authentication mechanisms. Each firmware release contains a fixed-size manifest header placed before the executable code. The header contains the signature of the hash for the release payload and the manifest itself. The bootloader code typically includes a fixed public key generated on the build system at compile time, or stored on a separate dedicated device such as a key vault or one-time-programmable memory.
wolfBoot is designed with safety-critical systems in mind. No dynamic memory allocations are used in the code, and all the memory needed for the boot stage is defined at compile time. Interrupts are turned off and code is running in a single thread. This makes the boot stage execution time deterministic, and provides reliable and consistent measurement of the boot time for real-time scenarios.
Available in all sizes
On resource-constrained device, wolfBoot can fit in about 10KB of storage space, and use about 2KB of RAM to stage the image. The code includes all the software to perform the signature verification and swapping release images in place. On those microcontrollers equipped with more resources however, performance can be tuned at compile time to speed up the authentication process at the expense of a slightly larger bootloader footprint. wolfBoot supports all the signature verification mechanisms provided by wolfCrypt, which come in different sizes and performance figures.
Hardware-assisted signature verification
Many MCU vendors on the market have one or more product families that include hardware accelerators for several cryptography operations. wolfCrypt already offer a wide range of device drivers for these vendor-specific accelerators. wolfBoot can take advantage of public-key hardware accelerators (PKHA or simply PKA, depending on the different manufacturers). There are several reasons why a project could choose to use wolfCrypt PKA modules in wolfBoot: optimizing power consumption at boot time, meet real-time deadlines on slow microcontrollers, enforce built-in hardware protection against side-channel attacks. Recently wolfBoot has added specific configuration supporting PKA technology on NXP Kinetis-K8x and STM32WB55.
Support for TPM 2.0 SPI/I2C devices
Thanks to the native integration with wolfTPM, wolfBoot can be used in combination with Trusted Platform Module (TPM) compatible secure cryptoprocessors. Integrity checks and signature verification operations can be offloaded completely to a dedicated external microcontroller.
Hardware-specific bootloader support
More and more platforms on the market provide vendor-specific bootloader integration APIs, to enable advanced boot features, such as swapping memory mapping of two physical partitions on the internal flash, or activating target-specific flags to integrate with bootloaders in a different stage. wolfBoot provides support for several of these features in modern microcontrollers, including hardware assisted partition swapping, firmware read-out protections, pre-configuration and staging of external memory mapped devices (e.g. QSPI).
wolfBoot is capable of updating itself, with the same mechanism used for firmware updates. Updates for the bootloader have a manifest header and are verified using the same public key. In order to update itself, the bootloader executes part of its code from a location in RAM while the storage supports are being overwritten.
Key handling under control
The entire authentication mechanism relies on one private key that is never distributed and has to remain secret. wolfBoot can be integrated in any trust chain by incorporating the private key in a certificate, but does not depend on a specific provisioning mechanism. The update authentication is flexible because it is based on open standards, and the signing step can be integrated in any existing or custom cloud-based key handling, or vendor-specific key provisioning system. By default, keys are created once, stored in the server responsible for signing the firmware, and used to create manifest headers of each and every release, but never shared with any third party.
wolfBoot integrates well with all microcontroller-based systems, and can be added to existing multi-stage boot strategies, at any stage, to include firmware verification capabilities and fail-safe update features. Due to its minimalist design, the hardware-specific code is limited to the drivers needed to access the storage space at runtime. Example configurations are available along with the source code to facilitate the integration into existing projects. wolfBoot is OS-agnostic, meaning that any embedded operating systems, or bare-metal loop based applications can be staged and distributed as release image payloads. The only modification required to integrate within an existing project is in general limited to re-defining the entry point of the main firmware to match the partitions on the FLASH memory.
Whether you are starting a new IoT product, or planning to secure the firmware updates in your existing fleet, you have the choice to integrate wolfBoot to cut down your time-to-market and rely on a secure, safe, thoroughly tested, existing solution.
wolfBoot can be shaped upon the features and resources available from your hardware design, and easily integrates with your centralized infrastructure to deliver remote updates, without any burden to your development team that can instead focus on delivering the actual system functionalities.
wolfBoot is developed using github (https://github.com/wolfSSL/wolfBoot) and is distributed under the terms of the GNU General Public License (GPL). Alternative proprietary licenses, technical support (up to 24/7 worldwide) and customization services are available via wolfSSL Inc.
Home page: https://www.wolfssl.com/wolfboot
Contact: facts at wolfssl dot com