1 /*
2  * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "config_tfm.h"
9 #include "config_ps_check.h"
10 #include "tfm_protected_storage.h"
11 #include "ps_object_system.h"
12 #include "tfm_ps_defs.h"
13 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
14 #include "tfm_internal_trusted_storage.h"
15 #endif /* !TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
16 
tfm_ps_init(void)17 psa_status_t tfm_ps_init(void)
18 {
19     psa_status_t err;
20 
21 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
22     err = tfm_its_init();
23     if (err != PSA_SUCCESS) {
24         return err;
25     }
26 #endif /* !TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
27 
28     err = ps_system_prepare();
29 #if PS_CREATE_FLASH_LAYOUT
30     /* If PS_CREATE_FLASH_LAYOUT is set to 1, it indicates that it is required to
31      * create a PS flash layout. PS service will generate an empty and valid
32      * PS flash layout to store assets. It will erase all data located in the
33      * assigned PS memory area before generating the PS layout.
34      * This flag is required to be set if the PS memory area is located in
35      * non-persistent memory.
36      * This flag can be set if the PS memory area is located in persistent
37      * memory without a previous valid PS flash layout in it. That is the case
38      * when it is the first time in the device life that the PS service is
39      * executed.
40      */
41     if (err != PSA_SUCCESS) {
42         /* Remove all data in the PS memory area and create a valid PS flash
43          * layout in that area.
44          */
45         err = ps_system_wipe_all();
46         if (err != PSA_SUCCESS) {
47             return err;
48         }
49 
50         /* Attempt to initialise again */
51         err = ps_system_prepare();
52     }
53 #endif /* PS_CREATE_FLASH_LAYOUT */
54 
55     return err;
56 }
57 
tfm_ps_set(int32_t client_id,psa_storage_uid_t uid,uint32_t data_length,psa_storage_create_flags_t create_flags)58 psa_status_t tfm_ps_set(int32_t client_id,
59                         psa_storage_uid_t uid,
60                         uint32_t data_length,
61                         psa_storage_create_flags_t create_flags)
62 {
63     /* Check that the UID is valid */
64     if (uid == TFM_PS_INVALID_UID) {
65         return PSA_ERROR_INVALID_ARGUMENT;
66     }
67 
68     /* Check that the create_flags does not contain any unsupported flags */
69     if (create_flags & ~(PSA_STORAGE_FLAG_WRITE_ONCE |
70                          PSA_STORAGE_FLAG_NO_CONFIDENTIALITY |
71                          PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION)) {
72         return PSA_ERROR_NOT_SUPPORTED;
73     }
74 
75     /* Create the object in the object system */
76     return ps_object_create(uid, client_id, create_flags, data_length);
77 }
78 
tfm_ps_get(int32_t client_id,psa_storage_uid_t uid,uint32_t data_offset,uint32_t data_size,size_t * p_data_length)79 psa_status_t tfm_ps_get(int32_t client_id,
80                         psa_storage_uid_t uid,
81                         uint32_t data_offset,
82                         uint32_t data_size,
83                         size_t *p_data_length)
84 {
85     /* Check that the UID is valid */
86     if (uid == TFM_PS_INVALID_UID) {
87         return PSA_ERROR_INVALID_ARGUMENT;
88     }
89 
90     /* Read the object data from the object system */
91     return ps_object_read(uid, client_id, data_offset, data_size,
92                           p_data_length);
93 }
94 
tfm_ps_get_info(int32_t client_id,psa_storage_uid_t uid,struct psa_storage_info_t * p_info)95 psa_status_t tfm_ps_get_info(int32_t client_id, psa_storage_uid_t uid,
96                              struct psa_storage_info_t *p_info)
97 {
98     /* Check that the UID is valid */
99     if (uid == TFM_PS_INVALID_UID) {
100         return PSA_ERROR_INVALID_ARGUMENT;
101     }
102 
103     /* Get the info struct data from the object system */
104     return ps_object_get_info(uid, client_id, p_info);
105 }
106 
tfm_ps_remove(int32_t client_id,psa_storage_uid_t uid)107 psa_status_t tfm_ps_remove(int32_t client_id, psa_storage_uid_t uid)
108 {
109     psa_status_t err;
110 
111     /* Check that the UID is valid */
112     if (uid == TFM_PS_INVALID_UID) {
113         return PSA_ERROR_INVALID_ARGUMENT;
114     }
115 
116     /* Delete the object from the object system */
117     err = ps_object_delete(uid, client_id);
118 
119     /* PSA_ERROR_INVALID_SIGNATURE is not supported by psa_ps_remove
120      * specification. So, this function returns TFM_PS_ERR_OPERATION_FAILED
121      * instead.
122      */
123     if (err == PSA_ERROR_INVALID_SIGNATURE) {
124         return PSA_ERROR_GENERIC_ERROR;
125     }
126 
127     return err;
128 }
129 
tfm_ps_get_support(void)130 uint32_t tfm_ps_get_support(void)
131 {
132     /*
133      * This function returns a bitmask with flags set for all of the optional
134      * features supported by the PS service implementation.
135      *
136      * PS service does not support the optional extended PSA PS API yet.
137      */
138 
139     return 0;
140 }
141