1 /*
2  * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3  * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4  * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 #include <string.h>
10 #include "psa/framework_feature.h"
11 #if PSA_FRAMEWORK_HAS_MM_IOVEC != 1
12 #include "cmsis_compiler.h"
13 #endif
14 #include "config_tfm.h"
15 #include "tfm_internal_trusted_storage.h"
16 #include "tfm_its_req_mngr.h"
17 #include "tfm_hal_its.h"
18 #ifdef TFM_PARTITION_PROTECTED_STORAGE
19 #include "tfm_hal_ps.h"
20 #endif
21 #include "flash_fs/its_flash_fs.h"
22 #include "psa_manifest/pid.h"
23 #include "tfm_its_defs.h"
24 #include "its_utils.h"
25 #include "tfm_sp_log.h"
26 
27 #ifdef ITS_ENCRYPTION
28 #include "its_crypto_interface.h"
29 #endif
30 
31 #ifdef TFM_PARTITION_PROTECTED_STORAGE
32 #include "ps_object_defs.h"
33 #endif
34 
35 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
36 extern uint8_t *p_psa_src_data;
37 extern uint8_t *p_psa_dest_data;
38 #endif /* !TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
39 
40 static uint8_t g_fid[ITS_FILE_ID_SIZE];
41 static struct its_flash_fs_file_info_t g_file_info;
42 
43 #if (PSA_FRAMEWORK_HAS_MM_IOVEC != 1) && defined(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE)
44 /* Buffer to store asset data from the caller.
45  * Note: size must be aligned to the max flash program unit to meet the
46  * alignment requirement of the filesystem.
47  */
48 static uint8_t __ALIGNED(4) asset_data[ITS_UTILS_ALIGN(ITS_BUF_SIZE,
49                                           ITS_FLASH_MAX_ALIGNMENT)];
50 #endif
51 
52 #ifdef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
53 static its_flash_fs_ctx_t fs_ctx_its;
54 static struct its_flash_fs_config_t fs_cfg_its = {
55     .flash_dev = &ITS_FLASH_DEV,
56     .program_unit = ITS_FLASH_ALIGNMENT,
57     .max_file_size = ITS_UTILS_ALIGN(ITS_MAX_ASSET_SIZE, ITS_FLASH_ALIGNMENT),
58     .max_num_files = ITS_NUM_ASSETS + 1, /* Extra file for atomic replacement */
59 };
60 #endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
61 
62 #ifdef TFM_PARTITION_PROTECTED_STORAGE
63 static its_flash_fs_ctx_t fs_ctx_ps;
64 static struct its_flash_fs_config_t fs_cfg_ps = {
65     .flash_dev = &PS_FLASH_DEV,
66     .program_unit = PS_FLASH_ALIGNMENT,
67     .max_file_size = ITS_UTILS_ALIGN(PS_MAX_OBJECT_SIZE, PS_FLASH_ALIGNMENT),
68     .max_num_files = PS_MAX_NUM_OBJECTS,
69 };
70 #endif
71 
get_fs_ctx(int32_t client_id)72 static its_flash_fs_ctx_t *get_fs_ctx(int32_t client_id)
73 {
74 #ifdef TFM_PARTITION_PROTECTED_STORAGE
75 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
76     (void)client_id;
77     return &fs_ctx_ps;
78 #else
79     return (client_id == TFM_SP_PS) ? &fs_ctx_ps : &fs_ctx_its;
80 #endif /* !TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
81 #else
82     (void)client_id;
83     return &fs_ctx_its;
84 #endif
85 }
86 
87 #ifdef ITS_ENCRYPTION
88 /* Buffer to store the encrypted asset data before it is stored in the
89  * filesystem.
90  */
91 static uint8_t enc_asset_data[ITS_UTILS_ALIGN(ITS_BUF_SIZE,
92                                               ITS_FLASH_MAX_ALIGNMENT)];
93 
buffer_size_check(int32_t client_id,size_t buffer_size)94 static psa_status_t buffer_size_check(int32_t client_id, size_t buffer_size)
95 {
96 /* With protected storage no encryption is used */
97 #ifdef TFM_PARTITION_PROTECTED_STORAGE
98     if (client_id != TFM_SP_PS) {
99 #else
100     {
101 #endif /* TFM_PARTITION_PROTECTED_STORAGE */
102         /* When encryption is enabled the whole file needs to fit in the
103          * global buffer.
104          */
105         if (buffer_size > sizeof(enc_asset_data)) {
106             return PSA_ERROR_BUFFER_TOO_SMALL;
107         }
108     }
109     return PSA_SUCCESS;
110 }
111 
112 static psa_status_t tfm_its_crypt_data(int32_t client_id,
113                                 uint8_t **input,
114                                 size_t input_size)
115 {
116     psa_status_t status;
117 #ifdef TFM_PARTITION_PROTECTED_STORAGE
118     if (client_id != TFM_SP_PS) {
119 #else
120     {
121 #endif /* TFM_PARTITION_PROTECTED_STORAGE */
122         status = tfm_its_crypt_file(&g_file_info,
123                                     g_fid,
124                                     sizeof(g_fid),
125                                     *input,
126                                     input_size,
127                                     enc_asset_data,
128                                     sizeof(enc_asset_data),
129                                     true);
130 
131         if (status != PSA_SUCCESS) {
132             return status;
133         }
134         *input = enc_asset_data;
135     }
136     return PSA_SUCCESS;
137 }
138 
139 static psa_status_t tfm_its_get_encrypted(int32_t client_id,
140                          size_t data_offset,
141                          size_t data_size,
142                          size_t *p_data_length)
143 {
144     psa_status_t status;
145 
146     if (g_file_info.size_max > sizeof(enc_asset_data)) {
147             return PSA_ERROR_BUFFER_TOO_SMALL;
148     }
149 
150     /* When encryption is enabled we need to read the whole file */
151     status = its_flash_fs_file_read(get_fs_ctx(client_id),
152                                     g_fid,
153                                     g_file_info.size_current,
154                                     0,
155                                     enc_asset_data);
156     if (status != PSA_SUCCESS) {
157         *p_data_length = 0;
158         return status;
159     }
160 
161     status = tfm_its_crypt_file(&g_file_info,
162                                 g_fid,
163                                 sizeof(g_fid),
164                                 enc_asset_data,
165                                 g_file_info.size_current,
166                                 asset_data,
167                                 sizeof(asset_data),
168                                 false);
169     if (status != PSA_SUCCESS) {
170         *p_data_length = 0;
171         return status;
172     }
173 
174     #if (PSA_FRAMEWORK_HAS_MM_IOVEC == 1) /* PSA_FRAMEWORK_HAS_MM_IOVEC */
175     memcpy(its_req_mngr_get_vec_base(), asset_data + data_offset, data_size);
176     #else
177     /* Write asset data to the caller in one go as due to buffer check before
178      * it is ensured that all data fit into asset_data
179      */
180     its_req_mngr_write(asset_data + data_offset, data_size);
181     #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
182 
183     return PSA_SUCCESS;
184 }
185 #endif /* ITS_ENCRYPTION */
186 
187 /**
188  * \brief Maps a pair of client id and uid to a file id.
189  *
190  * \param[in]  client_id  Identifier of the asset's owner (client)
191  * \param[in]  uid        Identifier for the data
192  * \param[out] fid        Identifier of the file
193  */
194 static void tfm_its_get_fid(int32_t client_id,
195                             psa_storage_uid_t uid,
196                             uint8_t *fid)
197 {
198     memcpy(fid, (const void *)&client_id, sizeof(client_id));
199     memcpy(fid + sizeof(client_id), (const void *)&uid, sizeof(uid));
200 }
201 
202 #ifdef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
203 /**
204  * \brief Initialise the static ITS filesystem configurations.
205  *
206  * \return Returns PSA_ERROR_PROGRAMMER_ERROR if there is a configuration error,
207  *         and PSA_SUCCESS otherwise.
208  */
209 static psa_status_t init_its_fs_cfg(void)
210 {
211     struct tfm_hal_its_fs_info_t its_fs_info;
212 
213     /* Check the compile-time program unit matches the runtime value */
214     if (TFM_HAL_ITS_FLASH_DRIVER.GetInfo()->program_unit
215         != TFM_HAL_ITS_PROGRAM_UNIT) {
216         return PSA_ERROR_PROGRAMMER_ERROR;
217     }
218 
219     /* Retrieve flash properties from the ITS flash driver */
220     fs_cfg_its.sector_size = TFM_HAL_ITS_FLASH_DRIVER.GetInfo()->sector_size;
221     fs_cfg_its.erase_val = TFM_HAL_ITS_FLASH_DRIVER.GetInfo()->erased_value;
222 
223     /* Retrieve FS parameters from the ITS HAL */
224     if (tfm_hal_its_fs_info(&its_fs_info) != TFM_HAL_SUCCESS) {
225         return PSA_ERROR_PROGRAMMER_ERROR;
226     }
227 
228     /* Derive address, block_size and num_blocks from the HAL parameters */
229     fs_cfg_its.flash_area_addr = its_fs_info.flash_area_addr;
230     fs_cfg_its.block_size = fs_cfg_its.sector_size
231                             * its_fs_info.sectors_per_block;
232     fs_cfg_its.num_blocks = its_fs_info.flash_area_size / fs_cfg_its.block_size;
233 
234     return PSA_SUCCESS;
235 }
236 #endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
237 
238 #ifdef TFM_PARTITION_PROTECTED_STORAGE
239 /**
240  * \brief Initialise the static PS filesystem configurations.
241  *
242  * \return Returns PSA_ERROR_PROGRAMMER_ERROR if there is a configuration error,
243  *         and PSA_SUCCESS otherwise.
244  */
245 static psa_status_t init_ps_fs_cfg(void)
246 {
247     struct tfm_hal_ps_fs_info_t ps_fs_info;
248 
249     /* Check the compile-time program unit matches the runtime value */
250     if (TFM_HAL_PS_FLASH_DRIVER.GetInfo()->program_unit
251         != TFM_HAL_PS_PROGRAM_UNIT) {
252         return PSA_ERROR_PROGRAMMER_ERROR;
253     }
254 
255     /* Retrieve flash properties from the PS flash driver */
256     fs_cfg_ps.sector_size = TFM_HAL_PS_FLASH_DRIVER.GetInfo()->sector_size;
257     fs_cfg_ps.erase_val = TFM_HAL_PS_FLASH_DRIVER.GetInfo()->erased_value;
258 
259     /* Retrieve FS parameters from the PS HAL */
260     if (tfm_hal_ps_fs_info(&ps_fs_info) != TFM_HAL_SUCCESS) {
261         return PSA_ERROR_PROGRAMMER_ERROR;
262     }
263 
264     /* Derive address, block_size and num_blocks from the HAL parameters */
265     fs_cfg_ps.flash_area_addr = ps_fs_info.flash_area_addr;
266     fs_cfg_ps.block_size = fs_cfg_ps.sector_size * ps_fs_info.sectors_per_block;
267     fs_cfg_ps.num_blocks = ps_fs_info.flash_area_size / fs_cfg_ps.block_size;
268 
269     return PSA_SUCCESS;
270 }
271 #endif /* TFM_PARTITION_PROTECTED_STORAGE */
272 
273 psa_status_t tfm_its_init(void)
274 {
275     psa_status_t status = PSA_SUCCESS;
276 
277 #ifdef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
278     status = init_its_fs_cfg();
279     if (status != PSA_SUCCESS) {
280         return status;
281     }
282 
283     /* Initialise the ITS filesystem context */
284     status = its_flash_fs_init_ctx(&fs_ctx_its, &fs_cfg_its, &ITS_FLASH_OPS);
285     if (status != PSA_SUCCESS) {
286         return status;
287     }
288 
289     /* Prepare the ITS filesystem */
290     status = its_flash_fs_prepare(&fs_ctx_its);
291 #if ITS_CREATE_FLASH_LAYOUT
292     /* If ITS_CREATE_FLASH_LAYOUT is set to 1, it indicates that it is required to
293      * create a ITS flash layout. ITS service will generate an empty and valid
294      * ITS flash layout to store assets. It will erase all data located in the
295      * assigned ITS memory area before generating the ITS layout.
296      * This flag is required to be set if the ITS memory area is located in
297      * non-persistent memory.
298      * This flag can be set if the ITS memory area is located in persistent
299      * memory without a previous valid ITS flash layout in it. That is the case
300      * when it is the first time in the device life that the ITS service is
301      * executed.
302      */
303      if (status != PSA_SUCCESS) {
304         /* Remove all data in the ITS memory area and create a valid ITS flash
305          * layout in that area.
306          */
307         LOG_INFFMT("Creating an empty ITS flash layout.\r\n");
308         status = its_flash_fs_wipe_all(&fs_ctx_its);
309         if (status != PSA_SUCCESS) {
310             return status;
311         }
312 
313         /* Attempt to prepare again */
314         status = its_flash_fs_prepare(&fs_ctx_its);
315     }
316 #endif /* ITS_CREATE_FLASH_LAYOUT */
317 #endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
318 
319 #ifdef TFM_PARTITION_PROTECTED_STORAGE
320     /* Check status of ITS initialisation before continuing with PS */
321     if (status != PSA_SUCCESS) {
322         return status;
323     }
324 
325     status = init_ps_fs_cfg();
326     if (status != PSA_SUCCESS) {
327         return status;
328     }
329 
330     /* Initialise the PS filesystem context */
331     status = its_flash_fs_init_ctx(&fs_ctx_ps, &fs_cfg_ps, &PS_FLASH_OPS);
332     if (status != PSA_SUCCESS) {
333         return status;
334     }
335 
336     /* Prepare the PS filesystem */
337     status = its_flash_fs_prepare(&fs_ctx_ps);
338 #if PS_CREATE_FLASH_LAYOUT
339     /* If PS_CREATE_FLASH_LAYOUT is set to 1, it indicates that it is required to
340      * create a PS flash layout. PS service will generate an empty and valid
341      * PS flash layout to store assets. It will erase all data located in the
342      * assigned PS memory area before generating the PS layout.
343      * This flag is required to be set if the PS memory area is located in
344      * non-persistent memory.
345      * This flag can be set if the PS memory area is located in persistent
346      * memory without a previous valid PS flash layout in it. That is the case
347      * when it is the first time in the device life that the PS service is
348      * executed.
349      */
350      if (status != PSA_SUCCESS) {
351         /* Remove all data in the PS memory area and create a valid PS flash
352          * layout in that area.
353          */
354         LOG_INFFMT("Creating an empty PS flash layout.\r\n");
355         status = its_flash_fs_wipe_all(&fs_ctx_ps);
356         if (status != PSA_SUCCESS) {
357             return status;
358         }
359 
360         /* Attempt to prepare again */
361         status = its_flash_fs_prepare(&fs_ctx_ps);
362     }
363 #endif /* PS_CREATE_FLASH_LAYOUT */
364 #endif /* TFM_PARTITION_PROTECTED_STORAGE */
365 
366     return status;
367 }
368 
369 static psa_status_t get_file_info(psa_storage_uid_t uid, int32_t client_id)
370 {
371     /* Check that the UID is valid */
372     if (uid == TFM_ITS_INVALID_UID) {
373         return PSA_ERROR_INVALID_ARGUMENT;
374     }
375 
376     /* Set file id */
377     tfm_its_get_fid(client_id, uid, g_fid);
378 
379     /* Read file info */
380     return its_flash_fs_file_get_info(get_fs_ctx(client_id), g_fid,
381                                       &g_file_info);
382 }
383 
384 
385 static psa_status_t tfm_its_write_data_to_fs(const int32_t client_id,
386                                      const uint8_t *fid,
387                                      struct its_flash_fs_file_info_t *finfo,
388                                      const size_t data_size,
389                                      const size_t offset,
390                                      uint8_t *data)
391 {
392     psa_status_t status;
393     uint8_t *buffer_ptr = data;
394 #ifdef ITS_ENCRYPTION /* ITS_ENCRYPTION */
395     /* If the data will be encrypted the whole file needs to be written */
396     if (offset != 0) {
397         return PSA_ERROR_INVALID_ARGUMENT;
398     }
399     status = tfm_its_crypt_data(client_id, &buffer_ptr, data_size);
400     if (status != PSA_SUCCESS) {
401         return status;
402     }
403 #endif /* ITS_ENCRYPTION */
404     status = its_flash_fs_file_write(get_fs_ctx(client_id),
405                                         fid,
406                                         &g_file_info,
407                                         data_size, offset, buffer_ptr);
408     if (status != PSA_SUCCESS) {
409         return status;
410     }
411 
412     return PSA_SUCCESS;
413 }
414 
415 psa_status_t tfm_its_set(int32_t client_id,
416                          psa_storage_uid_t uid,
417                          size_t data_length,
418                          psa_storage_create_flags_t create_flags)
419 {
420     psa_status_t status;
421 #if (PSA_FRAMEWORK_HAS_MM_IOVEC != 1) && defined(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE)
422     size_t write_size;
423     size_t offset;
424 #endif
425 
426     /* Check that the UID is valid */
427     if (uid == TFM_ITS_INVALID_UID) {
428         return PSA_ERROR_INVALID_ARGUMENT;
429     }
430 
431     /* Check that the create_flags does not contain any unsupported flags */
432     if (create_flags & ~(PSA_STORAGE_FLAG_WRITE_ONCE |
433                          PSA_STORAGE_FLAG_NO_CONFIDENTIALITY |
434                          PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION)) {
435         return PSA_ERROR_NOT_SUPPORTED;
436     }
437 
438 #if defined ITS_ENCRYPTION && defined TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
439     status = buffer_size_check(client_id, data_length);
440     if (status != PSA_SUCCESS) {
441         return status;
442     }
443 #endif /* ITS_ENCRYPTION && TFM_PARTITION_INTERNAL_TRUSTED_STORAGE*/
444 
445     /* Read file info */
446     status = get_file_info(uid, client_id);
447     if (status == PSA_SUCCESS) {
448         /* If the object exists and has the write once flag set, then it
449          * cannot be modified.
450          */
451         if (g_file_info.flags & PSA_STORAGE_FLAG_WRITE_ONCE) {
452             return PSA_ERROR_NOT_PERMITTED;
453         }
454     } else if (status != PSA_ERROR_DOES_NOT_EXIST) {
455         /* If the file does not exist, then do nothing.
456          * If other error occurred, return it
457          */
458         return status;
459     }
460 
461     g_file_info.size_max = data_length;
462     g_file_info.flags = (uint32_t)create_flags |
463                         ITS_FLASH_FS_FLAG_CREATE | ITS_FLASH_FS_FLAG_TRUNCATE;
464 
465 
466 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
467     /* Write to the file in the file system
468      * No encryption needed as this will be stored in the Protected Storage
469      * Partition if ITS partition is not enabled.
470      */
471     status = its_flash_fs_file_write(get_fs_ctx(client_id), g_fid, &g_file_info,
472                                      data_length, 0, p_psa_src_data);
473 #elif PSA_FRAMEWORK_HAS_MM_IOVEC == 1
474     status = tfm_its_write_data_to_fs(client_id,
475                                       g_fid,
476                                       &g_file_info,
477                                       data_length, 0,
478                                       its_req_mngr_get_vec_base());
479 #else
480     offset = 0;
481 
482     /* Iteratively read data from the caller and write it to the filesystem, in
483      * chunks no larger than the size of the asset_data buffer.
484      */
485     do {
486         /* Write as much of the data as will fit in the asset_data buffer */
487         write_size = ITS_UTILS_MIN(data_length, sizeof(asset_data));
488 
489         /* Read asset data from the caller */
490         (void)its_req_mngr_read(asset_data, write_size);
491 
492         status = tfm_its_write_data_to_fs(client_id, g_fid, &g_file_info,
493                                           write_size, offset, asset_data);
494 
495         if (status != PSA_SUCCESS) {
496                 return status;
497         }
498         /* Do not create or truncate after the first iteration */
499         g_file_info.flags &= ~(ITS_FLASH_FS_FLAG_CREATE | ITS_FLASH_FS_FLAG_TRUNCATE);
500 
501         offset += write_size;
502         data_length -= write_size;
503     } while (data_length > 0);
504 #endif
505 
506     return status;
507 }
508 
509 static psa_status_t tfm_its_get_plain(int32_t client_id,
510                          size_t data_offset,
511                          size_t data_size,
512                          size_t *p_data_length)
513 {
514     psa_status_t status;
515 
516 #if (PSA_FRAMEWORK_HAS_MM_IOVEC != 1) && defined(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE)
517     size_t read_size;
518 #endif
519 
520 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
521     /* Read file data from the filesystem */
522     status = its_flash_fs_file_read(get_fs_ctx(client_id), g_fid, data_size,
523                                     data_offset, p_psa_dest_data);
524     if (status != PSA_SUCCESS) {
525         *p_data_length = 0;
526         return status;
527     }
528 
529 #elif (PSA_FRAMEWORK_HAS_MM_IOVEC == 1)
530     /* Read file data from the filesystem */
531     status = its_flash_fs_file_read(get_fs_ctx(client_id), g_fid, data_size,
532                                     data_offset, its_req_mngr_get_vec_base());
533     if (status != PSA_SUCCESS) {
534         *p_data_length = 0;
535         return status;
536     }
537 
538 #else
539 
540     /* Iteratively read data from the filesystem and write it to the caller, in
541      * chunks no larger than the size of the asset_data buffer.
542      */
543     do {
544         /* Read as much of the data as will fit in the asset_data buffer */
545         read_size = ITS_UTILS_MIN(data_size, sizeof(asset_data));
546 
547         /* Read file data from the filesystem */
548         status = its_flash_fs_file_read(get_fs_ctx(client_id), g_fid, read_size,
549                                         data_offset, asset_data);
550         if (status != PSA_SUCCESS) {
551             *p_data_length = 0;
552             return status;
553         }
554 
555         /* Write asset data to the caller */
556         its_req_mngr_write(asset_data, read_size);
557 
558         data_offset += read_size;
559         data_size -= read_size;
560     } while (data_size > 0);
561 #endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE & PSA_FRAMEWORK_HAS_MM_IOVEC */
562 
563     return PSA_SUCCESS;
564 }
565 
566 psa_status_t tfm_its_get(int32_t client_id,
567                          psa_storage_uid_t uid,
568                          size_t data_offset,
569                          size_t data_size,
570                          size_t *p_data_length)
571 {
572     psa_status_t status;
573 
574 #ifdef TFM_PARTITION_TEST_PS
575     /* The PS test partition can call tfm_its_get() through PS code. Treat it
576      * as if it were PS.
577      */
578     if (client_id == TFM_SP_PS_TEST) {
579         client_id = TFM_SP_PS;
580     }
581 #endif
582 
583     /* Check that the UID is valid */
584     if (uid == TFM_ITS_INVALID_UID) {
585         return PSA_ERROR_INVALID_ARGUMENT;
586     }
587 
588 #if defined ITS_ENCRYPTION && defined TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
589     status = buffer_size_check(client_id, data_offset + data_size);
590     if (status != PSA_SUCCESS) {
591         return status;
592     }
593 #endif /* ITS_ENCRYPTION && TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
594 
595     /* Read file info */
596     status = get_file_info(uid, client_id);
597     if (status != PSA_SUCCESS) {
598         return status;
599     }
600 
601     /* Boundary check the incoming request */
602     if (data_offset > g_file_info.size_current) {
603         return PSA_ERROR_INVALID_ARGUMENT;
604     }
605 
606     /* Copy the object data only from within the file boundary */
607     data_size = ITS_UTILS_MIN(data_size,
608                               g_file_info.size_current - data_offset);
609 
610     /* Update the size of the output data */
611     *p_data_length = data_size;
612 
613 #if defined ITS_ENCRYPTION && defined TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
614 #if defined TFM_PARTITION_PROTECTED_STORAGE
615     /* With protected storage no encryption is used */
616     if (client_id == TFM_SP_PS) {
617         return tfm_its_get_plain(client_id, data_offset, data_size, p_data_length);
618     } else
619 #endif /* TFM_PARTITION_PROTECTED_STORAGE */
620     {
621         return tfm_its_get_encrypted(client_id, data_offset, data_size, p_data_length);
622     }
623 #else
624     {
625         return tfm_its_get_plain(client_id, data_offset, data_size, p_data_length);
626     }
627 #endif /* ITS_ENCRYPTION  && TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
628 }
629 
630 psa_status_t tfm_its_get_info(int32_t client_id, psa_storage_uid_t uid,
631                               struct psa_storage_info_t *p_info)
632 {
633     psa_status_t status;
634 
635     /* Validate and read file info */
636     status = get_file_info(uid, client_id);
637     if (status != PSA_SUCCESS) {
638         return status;
639     }
640 
641     /* Copy file info to the PSA info struct */
642     p_info->capacity = g_file_info.size_current;
643     p_info->size = g_file_info.size_current;
644     p_info->flags = g_file_info.flags;
645 
646     return PSA_SUCCESS;
647 }
648 
649 psa_status_t tfm_its_remove(int32_t client_id, psa_storage_uid_t uid)
650 {
651     psa_status_t status;
652 
653 #ifdef TFM_PARTITION_TEST_PS
654     /* The PS test partition can call tfm_its_remove() through PS code. Treat
655      * it as if it were PS.
656      */
657     if (client_id == TFM_SP_PS_TEST) {
658         client_id = TFM_SP_PS;
659     }
660 #endif
661 
662     /* Validate and read file info */
663     status = get_file_info(uid, client_id);
664     if (status != PSA_SUCCESS) {
665         return status;
666     }
667 
668     /* If the object exists and has the write once flag set, then it
669      * cannot be deleted.
670      */
671     if (g_file_info.flags & PSA_STORAGE_FLAG_WRITE_ONCE) {
672         return PSA_ERROR_NOT_PERMITTED;
673     }
674 
675     /* Delete old file from the persistent area */
676     return its_flash_fs_file_delete(get_fs_ctx(client_id), g_fid);
677 }
678