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