IOT (Internet of Things) is quite a thing nowadays, from small home devices such as lamps or coffee machines to bigger home appliances like washing machines or refrigerators. All devices tend to be connected to internet, you can now control them when you are outside your home or get different notifications on your phone. In the healthcare sector we talk about IoMT (Internet of Medical Things), and it follows the same idea; medical devices that are connected to internet and allow to improve the quality of life of some patients. For an IoT device, one of the possible maintenances is to get new updates to add functionality, increase compatibility or fix any bug or problem.
In this context, cybersecurity has become extremely important, every single device that is connected to the network is susceptible to an attack which can cause a lot of damage if the device is connected directly to your body such as an insulin pen, a dialysis machine, or a pacemaker. Because of that, there are mechanisms that modern processors offer to ensure that the software the device is running on is well programmed, doesn’t contain errors and above all it’s the one that the company that manufactures the device wants. This is crucial because if the device has the possibility to get a software update, how can it know if the new update is the chosen one?
The bootloader is the responsible software for booting the device, once you power up the device, it is the first thing that runs into the processor. Commonly the CPU has its own bootloader that you are not able to modify, and at least you need to adapt it to your custom setup. After this first bootloader, the program jumps to your software, and you have total control of the processor. Because this first bootloader is not fully customizable, the most common approach is to have a second custom bootloader that allows to manage all the possible scenarios that may occur.
In this article we are going to focus on the custom Bootloader and how to check that the application that is going to be run is correct. Even in a final implementation it is important to understand how the Internal Bootloader works and how to configure it because some functions belong exclusively to it.
A signed firmware is a piece of software that has been signed by the vendor or developer of a device with a key to ensure that this software belongs to him and has not been modified or corrupted. This process of “signing” a firmware may differ depending on the architecture or processor, because each manufacturer provides a set of tools to do it, but the general process to follow remains the same:
- Generate the binary of your application: First, we will need the application. There are many ways of generating it, but at the end, the result will be a binary file that will be flashed into the device.
- Generate keys: This will be highly dependent on the architecture and tools provided by the vendor of the processor. Ideally it will exist as a tool that allows you to generate, on one side, a private key that you will need to sign the firmware and, on the other side, a public key you will need to store in the device.
- Sign the firmware: This will depend on the tools provided, but the result is that the combination of the private key, and the firmware binary will result in a signed firmware that will be another binary file that contain the firmware and additional information related to the signing process and the keys. This is the one that will flash into the device.
- Give the public key to the bootloader: The bootloader needs to know the key generated by the firmware, because at the end, the bootloader will be the one to check if the program runs or not. For that purpose, we will use the public key.
- Flash the signed firmware: The last step is to flash the device. We will put the bootloader into the memory and the signed firmware. The bootloader will check the signature and if everything is correct the program will run.
Following this process, we ensure that no one can run any unknown program in our device, at least without knowing the key. As we mentioned before, the bootloader is the first program to be to be executed when powering up. So, this piece of software will be the one to check that the key used to sign the firmware and the internal key matches. In other case, the bootloader will not allow the execution of the codes
Check the signature
So, our bootloader, using this additional data and his public key will calculate the hash and compare it with the hash that is in the signed firmware, if it matches, he can ensure that the firmware was signed with the same private key, even without having the private key itself.
As earlier mentioned, this is a simplification of the process and a fast way of explaining how to validate a signed firmware remarking the importance of protecting the private key. Of course the process is much more complex and will be hard depending on the platform and the tools used, because of that, in the following articles we will put this into practice in a concrete platform to demonstrate how to implement all the steps.