Request for Guidance and Documentation on ERASEPROTECT/APPROTECT/SECUREAPPROTECT

Hi,

We've created an application for the nRF9160 non secure image with TF-M and are looking to add in ERASEPROTECT/APPROTECT/SECUREAPPROTECT functionality. From reading the Production Programming document I can see that when enabling ERASEPROTECT, APPROTECT, and SECUREAPPROTECT, the only way to recover the device is "if the installed firmware and the debugger both write the same non-zero 32-bit KEY value to ERASPROTECT.DISABLE (0x01C)"

My understanding is that since we already have a application that we want to build for non secure (for example, if it was the Blinky sample built for the nrf9160dk_nrf9160_ns with TF-M), we would need to create a separate secure image in order to write the non-zero 32-bit key value to ERASEPROTECT.DISABLE.

My questions are:

  1. How can we create a separate secure image with our nonsecure application? As I understand, the secure image should run first before handing over control of the execution to the nonsecure application. What would be the best way to add an additional secure image to something like the nonsecure Blinky sample? Would this be a child image?
  2. Is there any examples of how to interact with the ERASEPROTECT, APPROTECT, and SECUREAPPROTECT settings from the application side? I unfortunately don't have much experience working directly with various registers on the nRF9160 and would be happy to get any help possible, especially with regards to what needs to be provisioned to interact with the registers and if there is a getting started guide for tasks like this. I want to create a script that upon boot up of the nRF9160, the program: 
    1. Checks if any of the ERASEPROTECT, APPROTECT, and SECUREAPPROTECT functionalities are not enabled. If any of these are not enabled, the program will enable the protection and perform a reset of the device. On the next boot up, all three of the protections should be enabled.
    2. If ERASEPROTECT, APPROTECT, and SECUREAPPROTECT are all enabled, it will write a 32-bit key to ERASPROTECT.DISABLE. This way, if we need to recover the device, we can use the SWD to write in the 32-bit key to trigger an erase all
    3. Finally, hands over execution to our nonsecure program
  3. Our current application uses MCUBOOT and supports OTA. Would ERASEPROTECT affect the application's ability to download new application updates and boot up with the new updates?

I've found some previous posts which seem to be quite helpful, however I'm still unsure of how I would need to go about integrating it into an existing nonsecure application. 
This post seems fairly helpful in talking about how to create a non-ns script to remove erase protect. However, I'm having a bit of difficulty following/finding the documentation on modifying/reading contents for items like NRF_NVMC and NRF_UICR through the application, and what the particular bits like (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos) being set indicate. 

Thank you in advance!

