TF-M partition alignment assert within SPU might fail for some partition-manager computed configs

v2.3.0 of the sdk-nrf included this commit that checks for the alignment of the TF-M Non Secure partition (which hosts the `app` one) with CONFIG_NRF_SPU_FLASH_REGION_SIZE .

#define IS_ALIGNED_POW2(value, align) (((value) & ((align) - 1)) == 0)

#if !(IS_ALIGNED_POW2(PM_TFM_NONSECURE_ADDRESS, CONFIG_NRF_SPU_FLASH_REGION_SIZE))
#error "TF-M non-secure address start is not aligned on SPU region size"
#endif

For stock/most cases (eg. hello_world code), the assertion holds and the project compiles. 

The problem arouses when the partition_manager.py script outputs a layout solution in which the resulting PM_TFM_NONSECURE_ADDRESS becomes non-aligned. This has been my experience with the current project that I'm working on.

To temporarily mitigate this, I ended up taking out the alignment assertion check altogether. 

Is this a safe thing to do or is there any other better solution to this?

Thank you,

V

  • Hi,

     

    On the nRF5340, each flash protect region is 16kB aligned:

    https://infocenter.nordicsemi.com/topic/ps_nrf5340/spu.html?cp=4_0_0_6_31_1#flash_access_control

    If your partitions do not align on 16kB regions, you must disable the CONFIG_FPROTECT in addition to the change that you have already done.

     

    Is this a safe thing to do or is there any other better solution to this?

    Disabling the FPROTECT has its drawbacks, security-wise, so if possible; I would recommend that you keep FPROTECT enabled and rather align your partitions in pm_static.yml in such a way that it passes this specific test.

     

    Are you creating FOTA images for a product out in the field?

    Update 24th of March:

    My initial striked out comment is incorrect. This 16k (32k for nRF9160) alignment is based on the "app" region, which holds both the TFM image and the non-secure application.

    Mcuboot will see the TFM+non_secure application as one whole section. This means that all FOTA images can be dynamically aligned for TFM+non_secure-app, and thus be able to use FPROTECT. 

     

    Kind regards,

    Håkon

  • I'll add that I am also running into this issue building for the NRF9160 after updating to v2.3.0 from v2.2.0.

    For more information I'm building for the Circuit Dojo NRF9160 Feather. I'm using all upstream partition sizes with no app specific configs or overrides.

  • Thank you for the reply, Håkon!

    Yes, we are planning on doing fota-s, but have not yet shipped the initial version. We are striving to have FPROTECT on since the device is considered a high-security, critical, application.

    It would be nice if the partition_manage.py script would be aware of this alignment constraint and generate solutions accordingly. As it is now, I do see it causing issues for others: outputting a valid layout config while failing the SPU alignment guard.

  • Hi,

     

    3Nigma said:
    Yes, we are planning on doing fota-s, but have not yet shipped the initial version. We are striving to have FPROTECT on since the device is considered a high-security, critical, application.

    Could you share your pm_static.yml (or the build/partitions.yml) file?

     

    3Nigma said:
    It would be nice if the partition_manage.py script would be aware of this alignment constraint and generate solutions accordingly. As it is now, I do see it causing issues for others: outputting a valid layout config while failing the SPU alignment guard.

    I will report this internally, and make the developers aware of this.

     

    Kind regards,

    Håkon

  • Sure! Here is the partitions.yml file:

    EMPTY_0:
      address: 0xff00
      end_address: 0x10000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0x100
    app:
      address: 0x20200
      end_address: 0x100000
      region: flash_primary
      size: 0xdfe00
    external_flash:
      address: 0x8f2000
      end_address: 0x1000000
      region: external_flash
      size: 0x70e000
    littlefs_storage:
      address: 0xf2000
      device: DT_CHOSEN(nordic_pm_ext_flash)
      end_address: 0x8f2000
      placement:
        before:
        - tfm_storage
        - end
      region: external_flash
      size: 0x800000
    mcuboot:
      address: 0x0
      end_address: 0xff00
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xff00
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10200
      placement:
        align:
          start: 0x4000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0x10000
      end_address: 0x100000
      orig_span: &id001
      - mcuboot_pad
      - app
      - tfm
      region: flash_primary
      size: 0xf0000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x100000
      orig_span: &id002
      - app
      - tfm
      region: flash_primary
      size: 0xefe00
      span: *id002
    mcuboot_secondary:
      address: 0x0
      device: DT_CHOSEN(nordic_pm_ext_flash)
      end_address: 0xf0000
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0xf0000
    mcuboot_sram:
      address: 0x20000000
      end_address: 0x20008000
      orig_span: &id003
      - tfm_sram
      region: sram_primary
      size: 0x8000
      span: *id003
    otp:
      address: 0xff8100
      end_address: 0xff83fc
      region: otp
      size: 0x2fc
    rpmsg_nrf53_sram:
      address: 0x20070000
      end_address: 0x20080000
      placement:
        before:
        - end
      region: sram_primary
      size: 0x10000
    settings_storage:
      address: 0xf0000
      device: DT_CHOSEN(nordic_pm_ext_flash)
      end_address: 0xf2000
      inside:
      - nonsecure_storage
      placement:
        before:
        - tfm_storage
        - end
      region: external_flash
      size: 0x2000
    sram_nonsecure:
      address: 0x20008000
      end_address: 0x20080000
      orig_span: &id004
      - sram_primary
      - rpmsg_nrf53_sram
      region: sram_primary
      size: 0x78000
      span: *id004
    sram_primary:
      address: 0x20008000
      end_address: 0x20070000
      region: sram_primary
      size: 0x68000
    sram_secure:
      address: 0x20000000
      end_address: 0x20008000
      orig_span: &id005
      - tfm_sram
      region: sram_primary
      size: 0x8000
      span: *id005
    tfm:
      address: 0x10200
      end_address: 0x20200
      inside:
      - mcuboot_primary_app
      placement:
        before:
        - app
      region: flash_primary
      size: 0x10000
    tfm_nonsecure:
      address: 0x20200
      end_address: 0x100000
      orig_span: &id006
      - app
      region: flash_primary
      size: 0xdfe00
      span: *id006
    tfm_secure:
      address: 0x10000
      end_address: 0x20200
      orig_span: &id007
      - mcuboot_pad
      - tfm
      region: flash_primary
      size: 0x10200
      span: *id007
    tfm_sram:
      address: 0x20000000
      end_address: 0x20008000
      inside:
      - sram_secure
      placement:
        after:
        - start
      region: sram_primary
      size: 0x8000
    

    Thank you once again,

    Take care,

    V

Related