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