Hi,
I am working on an update from TF-M 1.8.1 to TF-M 2.1.1 on a board that uses encrypted Protected Storage. The board used is stm32 b_u585i_iot02a, NSPE side using Zephyr OS. I want to support field updates as well for devices already having Protected Storage objects created from NSPE. In my case, Protected Storage is created and used by TF-M 1.8.1, and I want it to remain functional after upgrading to TF-M 2.1.1. PS_CRYPTO_AEAD_ALG is set to (default) PSA_ALG_GCM.
I have faced two issues with the uplift:
1. It seems commit ffd13c3 ( https://github.com/TrustedFirmware-M/trusted-firmware-m/commit/ffd13c31d5e6f...) has changed the layout how Protected Storage objects are stored into flash. With TF-M 2.1.1 and old PS data, PS init fails (or gets recreated if PS_CREATE_FLASH_LAYOUT, which I don't want since then all the existing objects would get erased). If I revert the commit (and https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... as not to have conflicts), then the PS initialization can pass and objects are decrypted successfully.
I have not been able to understand this thoroughly, but at least change in `union ps_crypto_t` struct member order is changing padding (sizeof 48 -> 40), and that in turn seems to shift at least additional data by 8 bytes via `#define PS_NON_AUTH_OBJ_TABLE_SIZE sizeof(union ps_crypto_t)`. Is this compatibility issue "a bug" in 2.1.1 or expected by design?
2. PS objects in 1.8.1 were storing client id to the object table entry to implement access control (?). With 1.8.1, the client id that got stored was -1. With 2.1.1, likely due to the Mailbox NS Agent Design Update ( https://tf-m-user-guide.trustedfirmware.org/design_docs/dual-cpu/mailbox_ns_...), non-secure requests to get an object seems to pass client ID -0x3c000000 to the Protected Storage implementation. That is, client id -1 seems to be transformed to `client_id_limit`. Due to this, `psa_ps_get_info()` fails to get an object that has been previously made with 1.8.1 FW.
I am able to get reading of old stored objects working by changing `client_id_limit` from value -0x3c000000 to -1 which changes to use 1-to-1 mapping when using client_id=-1. But I am unsure if this change causes some unwanted side effects. Is this the correct way to gain backwards compatibility? And if it is, would it make sense to pick https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... into 2.1.x branch and add a configuration flag for the 1-to-1 mapping support without code change for backwards compatibility?
Thanks, Miika
Hi Miika,
A Client ID mapping was changed for support hybrid platforms. If your platform is not hybrid than it’s safe to use previous mapping. Mate Toth-Pal presented hybrid platform design in a TF-M Tech Forum on April 11, 2024: https://www.trustedfirmware.org/meetings/tf-m-technical-forum/
Hope that helps, Anton
From: Miika Karanki via TF-M tf-m@lists.trustedfirmware.org Sent: Wednesday, November 27, 2024 11:53 AM To: tf-m@lists.trustedfirmware.org Subject: [TF-M] Backwards compatibility of Protected Storage implementation (TF-M 1.8.1 -> 2.1.1)
Hi,
I am working on an update from TF-M 1.8.1 to TF-M 2.1.1 on a board that uses encrypted Protected Storage. The board used is stm32 b_u585i_iot02a, NSPE side using Zephyr OS. I want to support field updates as well for devices already having Protected Storage objects created from NSPE. In my case, Protected Storage is created and used by TF-M 1.8.1, and I want it to remain functional after upgrading to TF-M 2.1.1. PS_CRYPTO_AEAD_ALG is set to (default) PSA_ALG_GCM.
I have faced two issues with the uplift:
1. It seems commit ffd13c3 (https://github.com/TrustedFirmware-M/trusted-firmware-m/commit/ffd13c31d5e6f...) has changed the layout how Protected Storage objects are stored into flash. With TF-M 2.1.1 and old PS data, PS init fails (or gets recreated if PS_CREATE_FLASH_LAYOUT, which I don't want since then all the existing objects would get erased). If I revert the commit (and https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... as not to have conflicts), then the PS initialization can pass and objects are decrypted successfully.
I have not been able to understand this thoroughly, but at least change in `union ps_crypto_t` struct member order is changing padding (sizeof 48 -> 40), and that in turn seems to shift at least additional data by 8 bytes via `#define PS_NON_AUTH_OBJ_TABLE_SIZE sizeof(union ps_crypto_t)`. Is this compatibility issue "a bug" in 2.1.1 or expected by design?
2. PS objects in 1.8.1 were storing client id to the object table entry to implement access control (?). With 1.8.1, the client id that got stored was -1. With 2.1.1, likely due to the Mailbox NS Agent Design Update (https://tf-m-user-guide.trustedfirmware.org/design_docs/dual-cpu/mailbox_ns_...), non-secure requests to get an object seems to pass client ID -0x3c000000 to the Protected Storage implementation. That is, client id -1 seems to be transformed to `client_id_limit`. Due to this, `psa_ps_get_info()` fails to get an object that has been previously made with 1.8.1 FW.
I am able to get reading of old stored objects working by changing `client_id_limit` from value -0x3c000000 to -1 which changes to use 1-to-1 mapping when using client_id=-1. But I am unsure if this change causes some unwanted side effects. Is this the correct way to gain backwards compatibility? And if it is, would it make sense to pick https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... into 2.1.x branch and add a configuration flag for the 1-to-1 mapping support without code change for backwards compatibility?
Thanks, Miika
Hi Miika,
Unfortunately there have been a couple of changes to the way that PS data is stored in flash. I hope that we are getting better at considering backwards compatibility. In general I think that whenever we do introduce a change like this, we need to ensure that data stored with the old layout can still be read by newer code.
I believe the patch that you’ve identified was part of the work to make PS encryption optional. Looking at it now, I don’t see that the layout was a necessary part of that work. Unfortunately, we’re now in a position where there could be PS data stored on devices in this new format, so just reverting that part of that patch would cause other problems.
The bad news is that there’s another stored format change post-v2.1.1. The good news is that we did think about existing data and introduced a build option to read the old format.
One solution to your problem would be similar to https://github.com/TrustedFirmware-M/trusted-firmware-m/commit/e8d48d78c166c... - a build option to support reading the old format, with stores then using the new format. Another option would be to introduce the 1.8.1 format as an alternative implementation i.e. a second struct inside union ps_crypto_t and provide the 1.8.1 code as well as the current code (this would mean picking a storage format at build time and using it forever).
Regarding the client_id. You’re correct that the client_id is used as a kind of access control (the client_id and UID together identify the stored object). Yes, there was a major change to the way that client_ids are used, with the mapping being added. Do you have TFM_NS_MANAGE_NSID set to ON? I believe that if it is set to OFF then -1 is used inside TF-M to represent all non-secure clients, which sounds like it may be what you need.
Chris
From: Miika Karanki via TF-M tf-m@lists.trustedfirmware.org Sent: Wednesday, November 27, 2024 3:53 AM To: tf-m@lists.trustedfirmware.org Subject: [TF-M] Backwards compatibility of Protected Storage implementation (TF-M 1.8.1 -> 2.1.1)
Caution: This e-mail originated outside Infineon Technologies. Please be cautious when sharing information or opening attachments especially from unknown senders. Refer to our intranet guidehttps://intranet-content.infineon.com/explore/aboutinfineon/rules/informationsecurity/ug/SocialEngineering/Pages/SocialEngineeringElements_en.aspx to help you identify Phishing email.
Hi,
I am working on an update from TF-M 1.8.1 to TF-M 2.1.1 on a board that uses encrypted Protected Storage. The board used is stm32 b_u585i_iot02a, NSPE side using Zephyr OS. I want to support field updates as well for devices already having Protected Storage objects created from NSPE. In my case, Protected Storage is created and used by TF-M 1.8.1, and I want it to remain functional after upgrading to TF-M 2.1.1. PS_CRYPTO_AEAD_ALG is set to (default) PSA_ALG_GCM.
I have faced two issues with the uplift:
1. It seems commit ffd13c3 (https://github.com/TrustedFirmware-M/trusted-firmware-m/commit/ffd13c31d5e6f...) has changed the layout how Protected Storage objects are stored into flash. With TF-M 2.1.1 and old PS data, PS init fails (or gets recreated if PS_CREATE_FLASH_LAYOUT, which I don't want since then all the existing objects would get erased). If I revert the commit (and https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... as not to have conflicts), then the PS initialization can pass and objects are decrypted successfully.
I have not been able to understand this thoroughly, but at least change in `union ps_crypto_t` struct member order is changing padding (sizeof 48 -> 40), and that in turn seems to shift at least additional data by 8 bytes via `#define PS_NON_AUTH_OBJ_TABLE_SIZE sizeof(union ps_crypto_t)`. Is this compatibility issue "a bug" in 2.1.1 or expected by design?
2. PS objects in 1.8.1 were storing client id to the object table entry to implement access control (?). With 1.8.1, the client id that got stored was -1. With 2.1.1, likely due to the Mailbox NS Agent Design Update (https://tf-m-user-guide.trustedfirmware.org/design_docs/dual-cpu/mailbox_ns_...), non-secure requests to get an object seems to pass client ID -0x3c000000 to the Protected Storage implementation. That is, client id -1 seems to be transformed to `client_id_limit`. Due to this, `psa_ps_get_info()` fails to get an object that has been previously made with 1.8.1 FW.
I am able to get reading of old stored objects working by changing `client_id_limit` from value -0x3c000000 to -1 which changes to use 1-to-1 mapping when using client_id=-1. But I am unsure if this change causes some unwanted side effects. Is this the correct way to gain backwards compatibility? And if it is, would it make sense to pick https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/... into 2.1.x branch and add a configuration flag for the 1-to-1 mapping support without code change for backwards compatibility?
Thanks, Miika
tf-m@lists.trustedfirmware.org