MCUboot Security Part 1

By | Blog

Zephyr Project member David Brown, a Senior Engineer with Linaro Ltd.,  shares the best practices for security in this blog post, which first ran on Brownian Motion

This is the first in what I hope to be a series of posts about the MCUboot bootloader from a security perspective. Please note that although I work in security, I am by no means a cryptographer. I appreciate any feedback on any and all flaws in my analysis.

The MCUboot project

The MCUboot Project is a secure bootloader for 32-bit MCUs. The goal of MCUboot is to define a common infrastructure for the bootloader, system flash layout on microcontroller systems, and to provide a secure bootloader that enables easy software upgrade.

The essential problem that MCUboot seeks to solve is how to allow firmware updates, while still maintaining some kind of integrity and control over what firmware can be run on the device. The easiest way to prevent unauthorized firmware from running on a device is to configure the flash to be immutable. Unfortunately, this prevents potential security updates (as well as functionality improvements). MCUboot solves this by itself being a small amount of code that can be placed in an immutable section of flash. It then can verify the main code before allowing it to execute, as well as control updates to that code.

MCUboot is configurable, and these configuration choices affect the security promises that MCUboot is able to make.

  • CONFIG_BOOT_SIGNATURE_TYPE_RSA and CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256control the type of digital signature MCUboot uses to verify the image. It is possible to define neither of these, and it will only ensure that there is a SHA256 hash present. With neither signature algorithm, the image is not protected against intentional tampering, but merely acts as a checksum, to prevent a corrupted image from booting.
  • CONFIG_BOOT_VALIDATE_SLOT0 controls whether MCUboot validates the signature of the booted image on every boot (or just when upgrading). This can be disabled to make the boot process slightly faster, at the cost of no longer verifying a path of trust to the running image.
  • CONFIG_BOOT_UPGRADE_ONLY controls how upgrades are performed. If this is unset, MCUboot uses a (complex) swapping algorithm to exchange the new upgrade image with the old image. This will allow an easy revert if the system determines that the image will not boot. If this is enabled, the new image will overwrite the old image, and if it doesn’t boot, there is no fallback image.

From a security perspective, I will assume that one of the signature options is set, and that SLOT0 is validated. In a future post, I will discuss the upgrade only option, and demonstrate why neither of these is a good solution, from a security perspective. It will offer a suggestion for how to better handle reverts.

System Model

MCUboot assumes that it is running on a small 32-bit microcontroller where the code executes directly out of flash (eXecute In Place, or XIP). Although support for non-XIP targets is desirable, it has not been implemented at the time of writing.

MCUboot divides flash into several regions. We will refer to them as B for the bootloader area, P for the primary region, U for the upgrade region, and S for the scratch region. There are constraints on the layout and sizes of these partitions which are not relevant to our analysis here. We make the following assumptions of this flash memory:

  • The flash memory is internal to the MCU itself. External flash memory is easier for a malicious party to modify.
  • The B region can be permanently marked as immutable. Some MCUs will still allow a full-chip erase, which would allow a determined party to replace the entire firmware with their own.
  • The code at B is the first configurable code that the MCU will run. The MCU may have internal boot code, however if it can be configured to support some type of recovery process, this must be permanently disabled (to prevent arbitrary code from running).
  • JTAG and SWD debugging ports will be disabled in production devices. Limited debugging can be permitted as long as the B region cannot be tampered with.

Image format

MCUboot (the code in B) verifies the image in P before running it. This image begins with a small header Hd, the executable image itself, Ex, and a set of metadata after the image, M1M2, etc. The format of the payload then looks like (Hd||Ex||M1||M2||…).

Each piece of metadata is in tag-length-value format, with the following tags:

  • IMAGE_TLV_SHA256: The associated data is the SHA256 hash of (Hd||Ex). This tag is required in all configurations.
  • IMAGE_TLV_KEYHASH: The associated data is the SHA256 hash of a public key. This is used to indicate what public key a following signature uses.
  • IMAGE_TLV_RSA2048_PSS: A digital signature made with RSA-2048 PKCS v2.1 PSS. The signature is made with the same hash as IMAGE_TLV_SHA256.
  • IMAGE_TLV_ECDSA224: A digital signature of the hash made with ECDSA using the NIST P-224 curve.
  • IMAGE_TLV_ECDSA256: A digital signature of the hash made with ECDSA using the NIST P-256 curve.

If MCUBOOT has been configured to support one of the signature types, then at the following tags must be present: IMAGE_TLV_SHA256IMAGE_TLV_KEYHASH, and one signature that matches the signature type compiled into the code. There can be more than one pair of keyhash and signature pairs present, and the bootloader will ignore any that it doesn’t understand.

MCUboot will reject the image if the metadata does not meet these requirements.

Boot process

Upon booting, MCUboot examines PU, and S to determine its internal state. If it detects it was in the middle of an operation, it will try to continue that operation. If U is valid, and is marked to indicate an upgrade, it will begin the upgrade process. This will either copy U onto P entirely, or use a swap algorithm using S to exchange the contents of P and U (depending on configuration).