Parents Reply Children
  • Hi Edward,

    1. This might be based on a misunderstanding:

    When building an application for the "_ns" target, you tell NCS that you are building a non-secure application (read: one that shouldn't be trusted), and then NCS will automatically include TF-M and a secure partition which exposes various "secure" functions and services such as cryptography functions.

    Please see this article by my colleague: An Introduction to Trusted Firmware-M (TF-M)

    So, it's automatically included, but note that this secure partition is not a child image, and in fact isn't even built on Zephyr.

    If the provided secure services don't cover your needs, you can create custom Root-of-Trust services that you can access from your non-secure code.

    2. regarding this point, I should again clarify some things:

    APPROTECT and ERASEPROTECT have very different use cases.

    APPROTECT, enables protection of the debug access port, which mainly serves to prevent people with a debugger from extracting the firmware from one of your devices. If this were disabled, someone could for instance copy your product by first copying the physical hardware and then just flashing firmware that they extracted from an original device.

    APPROTECT protects intellectual property.

    APPROTECT can usually be disabled by doing a "recover", which in essence is an erase-all of the flash. This will unlock the access port, but there will be no firmware left to extract.

    ERASEPROTECT on the other hand, protects against someone with a debugger, doing exactly that, erasing the device. As far as I know, this is only useful if you're selling some special device where it is absolutely critical that nobody is able to flash their own firmware to the device.

    ERASEPROTECT is rarely needed, and is not "supported" in NCS, it has to be done by setting the registers directly. Are you sure you need this?

    Note that if you enable both ERASEPROTECT and APPROTECT and you haven't added a robust way to unlock the device from the inside, you will have bricked the device.

    APPROTECT is commonly used and can be set through NCS, by setting one or both of the following Kconfig options (you usually only do this for the release build that will be flashed to production devices):

    CONFIG_NRF_APPROTECT_LOCK - locks the Debug Access Port entirely

    CONFIG_NRF_SECURE_APPROTECT_LOCK - Locks the ability to debug code and peripherals under the "secure" environment.

    See here for a more in-depth description: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/app_dev/ap_protect/index.html#configuration-overview-in-the-ncs

    I think it's likely that your needs are entirely covered by the default APPROTECT options.

    3. if you do use ERASEPROTECT; then this won't affect your DFU/FOTA ability. ERASEPROTECT only protects against an "eraseall" operation, which isn't used for FOTA.

    Regarding your supplemental question, I'm actually not sure. I'll see if a colleague can answer that for you. I'll be out-of-office for the next 14 days.

    Best regards,

    Raoul

  • Hi Raoul,

    Thank you for getting back to me and sharing that information. 

    1. Thank you for clarifying the process for the ns and non-ns builds. In this case, if we needed to add a bit of additional code to the our application to write the 32-bit key into the ERASEPROTECT.DISABLE register, what would you recommend as the best way to go about that? Is there an easy way to add this to be executed by the secure partition while keeping TF-M?

    2. In our case with the nRF9160, the APPROTECT and SECUREAPPROTECT are important to prevent someone else from reading back our firmware. Thank you for sharing the information about the KCONFIGs, that should come in handy in our case.

    Our application uses the nRF9160's CMNG to store certificates.  Since ERASEALL does not remove certificates stored in CMNG, our concern is to prevent the possibility of an attack that someone else may be able to load their own program onto our device and use the certificates for their own purposes. Although they shouldn't be able to read out the certificate contents, they could possibly use the certificates in a similar manner as we use it in our application.

    Note that if you enable both ERASEPROTECT and APPROTECT and you haven't added a robust way to unlock the device from the inside, you will have bricked the device.

    I'm hoping to get a bit of guidance on how to properly add a robust way to unlock the device. Any help would be greatly appreciated, thank you!

    3. Thank you for confirming that ERASEPROTECT does not affect FOTA.

    Thank you again for your help!

  • Hi blasph,

    We were in a similar situation, and figured out how to enable/disable all three protections: APPROTECT, SECUREAPPROTECT, and ERASEPROTECT.

    First off, we found that CONFIG_NRF_APPROTECT_LOCK and CONFIG_NRF_SECURE_APPROTECT_LOCK are only supported on the nRF52 and nRF53 series SoCs, and cannot be used with the nRF91 series. See documentation here.

    Setting these protections on the nRF9160 seems to only be possible by writing to the UICR with a JLink during production.

    Mechanism to set ERASEPROTECT.DISABLE in MCUBoot

    This is very important to implement first, as it is needed if you ever want to disable ERASEPROTECT. Without this mechanism, you will never be able to erase the chip again once ERASEPROTECT is enabled, and it could become a brick.

    We decided to trigger setting NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE to our special 32-bit unlock key in MCUBoot only when serial recovery is forced via GPIO button press. Just before boot_serial_enter() is called in MCUBoot, we check if NRF_UICR_S->ERASEPROTECT is enabled, and if it is, set NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = (uint32_t)0xDEADF00D.

    bootloader/mcuboot/boot/zephyr/main.c

    #ifdef CONFIG_BOOT_SERIAL_ENTRANCE_GPIO
        if (detect_pin() &&
                !boot_skip_serial_recovery()) {
    
            if (NRF_UICR_S->ERASEPROTECT != UICR_ERASEPROTECT_PALL_Unprotected)
            {
                // Disable ERASEPROTECT in serial recovery
                NRF_CTRL_AP_PERI_S->ERASEPROTECT.DISABLE = (uint32_t)0xDEADF00D;
            }
            boot_serial_enter();
        }
    #endif

    If serial recovery is not activated at boot, you can optionally prevent ERASEPROTECT.DISABLE from being written to until next reboot by setting NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK = (uint32_t)0x00000001

        ...
        if (NRF_UICR_S->ERASEPROTECT != UICR_ERASEPROTECT_PALL_Unprotected)
        {
            // Lock ERASEPROTECT before booting image
            NRF_CTRL_AP_PERI_S->ERASEPROTECT.LOCK = (uint32_t)0x00000001;
        }
        FIH_CALL(boot_go, fih_rc, &rsp);
        ...

    Enabling APPROTECT, SECUREAPPROTECT, and ERASEPROTECT in Production

    We learned that you can use a sequence of nrfjprog commands, or a JLink Commander script to program our factory_image.hex file, and then write to the UICR to set all three protections, followed by a pin reset.

    nrfjprog commands:

    nrfjprog.exe --family NRF91 --program factory_image.hex --chiperase --verify factory_image.hex
    nrfjprog.exe --family NRF91 --memwr 0x00FF8000 --val 0
    nrfjprog.exe --family NRF91 --memwr 0x00FF802C --val 0
    nrfjprog.exe --family NRF91 --memwr 0x00FF8030 --val 0
    nrfjprog.exe --family NRF91 --pinreset

    JLink Commander script:

    device NRF9160_XXAA
    selectinterface SWD
    speed 4000
    connect
    halt
    erase
    loadfile factory_image.hex
    write4 0x00FF8000 0
    write4 0x00FF802C 0
    write4 0x00FF8030 0
    RSetType 2
    reset
    exit

    At this point, the nRF9160 should have all three protections set. The JLink debugger will no longer work at all if you try to even connect and detect the Chip ID. The nRF9160 is completely protected from any and all access over the SWD interface, including flash read, write, and erase, and is considered "sealed". The only access that can be done over CTRL-AP is to set ERASEPROTECT.DISABLE to hopefully disable ERASEPROTECT and allow an ERASEALL.


    Disabling ERASEPROTECT and Performing ERASEALL

    If you do need to erase a device that has been sealed, you must first boot the nRF9160 and trigger the mechanism to set ERASEPROTECT.DISABLE to the known 32-bit key value.

    For this example, serial recovery must be forced via button press so that ERASEPROTECT.DISABLE is set to our key 0xDEADF00D.

    Then, the following JLink Commander script can be used to set the Ctrl-AP ERASEPROTECT.DISABLE to the matching key, and then trigger an ERASEALL and RESET.

    JLink Commander script:

    // Setup SWD
    SWDSelect               // Activate SWD
    SWDWriteDP 1 0x50000000 // Enable debug power
    
    // Set ERASEPROTECT.DISABLE
    SWDWriteDP 2 0x04000010 // Select the 0x04XXXXXX Access Port and 0xXXXXX01X Register bank in the access port
    SWDWriteAP 3 0xDEADF00D // CTRL-AP Bank 1, register offset 3 (ERASEPROTECT.DISABLE 0x01C)
    
    // Perform ERASEALL
    SWDWriteDP 2 0x04000000 // Select the 0x04XXXXXX Access Port and 0xXXXXX00X Register bank in the access port
    SWDWriteAP 1 0x00000001 // CTRL-AP Bank 0, register offset 1 (ERASEALL 0x004)
    SWDReadAP 2             // CTRL-AP Bank 0, register offset 2 (ERASEALLSTATUS 0x008)
    SWDReadAP 2             // Second read returns the value: 0 = Ready, 1 = Busy
    sleep 2000
    SWDReadAP 2             // CTRL-AP Bank 0, register offset 2 (ERASEALLSTATUS 0x008)
    SWDReadAP 2             // Second read returns the value: 0 = Ready, 1 = Busy
    
    // Perform RESET
    SWDWriteAP 0 0x00000001 // CTRL-AP Bank 0, register offset 0 (RESET 0x000)
    SWDWriteAP 0 0x00000000 // CTRL-AP Bank 0, register offset 0 (RESET 0x000)
    SWDReadAP 0             // CTRL-AP Bank 0, register offset 0 (RESET 0x000)
    SWDReadAP 0             // Second read returns the value: 0 = NoReset, 1 = Reset
    exit

    Hope this helps!

  • Hi Rory,

    Thank you very much for replying and for the in depth write up! 

    Thank you for clarifying that those KCONFIGs don't work for the nRF9160. 

    The information you provided about setting the protections via the JLink Commander scripts and modifying the mcuboot main.c is extremely helpful, thank you for sharing that! I'll try implementing this over the next couple of days and will circle back with my findings. 

  • Hi Rory,

    Apologies for the day delay in response, I've been pulled to a different project for the last bit and am just able to get back into this project. 

    I've setup my device to use the MCUboot edit and am able to successfully replicate having the MCUboot file set a key and using the JLink Commander script to remove the ERASEPROTECT! Thank you for your help! I will continue with testing the JLink Commander script to flash the hex file and set the protections.

    The only thing I'd hope for on, which may be a bit out of scope, is if there's a better way to locate the code that sets the script to be closer to the application directory. This way my coworkers can replicate this without making a more-so in-tree change. I've been able to create a script based off of this response to set the key when built for the nrf9160dk_nrf9160 (not ns) -- I'm curious if there's a way to merge a compiled hex file built for the nrf9160dk_nrf9160 into a separate nrf9160dk_nrf9160_ns application.

     Thank you again for the help, Rory!

Related