| ########################################### |
| Protected Storage Service Integration Guide |
| ########################################### |
| |
| ************ |
| Introduction |
| ************ |
| TF-M Protected Storage (PS) service implements PSA Protected Storage APIs. |
| |
| The service is backed by hardware isolation of the flash access domain and, in |
| the current version, relies on hardware to isolate the flash area from |
| non-secure access. In absence of hardware level isolation, the secrecy and |
| integrity of data is still maintained. |
| |
| The PS service implements an AES-GCM based AEAD encryption policy, as a |
| reference, to protect data integrity and authenticity. |
| |
| PS reuses the non-hierarchical filesystem provided by the TF-M Internal Trusted |
| Storage service to store encrypted, authenticated objects on the external flash |
| device. |
| |
| The design addresses the following high level requirements as well: |
| |
| - **Confidentiality** - Resistance to unauthorised accesses through |
| hardware/software attacks. |
| |
| - **Access Authentication** - Mechanism to establish requester's identity (a |
| non-secure entity, secure entity, or a remote server). |
| |
| - **Integrity** - Resistant to tampering by either the normal users of a product, |
| package, or system or others with physical access to it. If the content of the |
| protected storage is changed maliciously, the service is able to detect it. |
| |
| - **Reliability** - Resistant to power failure scenarios and incomplete write |
| cycles. |
| |
| - **Configurability** - High level configurability to scale up/down memory |
| footprint to cater for a variety of devices with varying security |
| requirements. |
| |
| - **Performance** - Optimized to be used for resource constrained devices with |
| very small silicon footprint, the PPA (power, performance, area) should be |
| optimal. |
| |
| ****************************** |
| Current PS Service Limitations |
| ****************************** |
| - **Fragmentation** - The current design does not support fragmentation, as an |
| asset is stored in a contiguous space in a block. This means that the maximum |
| asset size can only be up-to a block size. Detailed information about the |
| maximum asset size can be found in the section `Maximum asset size` below. |
| Each block can potentially store multiple assets. |
| A delete operation implicitly moves all the assets towards the top of the block |
| to avoid fragmentation within block. However, this may also result in |
| unutilized space at the end of each block. |
| |
| - **Asset size limitation** - An asset is stored in a contiguous space in a |
| block/sector. Hence, the maximum asset size can be up-to the size of the |
| data block/sector. Detailed information about the maximum asset size can be |
| found in the section `Maximum asset size` below. |
| |
| - **Non-hierarchical storage model** - The current design uses a |
| non-hierarchical storage model, as a filesystem, where all the assets are |
| managed by a linearly indexed list of metadata. This model locates the |
| metadata in blocks which are always stored in the same flash location. That |
| increases the number of writes in a specific flash location as every change in |
| the storage area requires a metadata update. |
| |
| - **PSA internal trusted storage API** - In the current design, the service does |
| not use the PSA Internal Trusted Storage API to write the rollback protection |
| values stored in the internal storage. |
| |
| - **Protection against physical storage medium failure** - Complete handling of |
| inherent failures of storage mediums (e.g. bad blocks in a NAND based device) |
| is not supported by the current design. |
| |
| - **Key diversification** - In a more robust design, each asset would be |
| encrypted through a different key. |
| |
| - **Lifecycle management** - Currently, it does not support any subscription |
| based keys and certificates required in a secure lifecycle management. Hence, |
| an asset's validity time-stamp can not be invalidated based on the system |
| time. |
| |
| - **Provisioning vs user/device data** - In the current design, all assets are |
| treated in the same manner. In an alternative design, it may be required to |
| create separate partitions for provisioning content and user/device generated |
| content. This is to allow safe update of provisioning data during firmware |
| updates without the need to wipe out the user/device generated data. |
| |
| ************** |
| Code Structure |
| ************** |
| Protected storage service code is located in |
| ``secure_fw/partitions/protected_storage/`` and is divided as follows: |
| |
| - Core files |
| - Cryptographic interfaces |
| - Non-volatile (NV) counters interfaces |
| |
| The PSA PS interfaces for PS service are located in ``interface/include/psa`` |
| |
| PSA Protected Storage Interfaces |
| ================================ |
| |
| The PS service exposes the following mandatory PSA PS interfaces, version 1.0: |
| |
| .. code-block:: c |
| |
| psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags); |
| psa_status_t psa_ps_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size, void *p_data, size_t *p_data_length); |
| psa_status_t psa_ps_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info); |
| psa_status_t psa_ps_remove(psa_storage_uid_t uid); |
| uint32_t psa_ps_get_support(void); |
| |
| For the moment, it does not support the extended version of those APIs. |
| |
| These PSA PS interfaces and PS TF-M types are defined and documented in |
| ``interface/include/psa/protected_storage.h``, |
| ``interface/include/psa/storage_common.h`` and |
| ``interface/include/tfm_ps_defs.h`` |
| |
| Core Files |
| ========== |
| - ``tfm_ps_req_mngr.c`` - Contains the PS request manager implementation which |
| handles all requests which arrive to the service. This layer extracts the |
| arguments from the input and output vectors, and it calls the protected |
| storage layer with the provided parameters. |
| |
| - ``tfm_protected_storage.c`` - Contains the TF-M protected storage API |
| implementations which are the entry points to the PS service. |
| |
| - ``ps_object_system.c`` - Contains the object system implementation to manage |
| all objects in PS area. |
| |
| - ``ps_object_table.c`` - Contains the object system table implementation which |
| complements the object system to manage all object in the PS area. |
| The object table has an entry for each object stored in the object system |
| and keeps track of its version and owner. |
| |
| - ``ps_encrypted_object.c`` - Contains an implementation to manipulate |
| encrypted objects in the PS object system. |
| |
| - ``ps_utils.c`` - Contains common and basic functionalities used across the |
| PS service code. |
| |
| Flash Filesystem and Flash Interfaces |
| ===================================== |
| The PS service reuses the non-hierarchical filesystem and flash interfaces |
| provided by the TF-M Internal Trusted Storage service. It stores encrypted, |
| authenticated objects on the external flash device by making service calls to |
| the ITS service. When the ITS service receives requests from the PS partition, |
| it handles the request by using a separate filesystem context initialised to use |
| the external flash device. |
| |
| The ITS filesystem and flash interfaces and their implementation can be found in |
| ``secure_fw/partitions/internal_trusted_storage/flash_fs`` and |
| ``secure_fw/partitions/internal_trusted_storage/flash`` respectively. More |
| information about the filesystem and flash interfaces can be found in the |
| :doc:`ITS integration guide |
| </docs/reference/services/tfm_its_integration_guide>`. |
| |
| The ITS service implementation in |
| ``secure_fw/partitions/internal_trusted_storage/tfm_internal_trusted_storage.c``, |
| constructs a filesystem configuration for Protected Storage based on |
| target-specific definitions from the Protected Storage HAL. Please see the |
| `Protected Storage Service HAL` section for details of these. |
| |
| Cryptographic Interface |
| ======================= |
| - ``crypto/ps_crypto_interface.h`` - Abstracts the cryptographic operations for |
| the protected storage service. |
| |
| - ``crypto/ps_crypto_interface.c`` - Implements the PS service cryptographic |
| operations with calls to the TF-M Crypto service. |
| |
| Non-volatile (NV) Counters Interface |
| ==================================== |
| The current PS service provides rollback protection based on NV |
| counters. |
| PS defines and implements the following NV counters functionalities: |
| |
| - ``nv_counters/ps_nv_counters.h`` - Abstracts PS non-volatile |
| counters operations. This API detaches the use of NV counters from the TF-M NV |
| counters implementation, provided by the platform, and provides a mechanism to |
| compile in a different API implementation for test purposes. A PS test suite |
| **may** provide its own custom implementation to be able to test different PS |
| service use cases. |
| |
| - ``nv_counters/ps_nv_counters.c`` - Implements the PS NV counters interfaces |
| based on TF-M NV counters implementation provided by the platform. |
| |
| **************************** |
| PS Service Integration Guide |
| **************************** |
| This section describes mandatory (i.e. **must** implement) or optional |
| (i.e. **may** implement) interfaces which the system integrator have to take |
| in to account in order to integrate the protected storage service in a new |
| platform. |
| |
| Maximum Asset Size |
| ================== |
| An asset is stored in a contiguous space in a block/sector. The maximum |
| size of an asset can be up-to the size of the data block/sector minus the object |
| header size (``PS_OBJECT_HEADER_SIZE``) which is defined in |
| ``ps_object_defs.h``. The ``PS_OBJECT_HEADER_SIZE`` changes based on the |
| ``PS_ENCRYPTION`` flag status. |
| |
| Protected Storage Service HAL |
| ============================= |
| The PS service requires the platform to implement the PS HAL, defined in |
| ``platform/include/tfm_hal_ps.h``. |
| |
| The following C definitions in the HAL are mandatory, and must be defined by the |
| platform in a header named ``flash_layout.h``: |
| |
| - ``TFM_HAL_PS_FLASH_DRIVER`` - Defines the identifier of the CMSIS Flash |
| ARM_DRIVER_FLASH object to use for PS. It must have been allocated by the |
| platform and will be declared extern in the HAL header. |
| |
| - ``TFM_HAL_PS_PROGRAM_UNIT`` - Defines the size of the PS flash device's |
| physical program unit (the smallest unit of data that can be individually |
| programmed to flash). It must be equal to |
| ``TFM_HAL_PS_FLASH_DRIVER.GetInfo()->program_unit``, but made available at |
| compile time so that filesystem structures can be statically sized. Valid |
| values are powers of two between 1 and the flash sector size, inclusive. |
| |
| The following C definitions in the HAL may optionally be defined by the platform |
| in the ``flash_layout.h`` header: |
| |
| - ``TFM_HAL_PS_FLASH_AREA_ADDR`` - Defines the base address of the dedicated |
| flash area for PS. |
| |
| - ``TFM_HAL_PS_FLASH_AREA_SIZE`` - Defines the size of the dedicated flash area |
| for PS in bytes. |
| |
| - ``TFM_HAL_PS_SECTORS_PER_BLOCK`` - Defines the number of contiguous physical |
| flash erase sectors that form a logical erase block in the filesystem. The |
| typical value is ``1``, but it may be increased so that the maximum required |
| asset size will fit in one logical block. |
| |
| If any of the above definitions are not provided by the platform, then the |
| ``tfm_hal_ps_fs_info()`` HAL API must be implemented instead. This function is |
| documented in ``tfm_hal_ps.h``. |
| |
| The sectors reserved to be used for Protected Storage **must** be contiguous |
| sectors starting at ``TFM_HAL_PS_FLASH_AREA_ADDR``. |
| |
| The design requires either 2 blocks, or any number of blocks greater than or |
| equal to 4. Total number of blocks can not be 0, 1 or 3. This is a design choice |
| limitation to provide power failure safe update operations. |
| |
| Protected Storage Service Optional Platform Definitions |
| ======================================================= |
| The following optional platform definitions may be defined in |
| ``flash_layout.h``: |
| |
| - ``PS_RAM_FS_SIZE`` - Defines the size of the RAM FS buffer when using the |
| RAM FS emulated flash implementation. The buffer must be at least as large as |
| the area earmarked for the filesystem by the HAL. |
| - ``PS_FLASH_NAND_BUF_SIZE`` - Defines the size of the write buffer when using |
| the NAND flash implementation. The buffer must be at least as large as a |
| logical filesystem block. |
| |
| More information about the ``flash_layout.h`` content, not PS related, is |
| available in :doc:`platform readme </platform/ext/readme>` along with other |
| platform information. |
| |
| TF-M NV Counter Interface |
| ========================= |
| To have a platform independent way to access the NV counters, TF-M defines a |
| platform NV counter interface. For API specification, please check: |
| ``platform/include/tfm_plat_nv_counters.h`` |
| |
| The system integrators **may** implement this interface based on the target |
| capabilities and set the ``PS_ROLLBACK_PROTECTION`` flag to compile in |
| the rollback protection code. |
| |
| Secret Platform Unique Key |
| ========================== |
| The encryption policy relies on a secret hardware unique key (HUK) per device. |
| It is system integrator's responsibility to provide an implementation which |
| **must** be a non-mutable target implementation. |
| For API specification, please check: |
| ``platform/include/tfm_plat_crypto_keys.h`` |
| |
| A stub implementation is provided in |
| ``platform/ext/common/template/crypto_keys.c`` |
| |
| Non-Secure Identity Manager |
| =========================== |
| TF-M core tracks the current client IDs running in the secure or non-secure |
| processing environment. It provides a dedicated API to retrieve the client ID |
| which performs the service request. |
| |
| :doc:`NS client identification documentation </docs/getting_started/tfm_ns_client_identification>` |
| provides further details on how client identification works. |
| |
| PS service uses that TF-M core API to retrieve the client ID and associate it |
| as the owner of an asset. Only the owner can read, write or delete that asset |
| based on the creation flags. |
| |
| The :doc:`integration guide </docs/getting_started/tfm_integration_guide>` |
| provides further details of non-secure implementation requirements for TF-M. |
| |
| Cryptographic Interface |
| ======================= |
| The reference encryption policy is built on AES-GCM, and it **may** be replaced |
| by a vendor specific implementation. |
| |
| The PS service abstracts all the cryptographic requirements and specifies the |
| required cryptographic interface in |
| ``secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.h`` |
| |
| The PS service cryptographic operations are implemented in |
| ``secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c``, using |
| calls to the TF-M Crypto service. |
| |
| PS Service Build Definitions |
| ============================ |
| The PS service uses a set of C definitions to compile in/out certain features, |
| as well as to configure certain service parameters. When using the TF-M build |
| system, these definitions are controlled by build flags of the same name. The |
| ``config/config_default.cmake`` file sets the default values of those flags, but |
| they can be overwritten based on platform capabilities by setting them in |
| ``platform/ext/target/<TARGET_NAME>/config.cmake``. The list of PS service build |
| definitions is: |
| |
| - ``PS_ENCRYPTION``- this flag allows to enable/disable encryption |
| option to encrypt the protected storage data. |
| - ``PS_CREATE_FLASH_LAYOUT``- this flag indicates that it is required |
| to create a PS flash layout. If this flag is set, PS service will |
| generate an empty and valid PS flash layout to store assets. It will |
| erase all data located in the assigned PS memory area before generating |
| the PS layout. This flag is required to be set if the PS memory area |
| is located in a non-persistent memory. This flag can be set if the PS |
| memory area is located in a persistent memory without a valid PS flash |
| layout in it. That is the case when it is the first time in the device |
| life that the PS service is executed. |
| - ``PS_VALIDATE_METADATA_FROM_FLASH``- this flag allows to |
| enable/disable the validation mechanism to check the metadata store in flash |
| every time the flash data is read from flash. This validation is required |
| if the flash is not hardware protected against malicious writes. In case |
| the flash is protected against malicious writes (i.e embedded flash, etc), |
| this validation can be disabled in order to reduce the validation overhead. |
| - ``PS_ROLLBACK_PROTECTION``- this flag allows to enable/disable |
| rollback protection in protected storage service. This flag takes effect only |
| if the target has non-volatile counters and ``PS_ENCRYPTION`` flag is on. |
| - ``PS_RAM_FS``- setting this flag to ``ON`` enables the use of RAM instead of |
| the persistent storage device to store the FS in the Protected Storage |
| service. This flag is ``OFF`` by default. The PS regression tests write/erase |
| storage multiple time, so enabling this flag can increase the life of flash |
| memory when testing. |
| If this flag is set to ``ON``, PS_RAM_FS_SIZE must also be provided. This |
| specifies the size of the block of RAM to be used to simulate the flash. |
| |
| .. Note:: |
| If this flag is disabled when running the regression tests, then it is |
| recommended that the persistent storage area is erased before running the |
| tests to ensure that all tests can run to completion. The type of persistent |
| storage area is platform specific (eFlash, MRAM, etc.) and it is described |
| in corresponding flash_layout.h |
| |
| - ``PS_MAX_ASSET_SIZE`` - Defines the maximum asset size to be stored in the |
| PS area. This size is used to define the temporary buffers used by PS to |
| read/write the asset content from/to flash. The memory used by the temporary |
| buffers is allocated statically as PS does not use dynamic memory allocation. |
| - ``PS_NUM_ASSETS`` - Defines the maximum number of assets to be stored in the |
| PS area. This number is used to dimension statically the object table size in |
| RAM (fast access) and flash (persistent storage). The memory used by the |
| object table is allocated statically as PS does not use dynamic memory |
| allocation. |
| - ``PS_TEST_NV_COUNTERS``- this flag enables the virtual implementation of the |
| PS NV counters interface in ``test/suites/ps/secure/nv_counters`` of the |
| ``tf-m-tests`` repo, which emulates NV counters in |
| RAM, and disables the hardware implementation of NV counters provided by |
| the secure service. This flag is enabled by default, but has no effect when |
| the secure regression test is disabled. This flag can be |
| overridden to ``OFF`` when building the regression tests. In this case, |
| the PS rollback protection test suite will not be built, as it relies |
| on extra functionality provided by the virtual NV counters to simulate |
| different rollback scenarios. The remainder of the PS test suites will |
| run using the hardware NV counters. Please note that running the tests in |
| this configuration will quickly increase the hardware NV counter values, |
| which cannot be decreased again. |
| Overriding this flag from its default value of ``OFF`` when not |
| building the regression tests is not currently supported. |
| |
| -------------- |
| |
| *Copyright (c) 2018-2021, Arm Limited. All rights reserved.* |
| *Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.* |