> Side Channel Analysis
Ready-to-use side channel tools to assess cryptography algorithms.
> Fault Injection: Laser, EM & Glitching
Make sure your chip withstands different techniques of physical fault injections.
> Firmware Security Analysis
Qualify embedded code binaries without physical devices and benches.
> Security Failure Analysis
Photoemission analysis to explore internal information in a chip.
> Vulnerability Research
Dynamic analyses at a system level for investigating potential vulnerabilities.
> esDynamic for EDU SCA and FI
A learning center for academics to teach and perform side-channel analysis and fault injection
> Data Science Platform
esDynamic is a complete data focused platform to leverage the know-how of your team for complex analyses.
> esFirmware Engine
Assess the security of the firmware of IoT devices against logical and physical attacks.
> esReven Engine
Record and replay vulnerability researches within reverse engineering processes and tools.
> Cybersecurity Training
Grow your expertise with training modules driven by a coach.
> Hardware Evaluation Lab
High-end laboratory capabilities specialized in hardware security evaluations.
> Mobile App Security
Know the threats and risks of your Mobile App.
> DevSecOps
Integrate the security protections verification in your CI/CD pipeline.
> PCI MPoC
Prepare your product to meet this new mobile payment standard.
> Mobile App Security Testing (MAST)
esChecker SaaS: automating the security testing of your mobile app binary.
> Mobile App Penetration Testing
Testing the resiliency of your Mobile App, SDK or RASP tool.
> Backend Penetration Testing
Testing the resiliency of your Web App, API or Backend Systems.
> Coaching for Mobile App Developers
Providing insights into the mobile app threats and how attackers work by a learning-by-doing approach.
Go to our German website
> Events
> Meet our experts
> Open positions
Join our team!
Youtube
Github
Gitlab
We start, with this post, a series about security aspects of the bootloader MCUBoot, in particular focused on the use of code emulation in the context of fault injection. In this post we bring, to those not familiar with MCUBoot, the elements to understand the purpose of this software, how it works. Focusing on the application code authentication at the startup, we will initiate the background for the security assessment using emulation developed in the second post of this series. We will close this post with some attack scenarios and the different approaches to break the code authentication.
MCUBoot is an open source project with the intent to define a so-called "secure bootloader" for 32 bits microcontrollers. As a bootloader, it is the first software executed by the device that offers security services. Among them it provides standardized secure methods and data infrastructure to load, upgrade software or simply start an authenticated software. It is operated by major names of the embedded system industry as ARM, ST, Infineon or Nordic Semiconductor. MCUBoot is integrated in the ARM Trusted Firmware-M which is the reference implementation of the Platform Security Architecture (PSA) IoT Security Framework.
Secure loading, starting or updating of the application code are the main security objectives of MCUBoot. From this claim, several assets are identified:
The potential threats targeting MCUBoot are:
To protect its assets against these threats, MCUBoot implements these security functions:
Application code is organized in a structure called image. This image is organized in items as depicted on Figure 1. Hereafter, we will restrict our image description to elements that take part of the authentication mechanism:
Figure 1 - Application code image
Let us follow the MCUBoot code to understand how the authentication of the application
code is driven. For this purpose, we use the version tagged v1.9.0. Each step will be explained
and linked to the corresponding source code with the canonical format filename:line_start-line_end
.
We can find the main function in the bl2_main.c file. As we can expect, the code crosses several functions before reaching the function of interest bootutil_img_validate where the image format is checked. The call stack is the following:
The bootutil_img_validate function loops on each item of the image and applies a validation process. At first, the header and the code are retrieved, and the bootutil_img_hash (image_validate.c:366-374) computes the SHA-256 hash of these two sections.
Then, it retrieves the corresponding hash section having the expected tag and the expected length (image_validate.c:393-405) and it checks that the computed hash value is consistent with the value loaded from the hash section (image_validate.c:407-410).
Next, MCUBoot reads the Public Key from the corresponding image section (image_validate.c:433-444), it computes its SHA-256 hash, and it compares the obtained value with the one embedded in its own data section with bootutil_find_key function (image_validate.c:445-445).
Ultimately, MCUBoot reads the signature section, and verifies it using the hash computed formerly on the header and the code (image_validate.c:465-466). If a RSA PSS PCKS#v2.1 signature is used, mbedtls_rsa_public performs the decryption with the public (image_rsa.c:187-187). Then, bootutil_cmp_rsasig checks the decrypted signature values (image_rsa.c:316-316).
Once the verification process is over, the function boot_go_for_image_id ends and returns a value reflecting the result of the image authentication. Back to the main function this final result is analyzed. In case of a failure, the execution will be stopped (bl2_main.c:154-158).
We have seen above the main mechanisms used by MCUBoot to ensure "secure" boot with legitimate application code. To summarize, the application code is instantiated through an image with a structure used by MCUBoot to verify integrity of both the code and some metadata, like the code version, the code length, and guarantee authenticity via a public key cryptographic signature.
Wouldn’t be cool if I could execute arbitrary code. Let me suppose that:
Obviously, I do not have the secret key necessary to sign the code and make a legitimate image, but I will use my favorite fault injection bench to induce fault during MCUBoot execution and try to get my code accepted.
Two attack scenarios come immediately to my mind:
In the first scenario, I expect MCUBoot to detect that the public key is not the genuine one at the public key verification step. According to the above code description, the find_key function should fail... bad luck 😕. Happily, for us, MCUBoot uses the provided Public Key inside the image. Therefore, tampering with the find_key function would result in acceptance of my code.
In the second scenario, my hack attempt should be detected by the signature verification because the hash is not the one used for the signature 🤔. In this case, the function bootutil_cmp_rsasig will return a failure status, and I can try to fault this status to force acceptance of my code... The way to exploit this vulnerability is not straightforward without going into the code details, let us put this aside we will come back on it in the next posts.
As I told you, I am familiar with fault injection, indeed at eShard we practice this hardware attack technique with different means: LASER, Glitch or Electro-Magnetic. With these fault injection benches, we induce perturbation during code execution of a targeted device to turn this into something exploitable, sometimes a cryptographic secret key, but also sometimes to turn a test result...
But let me tell you some advantages, and drawbacks of this approach:
Advantages
Drawbacks
The lack of equipment, knowledge or time make this approach too heavy for a lot of people. To tackle all these issues, with the growing computation power available on our desk today, a new approach emerged: leverage the software emulation of the target to make simulated hardware attacks.
Simulation-based software is another approach to assess a target against fault injection attacks. A part, or the whole of the target code can be emulated, and a disturbance injected during its execution. The emulation can take the binary code as an input. Different elements of the chip can be emulated, and therefore faulted: instruction, registers, memory. In another way, the emulation can be performed at a lower level with a hardware description language (HDL), such as Verilog and VHDL. From the hardware description, we should access a finer emulation of the target behavior, even though it is more complex to deploy. But, most of the chip HDL is not publicly available.
Seems to be promising, no? Let me draw the list of the advantages and the drawbacks of this approach:
Advantages
Drawbacks
In the next post, we will show how to emulate MCUBoot with esFirmware, and which strategies can be used to attack it with simulated faults.
Thanks to Pylou for proofreading this article.