If P contains a valid image, MCUboot will transfer control to the execution address of this image (indicated in a CPU specific manner; for Arm, the address and initial stack pointer are at the beginning of Ex).

If none of this is true, MCUboot will stop to prevent malicious code from running.

Stay tuned for more:

  • Security implications of not verifying SLOT0.
  • Security implications of not using a digital signature.
  • Deeper dive into “swap”, its complexities, and some discussion of an easier idea.

For more blogs from David, visit his personal webpage here.

ZephyrOS SDK version 0.9.5 is now available!

By | Blog

As announced a few weeks ago in the technical meetings and communication, the Zephyr Community has been working on a new version of the SDK with updates mostly to the host tools. Today, we are pleased to announce the release of version 0.9.5 of the ZephyrOS SDK. Thank you to all the community members and companies who worked to make this release a success.

This release has the following changes as compared with version 0.9.3.

  •       New QEMU release (based on 3.0.0+git 19b599f7664b2ebfd0f405fb79c14dd241557452)
  •       Qemu installation now has all needed ROMs and BIOS files to support connecting Ethernet drivers such as the Intel e1000.
  •       New OpenOCD based master with Zephyr related changes (commit: 05e0d633)
  •       New DTC version 1.4.7+git (commit 2e930b7f8f6421638869a04b00297034c42e1a82)
  •       Upgrade arc binutils to 2018.03-rc2

The above changes, and especially the Qemu related items, requires developers to  move to the new SDK as soon as possible. Earlier versions of the SDK will not work with the master tree.

The new SDK required some changes to ZephyrOS. They include:

  •       RISCV32 Qemu is now uses a different machine type. Qemu-riscv32 is now an alias to the hifive1 board which can be run in Qemu as well.
  •       NIOS2 Qemu is now using a different UART driver
  •       ARM Qemu is now supported by two machine types:

mps2_an385: This one will be the default target for sanitycheck and will be used for testing kernel features. This machine type does have MPU support and will enable userspace testing on ARM

lm3s6965evb: This is the machine type we have now, we will keep it for compatibility and testing some networking and Bluetooth related features. It might be obsoleted in favor of the above in the future.

Also of note: CI will be updated with the new SDK and sanitycheck will require the new SDK to pass, meaning that if you run sanitycheck locally you will need this SDK. We now made this version required for building Zephyr.

The SDK can be downloaded from here:

Direct link to the SDK binary:

Note: All of the changes above can be found in the following PR:

If you would like additional information or to see changes made in version 0.9.4 please visit:

If you have any questions or have any issues with the new SDK, please let us know or file a bug. Expands Commitment to Open Source and the Zephyr Project

By | Blog

By Tyler Baker, CTO for, an Internet of Things platform developer, has actively contributed to several open source projects since its inception in 2017, when it was spun out from Linaro. We strongly believe that open source software is the best choice for platforms others build upon. This is especially so in IoT applications, where products and devices tend to be heavily customized and optimized. We also believe open governance and community involvement are essential for healthy and diverse projects.

To that end, we have been using and contributing to The Linux Foundation’s Zephyr Project for many years, and have held the Community Member seat on its Technical Steering Committee since its creation. It’s only natural that we expand this commitment. is now a silver member for The Linux Foundation as well as a the Zephyr Project.

In August 2018, launched microPlatforms for an Always-Secure Internet of Things. The Zephyr and Linux microPlatforms™ are end to end tested, secure, updatable and configurable platforms based on Zephyr and OpenEmbedded/Yocto Linux and containers, for building IoT devices from smart sensors to autonomous vehicles. Not only do the microPlatforms use key Linux Foundation projects such as Zephyr and Yocto, but they also provide a universal device platform to support other key IoT-related projects such as EdgeX Foundry and the Akraino Edge Stack. We recently demoed the microPlatforms at Linaro Connect Vancouver 2018, to view the demo, click here (fast forward to 01.00.00 on the video).

As proponents of open collaboration, we are excited by its future as the “Linux kernel for microcontrollers” – a common, cross-architecture, batteries-included ecosystem with active backing from silicon vendors, software development companies, and open source community members. Zephyr is an essential part of our product offerings, and we’re looking forward to continuing our collaboration with the community in our new role as a Silver Member.

We look forward to partnering with other Linux Foundation members, and to participating in and contributing to the range of hosted projects. To find out more about, go to our website to read monthly updates and much more.


Join us at ELC Europe!

By | Blog

Next week, the Zephyr Community will be converging on Embedded Linux Conference Europe and OpenIoT Summit Europe 2018.  Attendees have the option to participate in a number of collaborative events in addition to a packed schedule of technical presentations.

To make sure you don’t miss any of the Zephyr related events, we’ve documented them all here for your easy reference. We also want to encourage you to download the conference app or view the full schedule here.

Monday, October 22:

Tuesday, October 23:

Wednesday, October 24:

Stay tuned on Zephyr’s social channels for live updates from the conference.