Preventing Reverse Engineering: Enabling Flash Security

Now I have invested a lot of time into my application, ready to be flashed on the devices and shipped. But wait: I don’t want that someone can read out the code from my device and have it reverse engineered. For this, I can ‘secure’ the device.

Flash Security Settings

Flash Security Settings

There are several ways to prevent unauthorized access with a debugger to the device:

  1. Disabling the debug interface: this is a rather weak method, as there might be still a small time slot after reset of the device until the device has disabled the debug interface. And if the debugger is fast enough, it might stop the target before it disables the debug interface. But this method in combination with other methods is still very valuable.
  2. Enabling Flash Security: this is typically a setting which prevents the debug block on the chip to access the flash memory. You only can regain access to the device if a complete erase of the flash memory is done first. This still protects the code on the target (it gets erased), and allows to regain access to the device during the development process.
  3. Disabling FLASH Mass Erase. Only having the Flash Security set still would allow a person to gain access to the device and program it with a different (malicious) firmware. To prevent this, the mass erase can be disabled. So disabling flash mass erasing in combination with the security setting is a one way thing: once set, there is no way back to regain access to the device, except some backdoor has been implemented.

Accidentally setting the wrong bits can be very bad, as outlined in “How (not) to Secure my Microcontroller“. Every microcontroller has some specific bits and settings which need to be set, and different ways how to implement a back door to regain access. Typically it is best if the backdoor is implemented through another hidden channel, e.g. with an encrypted password sent over USB or RS-232.

I show in this example how to enable the security for the Freescale KL25Z which is an ARM Cortex-M0+, using Processor Expert. The setting is in the CPU component. I enable the ‘Flash security’ option, and as explained above, I keep ‘Mass erase’ enabled:

Enabled Flash Security

Enabled Flash Security

After downloading such an application to the microcontroller will prevent that I can debug it: the P&E interface tells me that the device is secure:

Device is Secure

Device is Secure

I only get access to the device again with erasing the device with a new binary, and because Mass Erase is *not* disabled.

If somehow that does not work, there is an option in the P&E GDB panel which does an ‘early’ mass erase:

Always Mass Erase on Connect

Always Mass Erase on Connect

πŸ’‘ I do not have a board to spare now, so I do not show here an example with the Mass Erase disabled. πŸ˜‰

With Segger J-Link, I get a warning:

Segger Security Warning

Segger Security Warning

πŸ’‘ That dialog might be hidden behind Eclipse, so make sure you move that dialog to the foreground.

So the Segger J-Link will automatically disable the security bit to protect me from doing a mistake. To bypass that safety check, I need to specify the device with “(allow security)”:

Segger J-Link Device Name to Allow Security Bit Programming

Segger J-Link Device Name to Allow Security Bit Programming

But just to be clear: with this I need to make sure that I do not accidentally brick my board!

Summary

Enabling the Flash Security setting will prevent that someone is able to read out the (assembly/binary) code from the device for reverse engineering. Segger has a protection built in to prevent me doing a mistake. If mass erase is still enabled, I can erase the memory and get access to my device again. All in all, this is a very handy feature, but like a sharp knife: used with care πŸ˜‰

Happy Securing πŸ™‚

 

