1 /*
2  * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
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 #include "tfm_log_unpriv.h"
17 #include "psa/crypto.h"
18 
19 #ifdef PS_ENCRYPTION
20 static const psa_algorithm_t ps_crypto_aead_alg = PS_CRYPTO_AEAD_ALG;
21 #endif
22 
tfm_ps_init(void)23 psa_status_t tfm_ps_init(void)
24 {
25     psa_status_t err;
26 
27 #ifndef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
28     err = tfm_its_init();
29     if (err != PSA_SUCCESS) {
30         return err;
31     }
32 #endif /* !TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
33 
34 #ifdef PS_ENCRYPTION
35     (void)ps_crypto_aead_alg; /* Suppress warning if logging disabled */
36     INFO_UNPRIV("[PS] Encryption alg: 0x%x\n", ps_crypto_aead_alg);
37 #endif
38 
39     err = ps_system_prepare();
40 #if PS_CREATE_FLASH_LAYOUT
41     /* If PS_CREATE_FLASH_LAYOUT is set to 1, it indicates that it is required to
42      * create a PS flash layout. PS service will generate an empty and valid
43      * PS flash layout to store assets. It will erase all data located in the
44      * assigned PS memory area before generating the PS layout.
45      * This flag is required to be set if the PS memory area is located in
46      * non-persistent memory.
47      * This flag can be set if the PS memory area is located in persistent
48      * memory without a previous valid PS flash layout in it. That is the case
49      * when it is the first time in the device life that the PS service is
50      * executed.
51      */
52     if (err != PSA_SUCCESS) {
53         /* Remove all data in the PS memory area and create a valid PS flash
54          * layout in that area.
55          */
56         err = ps_system_wipe_all();
57         if (err != PSA_SUCCESS) {
58             return err;
59         }
60 
61         /* Attempt to initialise again */
62         err = ps_system_prepare();
63     }
64 #endif /* PS_CREATE_FLASH_LAYOUT */
65 
66     return err;
67 }
68 
tfm_ps_set(int32_t client_id,psa_storage_uid_t uid,uint32_t data_length,psa_storage_create_flags_t create_flags)69 psa_status_t tfm_ps_set(int32_t client_id,
70                         psa_storage_uid_t uid,
71                         uint32_t data_length,
72                         psa_storage_create_flags_t create_flags)
73 {
74     /* Check that the UID is valid */
75     if (uid == TFM_PS_INVALID_UID) {
76         return PSA_ERROR_INVALID_ARGUMENT;
77     }
78 
79     /* Check that the create_flags does not contain any unsupported flags */
80     if (create_flags & ~(PSA_STORAGE_FLAG_WRITE_ONCE |
81                          PSA_STORAGE_FLAG_NO_CONFIDENTIALITY |
82                          PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION)) {
83         return PSA_ERROR_NOT_SUPPORTED;
84     }
85 
86     /* Create the object in the object system */
87     return ps_object_create(uid, client_id, create_flags, data_length);
88 }
89 
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)90 psa_status_t tfm_ps_get(int32_t client_id,
91                         psa_storage_uid_t uid,
92                         uint32_t data_offset,
93                         uint32_t data_size,
94                         size_t *p_data_length)
95 {
96     /* Check that the UID is valid */
97     if (uid == TFM_PS_INVALID_UID) {
98         return PSA_ERROR_INVALID_ARGUMENT;
99     }
100 
101     /* Read the object data from the object system */
102     return ps_object_read(uid, client_id, data_offset, data_size,
103                           p_data_length);
104 }
105 
tfm_ps_get_info(int32_t client_id,psa_storage_uid_t uid,struct psa_storage_info_t * p_info)106 psa_status_t tfm_ps_get_info(int32_t client_id, psa_storage_uid_t uid,
107                              struct psa_storage_info_t *p_info)
108 {
109     /* Check that the UID is valid */
110     if (uid == TFM_PS_INVALID_UID) {
111         return PSA_ERROR_INVALID_ARGUMENT;
112     }
113 
114     /* Get the info struct data from the object system */
115     return ps_object_get_info(uid, client_id, p_info);
116 }
117 
tfm_ps_remove(int32_t client_id,psa_storage_uid_t uid)118 psa_status_t tfm_ps_remove(int32_t client_id, psa_storage_uid_t uid)
119 {
120     psa_status_t err;
121 
122     /* Check that the UID is valid */
123     if (uid == TFM_PS_INVALID_UID) {
124         return PSA_ERROR_INVALID_ARGUMENT;
125     }
126 
127     /* Delete the object from the object system */
128     err = ps_object_delete(uid, client_id);
129 
130     /* PSA_ERROR_INVALID_SIGNATURE is not supported by psa_ps_remove
131      * specification. So, this function returns TFM_PS_ERR_OPERATION_FAILED
132      * instead.
133      */
134     if (err == PSA_ERROR_INVALID_SIGNATURE) {
135         return PSA_ERROR_GENERIC_ERROR;
136     }
137 
138     return err;
139 }
140 
tfm_ps_get_support(void)141 uint32_t tfm_ps_get_support(void)
142 {
143     /*
144      * This function returns a bitmask with flags set for all of the optional
145      * features supported by the PS service implementation.
146      *
147      * PS service does not support the optional extended PSA PS API yet.
148      */
149 
150     return 0;
151 }
152