1======================================
2Internal Trusted Storage (ITS) Service
3======================================
4
5:Author: Jamie Fox
6:Organization: Arm Limited
7
8.. toctree::
9    :maxdepth: 1
10
11    Block-aligned flash <tfm_its_512_flash.rst>
12
13PSA Internal Trusted Storage
14============================
15PSA Internal Trusted Storage (ITS) is a PSA RoT Service for storing the most
16security-critical device data (e.g. cryptographic keys) in internal storage,
17which is trusted to provide data confidentiality and authenticity. This
18contrasts with PSA Protected Storage, which is an Application RoT service that
19allows larger data sets to be stored securely in external flash, with the option
20for encryption, authentication and rollback protection to protect the
21data-at-rest.
22
23Current TF-M Secure Storage
24===========================
25Currently, the TF-M Secure Storage service implements PSA Protected Storage
26version 1.0-beta2. There is not yet an implementation of PSA Internal Trusted
27Storage in TF-M.
28
29New TF-M service
30================
31The proposal is to implement the *PSA Internal Trusted Storage API* with the
32*TF-M Internal Trusted Storage service*. It can be abbreviated to *TF-M ITS
33service* in general and to ``its`` in code. This name has the advantage of
34making clear the correspondence between the service and the API it implements.
35
36If this name is adopted, then it may make sense to rename the *Secure Storage
37service* to the *Protected Storage service* in the future to match. Then "secure
38storage" could refer to the two services as a collective.
39
40The TF-M ITS service will implement PSA ITS version 1.0. It will be provided by
41a separate partition to Protected Storage, for a couple of reasons:
42
43- To permit isolation between the services.
44
45  - ITS is a PSA RoT Service, while Protected Storage is an Application RoT
46    Service.
47
48- To avoid circular dependencies.
49
50  - The PSA Firmware Framework does not permit circular dependencies between
51    partitions, which would occur if Protected Storage and ITS were provided by
52    the same partition. Protected Storage depends on Crypto, which in turn
53    depends on ITS.
54
55The existing SST filesystem will be reused to provide the backend of the
56service, with the flash layer modified to direct storage to internal flash,
57rather than external.
58
59Compared to Protected Storage, encryption, authentication and rollback
60protection are not required, so the SST encrypted object layer and the crypto
61and NV counter interfaces are not required. The rollback protection feature of
62the object table is also not required.
63
64Code structure
65==============
66The code structure of the service will be as follows:
67
68TF-M repo:
69
70``interface/``
71
72- ``include/psa/internal_trusted_storage.h`` - PSA ITS API
73- ``src/tfm_its_api.c`` - PSA ITS API implementation for NSPE
74
75``secure_fw/ns_callable/tfm_veneers.c`` - ITS veneers (auto-generated from
76manifest)
77
78``secure_fw/partitions/internal_trusted_storage/``
79
80- ``tfm_internal_trusted_storage.yaml`` - Partition manifest
81- ``tfm_its_secure_api.c`` - PSA ITS API implementation for SPE
82- ``tfm_its_req_mngr.c`` - Uniform secure functions and IPC request handlers
83- ``tfm_internal_trusted_storage.h`` - TF-M ITS API (with client_id parameter)
84- ``tfm_internal_trusted_storage.c`` - TF-M ITS implementation, using the
85  flash_fs as a backend
86- ``its_crypto_interface.h`` - APIs for encrypting ITS assets used by ITS implementation  (optional)
87- ``its_crypto_interface.c`` - Implementation for ITS encryption (optional)
88- ``platform/ext/target/.../tfm_hal_its_encryption.c`` - Platform implementation for ITS encryption HAL APIs (optional)
89- ``flash_fs/`` - Filesystem
90- ``flash/`` - Flash interface
91
92tf-m-tests repo:
93
94``test/secure_fw/suites/its/``
95
96- ``non_secure/psa_its_ns_interface_testsuite.c`` - Non-secure interface tests
97- ``secure/psa_its_s_interface_testsuite.c`` - Secure interface tests
98
99TF-M ITS implementation
100-----------------------
101The following APIs will be exposed by ``tfm_internal_trusted_storage.h``::
102
103    psa_status_t tfm_its_init(void);
104
105    psa_status_t tfm_its_set(int32_t client_id,
106                             psa_storage_uid_t uid,
107                             size_t data_length,
108                             const void *p_data,
109                             psa_storage_create_flags_t create_flags);
110
111    psa_status_t tfm_its_get(int32_t client_id,
112                             psa_storage_uid_t uid,
113                             size_t data_offset,
114                             size_t data_size,
115                             void *p_data,
116                             size_t *p_data_length);
117
118    psa_status_t tfm_its_get_info(int32_t client_id,
119                                  psa_storage_uid_t uid,
120                                  struct psa_storage_info_t *p_info);
121
122    psa_status_t tfm_its_remove(int32_t client_id,
123                                psa_storage_uid_t uid);
124
125That is, the TF-M ITS APIs will have the same prototypes as the PSA ITS APIs,
126but with the addition of a ``client_id`` parameter, which will be passed from
127the ITS request manager. A ``tfm_its_init`` function will also be present, which
128will be called at initialisation time and not exposed through a veneer or SID.
129
130The implementation in ``tfm_internal_trusted_storage.c`` must validate the
131parameters (excepting memory references, which are validated by the SPM),
132translate the UID and client ID into a file ID and then make appropriate calls
133to the filesystem layer. It must also take care ensure that any PSA Storage
134flags associated with the UID are honoured.
135
136Filesystem
137----------
138The ITS filesystem will be copied and modified from the SST filesystem. The
139modifications required will be to rename symbols from ``sst`` to ``its`` and to
140update the implementation to be aligned with the latest version of the PSA
141Storage spec (which consists mainly of moving to the ``psa_status_t`` error type
142and using common error codes from ``psa/error.h``).
143
144The filesystem will also be modified to align the size of each file stored to
145the alignment requirement exposed by the flash interface, by adding appropriate
146padding.
147
148The filesystem code will be de-duplicated again once the ITS service is
149implemented (see below).
150
151Flash layer
152-----------
153The flash layer will be copied from SST, and modified to direct writes to the
154internal flash device. It too needs to be updated to use ``psa_status_t`` error
155types.
156
157Platform layer
158--------------
159The TF-M platform layer must be be updated to distinguish between the external
160flash device used for Protected Storage and internal flash device used for ITS.
161A flash region for the relevant storage service needs to be allocated in each.
162
163On test platforms these may just be two distinct regions of the same flash
164device, but in general they will separate devices with their own drivers.
165
166Detailed design considerations
167==============================
168
169Mapping UID onto file ID
170------------------------
171The ITS APIs identify assets with 64-bit UIDs, to which the ITS service must
172append the 32-bit client ID of the calling partition for access control. The
173existing filesystem uses 32-bit file IDs to identify files, so some mapping
174would be required to convert between the identifiers.
175
176SST uses the object table to do the mapping from client ID, UID pairs to file
177IDs, which means making an extra filesystem read/write for each get/set
178operation. This mapping has minimal overhead for SST though, because object
179table lookups are already required for rollback protection.
180
181For ITS, no rollback protection feature is required, so there are two options:
182
183- Keep a simplified version of the SST object table that just maps from
184  (client ID, UID) to file ID
185
186- Modify the filesystem to take (at least) 96-bit file IDs, in the form of a
187  fixed-length char buffer.
188
189The advantage of the former is that it would require no extra modification to
190the existing filesystem code, and the existing SST object table could be cut
191down for ITS. However, it would mean that every ITS request would invoke twice
192the number of filesystem operations, increasing latency and flash wear. The code
193size of the ITS partition would be increased, as would RAM usage as the table
194would need to be read into RAM.
195
196The latter option would make the filesystem slightly more complex: the size of a
197metadata entry would be increased by 64-bits and the 96-bit fids would need to
198be copied and compared with ``memcpy`` and ``memcmp`` calls. On the other hand,
199mapping onto file IDs would incur only the cost of copying the UID and client ID
200values into the file ID buffer.
201
202A third, even more general, solution would be to use arbitrary-length
203null-terminated strings as the file IDs. This is the standard solution in
204full-featured filesystems, but we do not currently require this level of
205complexity in secure storage.
206
207With this in mind, the proposed option is the second.
208
209Storing create flags
210--------------------
211The ITS APIs provide a 32-bit ``create_flags`` parameter, which contains bit
212flags that determine the properties of the stored data. Only one flag is
213currently defined for ITS: ``PSA_STORAGE_FLAG_WRITE_ONCE``, which prevents a UID
214from being modified or deleted after it is set for the first time.
215
216There are two places that these flags could be stored: in the file data or as
217part of the file metadata.
218
219For the first option, the ITS implementation would need to copy to the flags
220into the buffer containing the data, and adjust the size accordingly, for each
221set operation, and the reverse for each get. Every get_info operation would need
222to read some of the file data, rather than just the metadata, implying a second
223flash read. A potential downside is that many of the cryptographic assets stored
224in ITS will be aligned to power-of-two sizes; adding an extra 32-bits would
225misalign the size, which may reduce flash performance or necessitate adding
226padding to align to the flash page size.
227
228To implement the second option, a 32-bit ``flag`` field would be added to the
229filesystem's metadata structure, whose interpretation is defined by the user.
230This field would clearly be catered towards the PSA Storage APIs, even if
231nominally generic, and alternative filesystems may not have any such field.
232However, it is a more intuitive solution and would simplify both flash alignment
233and get_info operations.
234
235Overall, it seems more beneficial to store the flags in the metadata, so this is
236the proposed solution.
237
238Code sharing between Protected Storage and ITS
239----------------------------------------------
240To de-duplicate the filesystem code used by both Protected Storage and ITS, it
241is proposed that Protected Storage calls ITS APIs as its backend filesystem.
242
243Protected Storage essentially becomes an encryption, authentication and rollback
244protection layer on top of ITS. It makes IPC requests or secure function calls
245to the ITS service to do filesystem operations on its behalf.
246
247This has a couple of advantages:
248
249- It shrinks Protected Storage's stack size, because the filesystem and flash
250  layer stack is only in ITS.
251
252- It automatically solves the problem of ensuring mutual exclusion in the
253  filesystem and flash layers when Protected Storage and ITS are called
254  concurrently. The second request to ITS will just be made to wait by the SPM.
255
256The disadvantage of this approach is that it will increase the latency of
257Protected Storage requests, due to the extra overhead associated with making a
258second IPC request or secure function call. It also limits Protected Storage to
259using only the ITS APIs, unless extra veneers are added solely for Protected
260Storage to use. This, for example, prevents Protected Storage from doing partial
261writes to file without reading and re-writing the whole file.
262
263ITS will need to be modified to direct calls from Protected Storage to a
264different flash device. It can use the client ID to detect when the caller is
265Protected Storage, and pass down the identity of the flash device to use to the
266flash layer, which then calls the appropriate driver.
267
268An open question is what to do if Protected Storage itself wants to store
269something in internal storage in the future (e.g. rollback counters, hash
270tree/table or top hash). A couple of possible solutions would be:
271
272- Divide up the UIDs, so certain UIDs from Protected Storage refer to assets in
273  internal storage, and others to ones in external storage.
274
275- Use the ``type`` field of ``psa_call`` in IPC model to distinguish between
276  internal and external storage requests.
277
278The other option for code sharing would be for Protected Storage and ITS to
279directly share filesystem code, which would be placed in a shared code region.
280With this approach, mutual exclusion to the flash device would need to be
281implemented separately, as would some way of isolating static memory belonging
282to each partition but not the code. Because of these complications, this option
283has not been considered further at this time.
284
285
286Encryption in ITS
287=================
288
289The ITS can optionally be configured to encrypt the internal trusted storage
290data.
291To support encryption in ITS the target platform must provide an
292implementation of the APIs defined in ``platform/include/tfm_hal_its_encryption.h``::
293
294    enum tfm_hal_status_t tfm_hal_its_aead_generate_nonce(uint8_t *nonce,
295                                                          const size_t nonce_size);
296
297    enum tfm_hal_status_t tfm_hal_its_aead_encrypt(
298                                         struct tfm_hal_its_auth_crypt_ctx *ctx,
299                                         const uint8_t *plaintext,
300                                         const size_t plaintext_size,
301                                         uint8_t *ciphertext,
302                                         const size_t ciphertext_size,
303                                         uint8_t *tag,
304                                         const size_t tag_size);
305
306    enum tfm_hal_status_t tfm_hal_its_aead_decrypt(
307                                         struct tfm_hal_its_auth_crypt_ctx *ctx,
308                                         const uint8_t *ciphertext,
309                                         const size_t ciphertext_size,
310                                         uint8_t *tag,
311                                         const size_t tag_size,
312                                         uint8_t *plaintext,
313                                         const size_t plaintext_size);
314
315
316Then encryption can be enabled by setting the build option ``-DITS_ENCRYPTION=ON``.
317
318The figure :numref:`fig-tfm_eits` describes the encryption and decryption
319process happening when calling ``tfm_its_set`` and ``tfm_its_get``.
320
321.. figure:: /design_docs/media/tfm_its_encryption.*
322    :align: center
323    :name: fig-tfm_eits
324    :width: 80%
325
326    En/Decryption of ITS
327
328By using an AEAD scheme, it is possible to not only encrypt the file data but
329also authenticate the file meta data, which include:
330
331- File id
332- File size
333- File flags
334
335The key used to perform the AEAD operation must be derived from a long-term
336key-derivation key and the file id, which is used as a derivation label.
337The long-term key-derivation key must be managed by the target platform.
338
339There is a generic implementation of the abovementioned functions under
340``platform/ext/common/template/tfm_hal_its_encryption.c`` using PSA crypto calls
341similar to Protected Storage solution. When used, the default NV seed template
342under ``platform/ext/common/template/crypto_nv_seed.c`` must be disabled, as it
343relies on ITS. If there is a need for NV seed usage, an ITS independent
344implementation is required. If NV seed is not necessary, it can be turned off by
345setting ``CRYPTO_NV_SEED=0``.
346
347
348--------------
349
350*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
351