In “5 Elements to a Secure Embedded System – Part 3 Secure Boot”, we continued our discussion about the five essential elements required to begin securing an embedded system. As you may recall, the five elements that every developer should be looking to implement are:
- Hardware based isolation
- A Root-of-Trust (RoT)
- A secure boot solution
- A secure bootloader
- Secure storage
The main focus last time was that the system needs to have secure boot which boots the system in stages and developers a Chain-of-Trust at each stage. In today’s post, we will continue the discussion with a look at secure bootloaders.
Element #4 – Secure Bootloaders
Bootloaders are a particularly interesting component in an embedded system, especially from my perspective. Bootloaders are often overlooked by development teams and developed at the last minute despite the fact that they are often complicated to implement and create critical functionality for the system. On several occasions, I’ve had companies approach me a week before they planned to launch a product and ask that I develop a secure bootloader for them! On one occasion it was even during the last week of the year right after Christmas!
So far in my career, I’ve written several dozen bootloaders for nearly every possible interface imaginable (spoiler alert, they nearly always take 6 – 8 weeks if done properly). Bootloaders are interesting because they fully test a developer’s skills in their ability to not just develop an application but to also understand all the nuances about the microcontroller that they are using.
What is a Secure Bootloader?
Secure bootloaders are different from just a standard run-of-the-mill bootloader in that the bootloader is often:
- Part of a chain-of-trust
- Authenticates new software images
- Verifies a software images integrity
- Requires access to cryptographic algorithms and accelerators
Non-secure bootloaders often just use a checksum to make sure the software image is whole but does little else before accepting and trying to run the image, which is extremely dangerous from a security perspective.
There are four main problems that a secure bootloader is trying to solve:
- Preventing firmware reverse engineering
- Preventing unauthorized firmware modification
- Loading unauthorized firmware
- Loading firmware on an unauthorized device
There are quite a few different ways that a secure bootloader may behave. Let’s take a quick, high-level look at how the entire process works.
The Bootloading Process
When a new firmware image is ready to be deployed, a company will generate a firmware signature that will accompany the firmware that will deployed in the field. A hash is generated for the new firmware which is then encrypted using the companies private key to generate a signature. The signature and the firmware (encrypted or not) is then sent to the embedded system through the bootloader. If you look at many of the secure bootloaders that are provided as examples by microcontroller vendors, you’ll often find that the secure bootloader will accept an encrypted firmware image, but an unencrypted image may also be sent depending on how the bootloader is configured. Even if a secure bootloader does accept an encrypted image, the image is often unencrypted in-flight before storing it locally somewhere in flash (which may be internal or external).
Once the bootloader has received the image, it will use the public key that is stored in the system to decrypt the signature to get the original hash for the firmware. The bootloader can then hash the received, unencrypted image and compare if the two are equal. If they are equal, then the bootloader has verified that the firmware image is authentic (from the signature) and its integrity is not compromised (from the hash). At this point, the bootloader can then go through the process of updating the firmware and booting the new software image.
Source: The Beningo / Cypress security training course: Getting Started with Secure Device Management using PSoC 64 and AWS
If a hacker decides that they want to try to place their own image on the device, they will need to have the companies private key in order to generate an appropriate certificate. If they somehow had access to the firmware and wanted to make changes, they would again need to be able to authenticate through a signature the new hash, which they would not be able to do. If they attempted to send new firmware to the device, the bootloader would be able to detect that it was not valid firmware and would then throw-a-way the image and continue to run the application code that it was already running.
What Does the Microcontroller Need to Support in Hardware?
Developing a secure bootloader can be challenging. Depending on the level of security and the features needed, not every microcontroller will be appropriate. Developers often need a microcontroller that supports:
- Hardware isolation
- A hardware cryptographic engine
- Memory protection units (MPU)
- True random number generators (TRNG)
- Flash bits to make the bootloader immutable
- A place to securely store keys
These are just a few features that the microcontroller needs to have for a secure bootloader solution. As you can imagine, success is in the details and requires both an expert understanding of the hardware and secure bootloader solutions. Therefore teams working on secure embedded products should start on their secure bootloader solution early and not wait until the last minute to try to implement it!
Secure bootloaders are much more involved than your traditional bootloader implementation. They mix the ability to update and run a new application image with the need to authenticate and verify a new image’s integrity. This requires that the bootloader implement cryptographic services. There are microcontroller-specific secure bootloader solutions that developers can leverage which decreases the security knowledge a team needs in order to implement a secure bootloader solution. If those solutions are not enough, it is critical that teams start their secure bootloader solution as soon as possible because it will take several months to build, test, and verify it successfully.
In the concluding part, we will discuss secure storage, what it is and what it means to developers.