How (not) to Secure my Microcontroller

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?

Device is Secure. Erase to unsecure?

Device is Secure. Erase to unsecure?

There are different levels of protection you can find in many embedded microprocessors, and the terms might vary from vendor to vendor:

  1. Protect
  2. Secure
  3. Disable Mass Erase

Protect

‘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

‘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:

Flash Configuration Field Description (Source: Freescale KL25Z Reference Manual)

Flash Configuration Field Description (Source: Freescale KL25Z Reference Manual)

The Flash Security Byte is at address 0x40C and is defined as following:

Flash Security Register FTFA_FSEC (Source: Freescale KL25Z Reference Manual)

Flash Security Register FTFA_FSEC (Source: Freescale KL25Z Reference Manual)

Of special interest are the MEEN (Mass Erase Enable) and SEC (Security) bits:

Mass Erase Enable Bits (Source: Freescale KL25Z Reference Manual)

Mass Erase Enable Bits (Source: Freescale KL25Z Reference Manual)

Flash Security (Source: Freescale KL25Z Reference Manual)

Flash Security (Source: Freescale KL25Z Reference Manual)

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):

Security disabled

Security disabled

This puppy has security disabled (the lowest two bits are 0b10).

But here is another one:

Inspecting Binary File

Inspecting Binary File

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:

FTFA_FOPT Register (Source: Freescale KL25Z Reference Manual)

FTFA_FOPT Register (Source: Freescale KL25Z Reference Manual)

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!

Security and Flash option in Processor Expert

Security and Flash option in Processor Expert

So I decided that I could afford to brick one of my KL25Z Freedom boards, but this is what I got:

Irreversible Secure Detected

Irreversible Secure Detected

CodeWarrior saves me from bricking my board 😀 . Thank you!

Note: Using the ‘Simple Flash Programmer’ is preventing me as well to brick my device.

Summary

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 🙂

Advertisements

