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