Search code examples
embeddedstm32openocd

STM32 Read-out protection via OpenOCD


The STM32 family of microcontrollers features a read-out protection feature so proprietary code can't be read out via the debug interface (JTAG or SWD).

Using OpenOCD, how can I enable/disable the read-out protection via a SWD/JTAG interface? How secure is the RDP read-out protection?

If possible, please give an answer valid for the entire STM32 family.


Solution

  • RDP levels

    First, you have to know which level of readout protection you want to set (refer e.g. to section 3.7.3 of the STM32F4 reference manual):

    • RDP level 1: This level is reversible. Once you disable it, the system memory is mass-erased and you can re-program
    • RDP level 2: This level is irreversible and disables the debug interface altogether. The only way of updating your firmware is via some bootloader mechanism.

    Usually you want to activate RDP level 1. In order to avoid mistakes that will certainly brick the microcontroller, I will not show how to enable RDP level 2 in this answer. Refer to the reference manual for details.

    Activating it using OpenOCD

    The activation feature is actually built-in into OpenOCD using the lock command. Just like executing the program command to flash your firmware, you can use the stm32f1x lock command (or stm32f2x lock for STM32F2/F4) to activate it.

    A typical OpenOCD configuration file would look like this (you need to flash the correct firmware before running this):

    # Set RDP to level 1
    init
    reset halt
    stm32f1x lock 0
    reset halt
    exit
    

    Note that the readout-protection will only be in effect once the microcontroller is reset or powered off (that's why there's a second reset in the command sequence).

    A typical OpenOCD call could look like this:

    openocd -d0  -f stlink-v2.cfg -f ocd-stm32f0.cfg -f ocd-lock.cfg
    

    where ocd-lock.cfg contains the command sequence shown above.

    Once activated, you can verify that the RDP is active by trying to flash the MCU using your usual programming command sequence

    Deactivating RDP

    Deactivating it is just as simple: Just use stm32f1x unlock (or stm32f2x unlock for F2/F4 devices) like this:

    # Set RDP to level 0
    init
    reset halt
    stm32f1x unlock 0
    reset halt
    exit
    

    How secure is it?

    That's a tough question that can't really be answered without additional information. One summary answer I can give is that it's pretty secure if you assume the protection has no inherent bugs and someone uses software tools only.

    One of the most popular methods of resetting the RDP bit without mass-erasing the flash is to disable the RDP with a laser. Given the fact that the STM32 family is not a family of dedicated security microcontrollers with specific countermeasures, this is rather easy if you have the right equipment and sufficient experience in this area. Even some specific security MCUs have some security issues, see e.g. the Security from the IC backside talk. However, most low-level attackers will usually refrain from the cost of doing so.