What is Immutable Boot Code?
As the word says, immutable is something that does not change over time.
Simply put, boot code is the first piece of software that gets executed after the processor is powered on. For instance: in ARM Cortex-M architectures, upon power up the CPU looks at the Reset Vector (second word in in the Interrupt Vector Table). It goes to the address stored in this word and looks for a valid instruction there.
So an immutable boot code essentially means that the boot code of your system should be immutable – it should never change and exhibit predictable behavior. It goes without saying that there should be no need to upgrade this piece of software. Of course, this makes the system rigid and if there are any vulnerabilities discovered in this piece of software, the same cannot be mitigated by changing the code itself. Hence, an implicit feature of immutable boot codes is that they are minimal and their primary goal is often to authenticate the next boot-loader and pass control to it.
So why even have such a minimal piece of software? Why not just have a larger more sophisticated boot-loader? Let us understand the same.
Why Immutable Boot Code?
There are multiple benefits to having an immutable boot code in your system. Some are obvious, some are not very obvious – but relevant all the same.
Once you know that the first piece of software is something that cannot be changed, the boot up of the processor will always be deterministic and predictable. While this is not a tangible benefit as such, it is often a good idea to be able to predict each state in your boot sequence as it helps to anticipate threats better.
Establish a Chain of Trust
In secure embedded systems, each software component should authenticate the next one before passing control to it. However, this chain has to start somewhere – the boot code is the perfect candidate for this purpose. It is then of utmost importance that this boot code is immutable since any tampering with this code can open the system to attacks which can alter or completely eliminate the chain of trust.
For example, the modified malicious boot code may completely bypass security mechanisms and/or change the addresses from where to load the next image and so on.
Prevent Firmware Injection
If the boot code can never be modified, one can never inject any malicious firmware into the system as this injected firmware would have to be signed and/or encrypted and/or possess the same credentials as a genuine image. Also, one can’t load a malicious firmware and pass control to it since the immutable code will not look at any other location except that of the genuine code to load the next image.
Why Immutability of Boot Code Is Not Very Common
Let us understand some common reasons why we don’t commonly find immutability of boot code on the must-have list of a system architect.
This is one of the key tenets of a secure embedded system but often gets overlooked as processors with immutable boot code (or even boot code for that matter) cost more than processors without them. Often this price delta deters the architect from choosing the processor – but this is changing fast!
Incorrect/Out-dated Threat Model
Often times the threat model of any system does not consider firmware injection/read-back as a potential threat as there is this belief that disabling the debugging capability will ensure that no one is able to load new code into/read code from the processor. Well that is NOT true. So if lack of reprogrammability and deterring firmware extraction is absolutely essential, then such threats must be taken into account. Having an immutable boot code goes a long way in being able to prevent firmware modification/read back.
Lack of Knowledge
Not everyone who writes software understands how a CPU works or even how their software does what it is supposed to do. And that is not a big problem in itself.
However, when the architect of the system who is responsible for ensuring security of the design is a person with a limited understanding of the potential threats, immutability of the boot code does not figure on the must-have list due to a lack of understanding of the far-reaching implications and/or the attack vector itself.
Over the last few years, there is a growing realization of the importance of having secure boot and secure firmware upgrade in systems. Immutable boot codes play a huge role in these processes. As a result, the embedded world is taking notice of the importance of this property of boot codes.
In the next post, we talk about diversification!