26 thoughts on “How (not) to Secure my Microcontroller

  1. It seems that whan you secure a device in CW, you are more than warned… You get warnings on component inspector, and also on a prompt just before downloading the code to the board. I bricked the device because I used the SDA flasher applet, and I dragged the wrong file (an ELF file). I am installing a new processor on my board, ans hopefully that will get back to work.

    Like

  2. Pingback: Tutorial: Bits and Pins with Kinetis and the FRDM-KL25Z Board | MCU on Eclipse

  3. Pingback: Binary Files for the mbed Bootloader with Eclipse and GNU ARM Eclipse Plugins | MCU on Eclipse

  4. Pingback: Preventing Reverse Engineering: Enabling Flash Security | MCU on Eclipse

  5. Hi;

    I’m trying to secure my KL25z code, before trying to secure the code I read this post, I was carefully about 0x040D address, bit 3 is set, reset pin is enabled, but the reset don’t occurs and the code isn’t running.

    Can you help me?

    Thanks

    Charles

    Like

      • Hi, Erich;

        Internal peripherals
        Reset control : enabled
        Reset pin : PTA20/RESET_b

        CPU.c

        0x7EU,
        /* NV_FOPT: ??=1,??=1,FAST_INIT=1,LPBOOT1=1,RESET_PIN_CFG=1,NMI_DIS=1,??=1,LPBOOT0=1 */

        Flash security field : Enabled
        – Peripheral settings
        — Reset pin function : Enabled

        On the reset pin I have a sawtooth signal, so the reset pin never goes level 1 and my code never running.

        Charles

        Like

      • Hi Charles, do you have a long reset line, or a noisy envirnment? I had cases where external EMI was causing the device to reset. You can apply internal filters, or put a C and a pull-up to the reset line (externally) to see if this helps?

        Like

      • Hi, Erich;

        My project has an external reset circuit, also has an external watchdog circuit, when I don’t secure the flash, CW 10.6 gives me the message “Target has been RESET and is active”, and my software starts running, but when I secure the flash, CW 10.6 gives me the message “Device is Secure; Device is secured. Erasing …; Target has been RESET and is active.”, after that my software don’t starts running.
        I don’t use the reset pin has an user button.

        When you want I can send you a test project, who I build and has the same problem, just tell me how .

        Charles

        Like

      • Hi Charles,
        if you have secured your device, then the messages from the debugger make 100% sense. Not sure if you have understood the purpose of securing, but if you secure your device, then you cannot access it from the debugger any more (without flash erasing). Try disconnecting the debug cable and check if the target comes out of power-on-reset.

        Like

    • I have added something like this to my projects without Processor Expert:
      /* Flash configuration field */
      __attribute__ ((section (“.cfmconfig”))) const uint8_t _cfm[0x10] = {
      /* NV_BACKKEY3: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY2: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY1: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY0: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY7: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY6: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY5: KEY=0xFF */
      0xFFU,
      /* NV_BACKKEY4: KEY=0xFF */
      0xFFU,
      /* NV_FPROT3: PROT=0xFF */
      0xFFU,
      /* NV_FPROT2: PROT=0xFF */
      0xFFU,
      /* NV_FPROT1: PROT=0xFF */
      0xFFU,
      /* NV_FPROT0: PROT=0xFF */
      0xFFU,
      /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */
      0x7EU,
      /* NV_FOPT: ??=1,??=1,FAST_INIT=1,LPBOOT1=1,RESET_PIN_CFG=1,NMI_DIS=1,??=1,LPBOOT0=1 */
      0xFFU,
      0xFFU,
      0xFFU
      };

      Like

  6. Pingback: Debugging Failure: Check List and Hints | MCU on Eclipse

  7. Pingback: Tutorial: How to Erase the FLASH with the GNU debugger | MCU on Eclipse

  8. Hi Erich, have you been able to use security features in KDS with KSDK and PEx? From what I see, security configuration is declared in “.section .FlashConfig” in gcc\startup_MCU.S file, so currently only manual changing of this value is possible. Do I think correctly?

    Thanks and regards, Filip.

    Like

      • PEx for “KSDK” repository is not so advanced as for “Kinetis” repository, and CPU component doesn’t have security options available (yet, I hope..) from what I see. I will give a try with manual change of this section. Thanks!

        Like

  9. What is the correct way to ensure that no matter what currently resides on the flash, I will be able to reprogram it WITHOUT getting any CW pop-ups (such as the ‘Device is secured’ message box)?

    I have emphasized WITHOUT, because I need the process to be as automatic as possible.

    Of course, you may assume that I haven’t irreversibly secured the device of course (otherwise the question is senseless).

    I have tried the following sequence:
    – Unprotect all sectors
    – Erase all sectors (using mass-erase)
    – Program the executable image
    – Protect all sectors

    But every device that I have tried it on, become non-responsive afterwards (unable to connect with debugger), so I am left to assume that I have irreversibly secured those devices.

    Thanks

    Like

    • I assume you are using Kinetis microcontrollers?
      You need to ensure that whatever you program to the device is using the proper security/flash erase structure defined in the binary.
      If you do that correctly, no other thing is needed. What you might face is a problem with the debugging probe (I had similar problems with openOCD, but works fine with P&E and Segger).
      Other than that, I recommend to invest into something like this: https://www.segger.com/flasher-arm.html
      Because this allows you fully automated flashing of many devices in a production line. We are using that for programming many boards, it is scriptable and can run standalone too.

      Like

      • Thank you very much for your extremely quick response!!!

        We are actually working on Freesscale MC1323x devices (equipped with HCS08 processor).

        Does that impact your answer above in any manner?

        My (s19) binary is perfectly safe, I know this one for a fact.

        I’m still a bit unsure of the procedure that I have described earlier:
        – Unprotect all sectors
        – Erase all sectors (using mass-erase)
        – Program the executable image
        – Protect all sectors

        I have previously used ‘Erase & Program’ as a single operation, which was working fine, except that I was sometimes getting the ‘Device is secured. Mass-erase to unsecure?’ pop-up.

        So I tried separating that operation into ‘Erase’ and then ‘Program’ (with the difference being that this time I am mass-erasing the entire flash, while previously I was only erasing the sectors that were about to be programmed).

        And every device I have tried that on has become inaccessible through debugger (JTAG).

        Thanks again 🙂

        Like

      • Ah, S08 :-).
        In that case this is a sign of unstable connection. Basically with BDM the debugger throws a “device is secure” if it cannot properly stop and talk to the device.
        I had such problem with instable power supply on the board, or with instable/bad cables (BDM flat cable).
        Another case I had when there was a log of noise (motors) nearby: try shielding the cable, try shortening the BDM cable.
        And talking to S08 is through BDM (Background Debug Mode), not through JTAG 🙂

        Like

  10. david a on January 21, 2017 at 08:27 said:
    hi Eric, how do i toggle program flash protection on a mk22fn1m0vlh12

    i can see how to do it in PE or by using

    /* Flash configuration field */
    __attribute__ ((section (“.cfmconfig”))) const uint8_t _cfm[0x10] = {
    /* NV_BACKKEY3: KEY=0xFF */
    0xFFU,
    /* NV_BACKKEY2: KEY=0xFF */

    etc

    but how do i change the following field in my application:

    /* NV_FPROT3: PROT=0xFF */
    0xFFU,
    /* NV_FPROT2: PROT=0xFF */
    0xFFU,
    /* NV_FPROT1: PROT=0xFF */
    0xFFU,
    /* NV_FPROT0: PROT=0x7F */

    i tried
    NV_FPROT3 = 0xFF;
    NV_FPROT2 = 0xFF;
    NV_FPROT1 = 0xFF;
    NV_FPROT0 = 0x7F;

    but that causes hard fault. i can read from those however.

    thanks for help
    dave

    Like

    Reply ↓

    Erich Styger
    on January 21, 2017 at 10:16 said:
    Hi David,
    maybe a better thread to post that question: https://mcuoneclipse.com/2012/11/04/how-not-to-secure-my-microcontroller/
    I’m not sure if I understand you correctly: are you trying to reprogram that protection/cfmconfig from the running application?
    You cannot do something like ‘NV_FPROT3 = 0xFF;’ because NV_FPROT3 is in FLASH, not RAM.

    Like

    Reply ↓

    Like

  11. Pingback: Getting Started: ROM Bootloader on the NXP FRDM-KL03Z Board | MCU on Eclipse

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s