Skip to content

Conversation

@petejohanson-adi
Copy link
Contributor

Where possible (i.e. not running in NS), erase the flash before testing the write once secure storage API.

This is based on feedback here: #97529 (review)

Note: This does not help with NS targets that can't directly access the flash and erase it. @tomi-font I'd really appreciate if you could offer some ideas for how to address that problem other than the one proposed in #97529

Where possible (i.e. not running in NS), erase the flash before testing the
write once secure storage API.

Signed-off-by: Pete Johanson <[email protected]>
@zephyrbot zephyrbot added area: Secure Storage Secure Storage area: Tests Issues related to a particular existing or missing test labels Nov 19, 2025
@dsseng
Copy link
Member

dsseng commented Nov 19, 2025

Are NS targets even supposed to use secure_storage? I believe if you cannot access the flash from NS, then you would typically use PSA ITS/PS provided by the secure world, thus not needing Zephyr's implementation

@petejohanson-adi
Copy link
Contributor Author

In our particular case, we have a possible convoluted path of secure_storage -> settings -> settings ITS backend.

@sonarqubecloud
Copy link

#if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE)
const struct flash_parameters *fparam = flash_get_parameters(fdev);

if (!(flash_params_get_erase_cap(fparam) & FLASH_ERASE_C_EXPLICIT)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in case we have no erase operation (e.g. nRF54 RRAM and MRAM) we should fully overwrite the region with zeroes or ones? That would also erase the data to make sure we start from a known-empty state.

native_sim can also simulate such NVM model IIRC, so it should be testable even without such HW.


for (int i = 0; i < MAX_NUM_PAGES && address < FLASH_ERASE_END_ADDR; i++) {
rc = flash_get_page_info_by_offs(fdev, address, &page_info);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking nit to unify the code style here

Suggested change

@dsseng
Copy link
Member

dsseng commented Nov 19, 2025

In our particular case, we have a possible convoluted path of secure_storage -> settings -> settings ITS backend.

Yes, nothing prevents this from working, but perhaps only running this test without TF-M is sufficient for the coverage purposes

Copy link
Contributor

@tomi-font tomi-font left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsseng is right in that NS targets are not meant to use Secure Storage:

menuconfig SECURE_STORAGE
bool "Secure storage subsystem"
depends on !BUILD_WITH_TFM
However this test has a scenario for TF-M in order to test API compatibility between TF-M and Secure Storage (as all the test does is use the PSA ITS API):
secure_storage.psa.its.tfm:
filter: CONFIG_BUILD_WITH_TFM
integration_platforms:
- nrf9151dk/nrf9151/ns
extra_args: EXTRA_CONF_FILE=overlay-tfm.conf
So it makes sense to also consider TF-M here.

In our particular case, we have a possible convoluted path of secure_storage -> settings -> settings ITS backend.

This is really weird... Can you tell me more about your use case? Why wouldn't you just directly be using the PSA ITS API exposed by TF-M, and how can you even manage to do this as there must be symbol clashes?

Other than that, thanks for the PR, I tested and it works on the nRF9151 and on native_sim with the Settings backend. Although not:

  • On the nRF54L15, probably because of https://github.com/zephyrproject-rtos/zephyr/pull/99701/files#r2543678217; could you also make it work there?
  • With the ZMS backend. In that case (on native_sim) the return value of psa_its_get_info() is not PSA_SUCCESS, which makes the test fail. This is maybe because the erase operation messes up ZMS or that the mounting needs to be done after erasing the flash:
    static int init_zms(void)
    {
    int ret;
    s_zms.sector_count = FIXED_PARTITION_NODE_SIZE(PARTITION_DT_NODE) / s_zms.sector_size;
    ret = zms_mount(&s_zms);
    if (ret) {
    LOG_DBG("Failed. (%d)", ret);
    }
    return ret;
    }
    SYS_INIT(init_zms, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
    Maybe having the flash erase as a SYS_INIT() hook that would run before that of ZMS would work.

Note: This does not help with NS targets that can't directly access the flash and erase it. @tomi-font I'd really appreciate if you could offer some ideas for how to address that problem other than the one proposed in #97529

I'm afraid there's no way around that, for NS targets you will just need to run twister/west with the erase option. It would be a pretty big security hole if the NS application could just erase parts of the secure flash. I mean I imagine it must be possible some way to achieve that but it must be all but trivial.


#if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE)

#define MAX_NUM_PAGES 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did you come up with this value? Is it even needed?

}
}

#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#endif /* !CONFIG_BUILD_WITH_TFM && CONFIG_FLASH_HAS_EXPLICIT_ERASE */

if (!(flash_params_get_erase_cap(fparam) & FLASH_ERASE_C_EXPLICIT)) {
return;
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#endif /* CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE */

@dsseng
Copy link
Member

dsseng commented Nov 20, 2025

I'm afraid there's no way around that, for NS targets you will just need to run twister/west with the erase option. It would be a pretty big security hole if the NS application could just erase parts of the secure flash. I mean I imagine it must be possible some way to achieve that but it must be all but trivial.

Can be potentially hacked around by making TF-M skip setting security attributes to the flash controller (needs a test-specific patch). It's still not really worth it for the test though it seems.

And on properly secured hardware that's the goal of TF-M to prevent NSPE from accessing Secure hardware, so there's no universal solution without hacking on TF-M.

@petejohanson-adi I still fail to grasp what do you test in such a case? If you use Secure Storage, then it writes to somewhere accessible from NSPE, right? Then that region should also be erasable/rewriteable by NSPE.

If you meant Secure Storage on top of ITS provided by TF-M (yes, I now realized it shouldn't even compile due to TF-M runtime library providing the same symbol names as secure_storage), please take a look here, maybe you should wipe ITS entries, and not the backing Flash: https://github.com/zephyrproject-rtos/zephyr/pull/94881/files#diff-93455f3e147570503f332b1446633676ffb36a58f958179f334273ca6b30c78e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Secure Storage Secure Storage area: Tests Issues related to a particular existing or missing test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants