TF-M Isolation Level is 1 with Profile Large

Dear all

Is CONFIG_TFM_ISOLATION_LEVEL = 2 in general supported by Nordic SDK v2.6.0 on a nRF9160?

If set CONFIG_TFM_ISOLATION_LEVEL = 2 in prj.conf, it's always overwritten to 1 by the default value in /nrf/modules/trusted-firmware-m/Kconfig Related kconfigs set in prj.conf:

  • CONFIG_TFM_IPC=1
  • CONFIG_TFM_ISOLATION_LEVEL=2
  • CONFIG_TFM_PROFILE_TYPE_LARGE=y

Thanks for your support

Manuel

Parents Reply Children
  • Thanks  for looking at it. I really appreciate.

    In the meanwhile I also tried to remove `CONFIG_TFM_PROFILE_TYPE_LARGE=y` and I added `CONFIG_TFM_IPC=y` and `CONFIG_TFM_ISOLATION_LEVEL=2`.

    Isolation Level is now logged at `2`. However, I run now into a MemManage fault.

  • Hi, 

    What is the application? Are you using the sample or developing your application?

    Could you provide the prj.conf and .conf under build/zephyr?

    -Amanda H.

  • Dear  

    I could find out what causes the issue.

    Within our custom secure service we access the UICR register to read the status of APPROTECT, ERASEPROTECT and SECUREAPPROTECT. This leads to the MemManage fault isses (if I comment it out, it works as expected).

    Previously with Isolation Level 1 it worked with the code below within the secure service. How can we read the UICR from non-secure part without violating the memory access rules?

    Best,

    Manuel

        EN_protection protection = PROTECTION_NONE;
        uint32_t *APPROTECT = (uint32_t *)(0x00FF8000);
        uint32_t *ERASEPROTECT = (uint32_t *)(0x00FF8030);
        uint32_t *SECUREAPPROTECT = (uint32_t *)(0x00FF802C);
        if (*APPROTECT != 0xFFFFFFFF) {
            protection |= PROTECTION_ACCESS_PORT;
        }
        if (*ERASEPROTECT != 0xFFFFFFFF) {
            protection |= PROTECTION_ERASE_PROTECTION;
        }
        if (*SECUREAPPROTECT != 0xFFFFFFFF) {
            protection |= PROTECTION_SECURE_ACCESS_PORT;
        }

  • Hi,

    You need a custom memory read service implemented in Platform Root of Trust to read UICR in Isolation 2 (and non-supported level 3). ARoTs don't have access to UICRs. Level 1 isolation makes every service look like it is in Platform RoT as there is no distinction.

    We have made such a Platform RoT service, so you should be able to create a custom ARoT-service that can read out UICR using the same methodology as NS world would use. You will have to read the memory using the tfm_platform_mem_read functions:

    https://github.com/nrfconnect/sdk-trusted-firmware-m/blob/5454e8edfcb240e564405cc92708716e5846770c/platform/ext/target/nordic_nrf/common/core/services/include/tfm_ioctl_core_api.h#L88

    But before you do that, you will have to add all the addresses that you want to be able to read in the memory range header file:

    https://github.com/nrfconnect/sdk-nrf/blob/main/modules/trusted-firmware-m/tfm_boards/services/include/tfm_read_ranges.h

    Note that the tfm_platform_mem_read service doesn't differentiate between NS or S service calls. If you add it in the tfm_read_ranges.h, then the NS-world would be able to request the same information

    -Amanda H.

  • I was trying to do the same thing but accessing OTP in NS, and I ended up implementing it this way. Here is my patch (for ncs v2.5.2)

    diff --git a/modules/tfm/tfm/boards/services/include/tfm_read_ranges.h b/modules/tfm/tfm/boards/services/include/tfm_read_ranges.h
    index 2f95b4eb7..56b366211 100644
    --- a/modules/tfm/tfm/boards/services/include/tfm_read_ranges.h
    +++ b/modules/tfm/tfm/boards/services/include/tfm_read_ranges.h
    @@ -41,6 +41,15 @@
     
     #endif /* NRF_FICR_S_BASE */
     
    +#ifdef NRF_UICR_S_BASE
    +
    +#define UICR_BASE              NRF_UICR_S_BASE
    +
    +#define UICR_OTP_ADDR          (UICR_BASE + offsetof(NRF_UICR_Type, OTP))
    +#define UICR_OTP_SIZE          (sizeof(((NRF_UICR_Type *)0)->OTP))
    +
    +#endif /* NRF_UICR_S_BASE */
    +
     static const struct tfm_read_service_range ranges[] = {
     #ifdef PM_MCUBOOT_ADDRESS
            /* Allow reads of mcuboot metadata */
    @@ -61,6 +70,9 @@ static const struct tfm_read_service_range ranges[] = {
     #if defined(FICR_SIPINFO_ADDR)
            { .start = FICR_SIPINFO_ADDR, .size = FICR_SIPINFO_SIZE },
     #endif
    +#if defined(UICR_OTP_ADDR)
    +       { .start = UICR_OTP_ADDR, .size = UICR_OTP_SIZE },
    +#endif
     };
     
     #endif /* TFM_READ_RANGES_H__ */

    I have no idea if Nordic will support this in their SDK (perhaps hidden behind a Kconfig option?). And I'm not sure if they will accept a PR from a non-employee.

Related