There are several reports in the forums around having ‘secured’ the Freedom board. But what does ‘securing’ a board mean? And what does it mean if I get that ‘Device is Secure’ dialog?
There are different levels of protection you can find in many embedded microprocessors, and the terms might vary from vendor to vendor:
- Disable Mass Erase
‘Protect’ is a prevention of accidentally erasing the device. The flash programming controller on the device protects parts or the full flash memory from being overwritten. The typical use case for protection is to prevent the application on the device to overwrite critical parts of the memory, such as in the context of a bootloader. In that case the flash blocks of the bootloader are protected to avoid that it gets reprogrammed. Typically protected memory is still accessible by the debugger, and unprotection requires setting some special device bits and/or mass erase of the memory.
‘Secure’ prevents that the device can be read-out using a debugger. This is usually applied to prevent reverse engineering of the software on a microcontroller. A debugger will not be able to read anything from the device. But typically the debugger can start a mass erase. The mass erase is a special command to completely erase the device. After erase, the device can be programmed as usually.
Disable Mass Erase
With both ‘protect’ and ‘secure’ it is possible for the debugger to reset the device so it can be re-programmed. As explained above, this is done with erasing the flash as a ‘reset’ mechanism. But there are cases where you want to prevent this as well. For example I have a safety or security critical device, and you want to prevent that an intruder can alter your microcontroller. With disabling mass erase I close that door too. On the KL25Z, that ‘disable mass erase’ only has an effect if combined with securing the device. Typically I can still have a bootloader, but only the application (and not the debugger) will be able to change things on the device. So I need to implement a secure connection (backdoor) to the device (for example with a serial SCI protocol), which would allow me to reprogram my device. But an external debugger without having knowledge of my custom protocol on a different communication channel will not be able to talk to my device.
Accidentally protecting and securing devices is not an issue for CodeWarrior (see this link), ❗ as long as the debugger can mass erase the device :!:. But if I accidentally have disabled mass erase for a secured device, I have bricked my device: Game over 😦
Checking the Bits
How to find out in a binary if protection, security or even mass erase is disabled? This requires the understanding of the device functionality. This varies from device to device, so I show it here for the Freescale KL25Z on the FRDM-KL25Z board.
At reset, the KL25Z reads a flash configuration from memory to set the protection and security. That configuration is located at address 0x400-0x40F for the KL25Z:
The Flash Security Byte is at address 0x40C and is defined as following:
Of special interest are the MEEN (Mass Erase Enable) and SEC (Security) bits:
So the really toxic 😯 combination is having MEEN set to 0b10 (mass erase is disabled) with SEC anything different than 0b10.
For example, I have here a binary file, shown in Eclipse (using EHEP):
This puppy has security disabled (the lowest two bits are 0b10).
But here is another one:
Here the address 0x40C is all zero. Which means that security is enabled (0b00), while mass erase is still enabled (0b00). Uff :-)!
💡 With binary files I need to specify what the content of undefined bytes will be (as it is a full memory map). Luckily both the usual patterns of setting undefined bytes to either 0x00 or 0xff will *not* disable mass erase, as mass erase is disabled with 0b10 :-).
But having the undefined bytes set to zero causes another problem: the address 0x40D is zero as well, this mean that the FTFA_FOPT register is zero:
Which means that reset is disabled after a POR (Power On Reset). And this might be a problem for a JTAG probe to get hold of the device. So using 0x00 for undefined bytes is not a good idea.
Inspecting S-Records/Intel Hex files works in a similar way: find the address 0x40C and inspect the content.
Safety Belt with CodeWarrior
The question is: will I get warned if I program a ‘toxic’ puppy with CodeWarrior?
Let’s try it to do toxic things in my application. This is easy with Processor Expert: two settings in the CPU component and things are really bad if that gets programmed into the device. And I cannot say that I have not been warned!
So I decided that I could afford to brick one of my KL25Z Freedom boards, but this is what I got:
CodeWarrior saves me from bricking my board 😀 . Thank you!
Note: Using the ‘Simple Flash Programmer’ is preventing me as well to brick my device.
Using ‘0x00’ for undefined bytes is usually not a good thing. I better use 0xff as that’s the default ‘erased’ state of a flash memory cell. Using anything else than 0xff has the danger of a ‘game over’ situation.
Before programming an application I have received from someone I do not trust, it is a good idea to inspect the file if it does not brick my board ;-). In any case, CodeWarrior for MCU10.3 is checking if I’m going to permanently lock my microcontroller: another good reason for CodeWarrior. But better if I check myself in any case too.
Happy Securing 🙂