28 thoughts on “Preventing Reverse Engineering: Enabling Flash Security

  1. Hello Erich,

    I got the same error message when trying to secure Kinetis K10 with J-Link. It seems to me that you are using Kinetis Design Studio in yout solution. I’m using CodeWarrior and I can’t find a device with “allow security”.
    Can you help me to enable security flashing with CodeWarrior and J-Link?
    Many thanks.

    Greetings
    Peter

    Like

    • Hi Petr,
      yes, I used Kinetis Design Studio in that article. To my knowledge CodeWarrior will help you *not* to secure the target if you do normal debug. But to my knowledge if you use the Target Task flash programming, it allows you to do this. See https://mcuoneclipse.com/2012/04/30/flashing-with-a-button-and-a-magic-wand/ and https://mcuoneclipse.com/2012/08/02/standalone-flash-programmer/
      Basically use that ‘Erase and Program’ with your .s19 or .elf with security enabled.

      I hope that helps,
      Erich

      Like

        • Hi Erich,

          I created a connection configuration and connected to the secured MCU. The JTAG adapter was not able to get the disassembly from the MCU That’s OK, I think.
          But I can’t look into the flash security bits. Also the MCU doesn’t run its application. Furthermore, after disconnection and resetting the device it doesn’t run the application until I flash the application again.
          Any idea what is going wrong?

          Like

        • Hi Peter,
          Can you connect/attach to a non-secured device to verify that the setup is working?
          If it is secured, then it makes sense that you cannot read the memory/disassemble it.
          Does the program run without security enabled? At least that would be a starting point.
          Erich

          Like

        • Hi Erich,

          if I connect to an unsecured device with the connection configuration everything looks fine. I see the disassembly and the registers. The MCU is running and I can pause and start it. After disconnecting the MCU is still runing.

          Like

        • Hi Peter,
          ok, then this will be a difficult one to debug. What you could do is to spread some LED blink debug code into your application. First start with the startup code to see if the processor cames through reset, and then see how far it goes. If you put in some blink codes, you could hook up a scope and find out until where it goes.
          Good luck!
          Erich

          Like

        • Hi Erich,

          OK. I will see what I can do.
          Many thanks for the very fast answering and help.

          Peter.

          Like

  2. What is the way to download the program to the board?
    Having activated “flash security” in the processor expert, I press run and the console says:

    INF: Initializing.
    INF: Device is Secure.
    INF: Device is secured. Erasing …
    INF: Target has-been reset and is active.

    But the program never starts to run.
    Do you know what could be happening? Thanks!

    Like

  3. Hi Erich, I started this thread in the Freescale community forum asking why the debug mode is possible when the flash security is enabled, please if you know why. Could you please help me?

    freescale community thread/347781

    Like

  4. Don’t suppose you know how to secure device using KSDK 1.2 or 1.3 within Eclipse Mars or Neon? I’m using segger j-link. I thought I could perhaps do this by modifying the values in the startup_{board}.s just after .”section .FlashConfig, “a”. When I run the debugger I can see memory at 0x40C is updated with the values I set but when I restart board the device ends up hard faulting and values in FSEC register tell the board is still unsecure.

    Like

    • Yes, you would have to set the flash protection values in the flash configuration section of the startup code/file. But make sure you use the ‘allow security’ device name for Segger so that these bits are actually written to the target.

      Like

      • Thanks Erich. Sorry I should have mentioned that I had already done that. If I choose device with ‘allow security’ then memory at 0x40C gets changed to the value I want (0xFFFFFFFD) but even after restart the FSEC register still reports unsecure. If I do not use ‘allow security’ then memory at 0x40C seems to always be set to a value of 0xFFFFFFFE. I think the j-link might still be forcing FSEC to be FFFFFFFE even though memory at 0x40C is set to FFFFFFFD. I’m using a FRDM K64F board and I thought maybe its the built in Open SDA debugger doing something, so I tried it with my external J-Link probe but same result. Wondering now if this isn’t a bug with the J-Link software 😦

        Like

  5. Hi,

    I am trying to used flash security with a KL25Z128 processor and the Multilink Universial (using the pegdbserver and gdb. I have a program that works fine when programming with Flash Security disabled, but fails to start when it is enabled. Any idea what I could be doing wrong? Can I even use Security with the Multilink?

    Thanks,
    Ralph

    Like

    • Hi Ralph,
      I know that the P&E debug protocol tries to prevent you to permanently lock the device. Other than that, everything should be possible. Which microcontroller are you using? In any case, I would go ahead and contact P&E?
      Erich

      Like

      • Hi Erich,

        thanks for the quick reply. The microcontroller is an MKL25Z128VLH4. I will contact P&E as suggested.

        Thanks,
        Ralph

        Like

      • Hi Erich,
        after a long time I got the answer from PEMicro:
        “the problem is, when you set flash security during programming we then reset
        the part to debug it.

        If the part is secure on reset, we unsecure the part which erases the flash,
        rendering the code blank and hence the debug session fails..”
        And sure enough, the server console (see below) seems to support this.
        Do you have any idea how to prevent the final reset/erase – I had no luck getting a response from PEMicro on that, other than that they want to sell me an expensive programming solution?
        It seems you tested with at least Segger J-Link, which I don’t have and FRDM-KL25Z, which I do. For the FRDM-KL25Z, do you still know which bootloader you flashed onto the board and what the Startup and Debug settings in KDS need to be?
        Thanks,
        Ralph
        —————–
        Server Console:
        PS C:\Users\aze\Desktop\prog> ./pegdbserver_console -startserver -device=Freescale_KL2x_KL25Z128M4 -attachonly

        P&E GDB Server for Arm(R) devices, Version 6.43.00.00
        Copyright 2014, P&E Microcomputer Systems Inc, All rights reserved

        Loading library C:\Users\aze\Desktop\prog\gdi\unit_ngs_arm_internal.dll … Done.

        Command line arguments: -startserver -device=Freescale_KL2x_KL25Z128M4 -attachonly
        Device selected is NXP_KL2x_KL25Z128M4
        HW Auto-Selected : Interface=USBMULTILINK Port=PE5658402 ; USB1 : Multilink Universal Rev B (PE5658402)
        Connecting to target.
        P&E Interface detected – Flash Version 6.15
        Device is NXP_KL2x_KL25Z128M4.
        Mode is In-Circuit Debug.

        (C)opyright 2012, P&E Microcomputer Systems, Inc. (www.pemicro.com)
        API version is 101

        Creating kernel driver for freertos
        Server 1 running on 127.0.0.1:7224
        Server 2 running on 127.0.0.1:7226
        Server 3 running on 127.0.0.1:7228
        Server 4 running on 127.0.0.1:7230
        Server 5 running on 127.0.0.1:7232
        Server 6 running on 127.0.0.1:7234
        All Servers Running
        Connection from “127.0.0.1” via 127.0.0.1
        Copyright 2012 P&E Microcomputer Systems,Inc.
        Command Line :”C:\Users\aze\Desktop\prog\pegdbserver_console.exe” -startserver -device=Freescale_KL2x_KL25Z128M4 -attachonly

        CMD>RE

        Initializing.
        Target has been RESET and is active.
        CMD>CM C:\Users\aze\Desktop\prog\gdi\P&E\supportFiles_ARM\NXP\KL2x\freescale_kl25z128m4_1x32x32k_pflash.arp

        Initializing.
        Initialized.

        ;version 1.05, 06/02/2014, Copyright 2014 P&E Microcomputer Systems, Inc. All rights reserved. http://www.pemicro.com [mk_128k_n_pflash_m0]

        ;device freescale, kl25z128m4, 1x32x32k, desc=pflash

        ;begin_cs device=$00000000, length=$00020000, ram=$20000000

        Loading programming algorithm …

        WARNING – Selected .ARP file has been modified. CRC16 = $139E
        Done.
        CMD>VC
        Verifying object file CRC-16 to device ranges …
        block 00000000-000000BF …
        Calculated CRC-16 does not match block. (File = $27D7, Device = $ED3C)

        CMD>EM

        Erasing.
        Module has been erased.
        Reloading programming algorithm …
        done.
        CMD>PM

        Programming.
        Processing Object File Data …

        .
        Programmed.
        CMD>VC
        Verifying object file CRC-16 to device ranges …
        block 00000000-000000BF …
        Ok.
        block 00000400-0000F2BF …
        Ok.
        Checksum Verification Successful. (Cumulative CRC-16=$C940)

        CMD>RE

        Initializing.
        Device is Secure.

        Device is secured. Erasing …
        Target has been RESET and is active.
        Disconnected from “127.0.0.1” via 127.0.0.1
        Target Disconnected.
        Target Disconnected.

        Like

        • Hi Ralph,
          this is what I have on my board:
          Board Name is: FRDM-KL25Z
          MicroBoot Kernel Version is: 1.05
          Bootloader Version is: 1.11
          Installed Application: PEMicro FRDM-KL25Z Mass Storage/Debug App
          Application Version is: 1.14

          No special debug settings in KDS (the default ones).

          Like

        • Hi Erich,

          thanks a lot. It works perfectly with those settings.
          The problem I had really only occurs for the Multilink Universal using the gdb tools, where enabling security always causes the extraneous unpreventable mass erase after program.

          Ralph

          Like

  6. Hi Erich,

    I’ve defined “BUILD_CONFIG_DEBUG” in the project Properties>C/C++ Build>Settings>Cross ARM C Compiler>Preprocessor>Defined Symbols.
    I’m using that define in several places in my code to enable/disable things which are appropriate for debug vs. production.

    Is it possible to enable/disable flash security based on which build configuration is selected at compile time?

    I see that PE is defining it in Cpu.c > PE_low_level_init() >
    /* Flash configuration field */
    __attribute__ ((section (“.cfmconfig”))) const uint8_t _cfm[0x10] = {

    /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=1,SEC=2 */
    0x76U,

    };
    And the linker file ensures that cfmconfig goes in the correct spot.

    Is there a way to override this at compile time without having to disable PE code generation?
    Thanks!

    Like

    • Hi Paul,
      There is no easy way to do this I think. If you don’t need to regenerate code, then you could disable code generation (see https://mcuoneclipse.com/2012/03/23/disable-my-code-generation/) for the CPU component, and do your changes in Cpu.c.
      What I do most of the time is to use Processor Expert configurations (see https://mcuoneclipse.com/2012/03/07/configurations-with-processor-expert/). The configuration creates a #define I can use in my application.
      The thing to keep in mind that this is not linked in anyway with the Eclipse CDT ‘build configuration’ (like debug or release). So you would have to select/switch the Processor Expert configuration and generate code for it.

      I hope this helps,
      Erich

      Like

    • NM, I figured it out- it was right there! There’s a check-box labeled “Flash Configuration Field” in the Cpu bean which when unchecked prevents PE from generating that definition.

      So I just copied the definition that PE had created to my main.c and added my preprocessor ifdef.


      #ifdef BUILD_CONFIG_DEBUG
      /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=1,SEC=2 */
      0x76U,
      #else
      /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=1,SEC=0 */
      0x74U,
      #endif

      Like

  7. Pingback: Execute-Only-Code with GNU and gcc | MCU on Eclipse

  8. Pingback: Reverse Engineering of a Not-so-Secure IoT Device | MCU on Eclipse

Leave a reply to Centaurian Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.