APPROTECT unclarities for NRF9151

Hello,

I have some unclarities for the APPROTECT mechanism on NRF9151.

Basically, I had a misunderstanding of the involved CONFIG features, and as a result I used CONFIG_NRF_APPROTECT_LOCK. However, the idea was that we could still unlock app protection via an OTA firmware update. This seems not possible now (since ERASEPROTECT is also enabled).

- Apparently, enabling CONFIG_NRF_APPROTECT_LOCK also implies that the UICR.APPROTECT is written to 0. I could not find where this is documented or explained. I was under the assumption that the UICR was not changed, so it would be possible to unlock the protection via FW update that sets NRF_APPROTECT_S->APPROTECT.DISABLE. properly. But apparently that's not the case. I could also not find in the code where this is executed. It's not applied in "system_nrf91_approtect.h".

- The reset value of UICR.APPROTECT is not 0xffffffff, but 0x50FA50FA. This is confusing (https://docs.nordicsemi.com/bundle/ps_nrf9151/page/uicr.html#ariaid-title3). It also means that the "hardware and software" AP-Protect implementation type of the table on https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/security/ap_protect.html is not enabled by default on NRF9151, on the contrary.

- To me, the table at https://docs.nordicsemi.com/bundle/ps_nrf9151/page/dif.html#d425e281 is not clear. I assume now that it means for the "debugging possible" rows, all conditions must be true whereas for the "No debugging possible" rows, debugging is not possible as soon as 1 of the conditions is true. Is this correct?

- Also on https://docs.nordicsemi.com/bundle/ps_nrf9151/page/dif.html, APPROTECT.DISABLE and APPROTECT.FORCEPROTECT eventually are the same register, but that's pretty hard to understand from the text until you look either to the code or the effective address. What's the reason for this split?

I suppose that there's no way for me to recover the devices (i.e. enable debug access) that were flashed with CONFIG_NRF_APPROTECT_LOCK? That's not a disaster, since they will later be used in the field, but it would be nice to know.

S.

Parents Reply Children
  • Hello,

    There is no Kconfig option to enable ERASEPROTECT as far as I know, did you set this yourself from with the programmer or with your own  code?

    Apparently, enabling CONFIG_NRF_APPROTECT_LOCK also implies that the UICR.APPROTECT is written to 0. I could not find where this is documented or explained. I was under the assumption that the UICR was not changed, so it would be possible to unlock the protection via FW update that sets NRF_APPROTECT_S->APPROTECT.DISABLE. properly. But apparently that's not the case. I could also not find in the code where this is executed. It's not applied in "system_nrf91_approtect.h".

    It's this code in TF-M that updates the UICR register: https://github.com/nrfconnect/sdk-trusted-firmware-m/blob/cb4acfd047fbb14c09e2d073022e80928ad0c65d/platform/ext/target/nordic_nrf/common/core/target_cfg_53_91.c#L53. I was not aware of it until today, to be honest, and it seems like we need to update the documentation to reflect this. That said, with  CONFIG_NRF_APPROTECT_LOCK selected it won't be possible to disable the approtect anyway as the the NRF_APPROTECT_S->APPROTECT.FORCEPROTECT register will be set by nrf91_handle_approtect().

    - The reset value of UICR.APPROTECT is not 0xffffffff, but 0x50FA50FA. This is confusing (https://docs.nordicsemi.com/bundle/ps_nrf9151/page/uicr.html#ariaid-title3). It also means that the "hardware and software" AP-Protect implementation type of the table on https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/security/ap_protect.html is not enabled by default on NRF9151, on the contrary.

    This can indeed be confusing. The UICR value is 0xFFFFFFFF after the initial ERASEALL operation used to disable APPROTECT, but nrfutil/nrfjprog will write back the unlock value to NRF_UICR_S->APPROTECT again after the erase to prevent it from being inadvertently erased during development when you want approtect to remain disabled.

    - To me, the table at https://docs.nordicsemi.com/bundle/ps_nrf9151/page/dif.html#d425e281 is not clear. I assume now that it means for the "debugging possible" rows, all conditions must be true whereas for the "No debugging possible" rows, debugging is not possible as soon as 1 of the conditions is true. Is this correct?

    Yes correct, and I agree that this could have been made more clear. I think it's implied by the paragraph after:

    Sebastiaan Merckx said:
    APPROTECT.DISABLE is apparently 0x1 after reset, according to https://docs.nordicsemi.com/bundle/ps_nrf9151/page/dif.html#ariaid-title7, but when I configure CONFIG_NRF_APPROTECT_USER_HANDLING=y, it is already set to 0x5A when entering main(). Also after power reset. Where is this done? Is the reset value correctly documented?

    nrf91_handle_approtect() is only called from the FW images executing in the secure domain, so in the bootloader and TF-M. Therefore, the same APPROTECT config you have in your prj.conf file (these are picked up by the TF-M build) must also be applied to your bootloader(s) build(s).

    Best regards,

    Vidar

  • Thanks for your elaborate response, Vidar!

    Most of your comments are clear.

    There is no Kconfig option to enable ERASEPROTECT as far as I know, did you set this yourself from with the programmer or with your own  code?

    => ERASEPROTECT was enabled via the nrfutil.

    That said, with  CONFIG_NRF_APPROTECT_LOCK selected it won't be possible to disable the approtect anyway as the the NRF_APPROTECT_S->APPROTECT.FORCEPROTECT register will be set by nrf91_handle_approtect()

    But this register is not persistent, so in theory, with an OTA that reconfigures APPROTECT, it should have been possible to re-enable debug access, right? That's what I tried. But it didn't work, and that's why I came to the conclusion that UICR.APPROTECT is probably activated. I could be wrong though?

    And yes, you're correct that the bootloader needs the same configuration. I figured that out in the meanwhile but forgot to update the ticket apparently.

  • Sebastiaan Merckx said:
    But this register is not persistent, so in theory, with an OTA that reconfigures APPROTECT, it should have been possible to re-enable debug access, right? That's what I tried. But it didn't work, and that's why I came to the conclusion that UICR.APPROTECT is probably activated. I could be wrong though?

    No you're right. The problem was the the HW protection had been enabled in the non-volatile UICR.APPROTECT register.

  • Hi  

    I have a follow-up question. After activating the erase protection (via "nrfutil device write --address 0x00FF8030 --value 0x0"), I am still able to flash the firmware via nRF Connect in vsCode, which uses "nrfjprog".

    However, when using the nrfutil for flashing instead of nrfjprog, this does not work. I have also tried other chip_erase_mode. It seems to me that nrfutil is doing a too explicit check.

    Version: nrfutil 8.0.0 (54d8087 2025-01-07)

    PS C:\Users\sebas\Downloads> ./nrfutil device write --address 0x00FF8030 --value 0x0
    ✔️ Data written to 50111305
    PS C:\Users\sebas\Downloads> ./nrfutil device program --firmware merged.hex --options chip_erase_mode=ERASE_RANGES_TOUCHED_BY_FIRMWARE
    [00:00:00] ------   0% [1/2 50111305] Failed, Device error: Cannot erase flash pages, device is erase protected                                                    Error: One or more program tasks failed:
     * 50111305: Device error: Cannot erase flash pages, device is erase protected (Generic)
    

  • Hi, 

    To enable the Erase all protection you need to perform a reset after setting the UICR.ERASEPROTECT register. But I agree, nrfutil device should not have aborted the erase just because the register was set. I will relay this feedback to the developers.

Related