1 /*
2  * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdbool.h>
11 
12 #include "cmsis_compiler.h"
13 #include "config_tfm.h"
14 #include "psa/storage_common.h"
15 #include "tfm_internal_trusted_storage.h"
16 
17 #include "psa/framework_feature.h"
18 #include "psa/service.h"
19 #include "psa_manifest/tfm_internal_trusted_storage.h"
20 #include "tfm_its_defs.h"
21 
22 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
23 static uint8_t *p_data;
24 #else
25 static psa_handle_t handle;
26 #endif
27 
tfm_its_set_req(const psa_msg_t * msg)28 static psa_status_t tfm_its_set_req(const psa_msg_t *msg)
29 {
30     psa_storage_uid_t uid;
31     psa_storage_create_flags_t create_flags;
32     size_t num;
33     size_t data_length;
34 
35     if (msg->in_size[0] != sizeof(uid) ||
36         msg->in_size[2] != sizeof(create_flags)) {
37         /* The size of one of the arguments is incorrect */
38         return PSA_ERROR_PROGRAMMER_ERROR;
39     }
40 
41     num = psa_read(msg->handle, 0, &uid, sizeof(uid));
42     if (num != sizeof(uid)) {
43         return PSA_ERROR_PROGRAMMER_ERROR;
44     }
45 
46     num = psa_read(msg->handle, 2, &create_flags, sizeof(create_flags));
47     if (num != sizeof(create_flags)) {
48         return PSA_ERROR_PROGRAMMER_ERROR;
49     }
50     data_length = msg->in_size[1];
51 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
52     if (data_length) {
53         p_data = (uint8_t *)psa_map_invec(msg->handle, 1);
54     } else {
55         p_data = NULL;
56     }
57 #else
58     handle = msg->handle;
59 #endif
60     return tfm_its_set(msg->client_id, uid, data_length, create_flags);
61 }
62 
tfm_its_get_req(const psa_msg_t * msg)63 static psa_status_t tfm_its_get_req(const psa_msg_t *msg)
64 {
65     psa_status_t status;
66     psa_storage_uid_t uid;
67     size_t data_size;
68     size_t data_length;
69     size_t data_offset;
70     size_t num;
71 
72     if (msg->in_size[0] != sizeof(uid) ||
73         msg->in_size[1] != sizeof(data_offset)) {
74         /* The size of one of the arguments is incorrect */
75         return PSA_ERROR_PROGRAMMER_ERROR;
76     }
77 
78     num = psa_read(msg->handle, 0, &uid, sizeof(uid));
79     if (num != sizeof(uid)) {
80         return PSA_ERROR_PROGRAMMER_ERROR;
81     }
82 
83     num = psa_read(msg->handle, 1, &data_offset, sizeof(data_offset));
84     if (num != sizeof(data_offset)) {
85         return PSA_ERROR_PROGRAMMER_ERROR;
86     }
87     data_size = msg->out_size[0];
88 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
89     if (data_size) {
90         p_data = (uint8_t *)psa_map_outvec(msg->handle, 0);
91     } else {
92         p_data = NULL;
93     }
94 #else
95     handle = msg->handle;
96 #endif
97     status = tfm_its_get(msg->client_id, uid, data_offset, data_size, &data_length);
98 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
99     if ((status == PSA_SUCCESS) && (data_size != 0)) {
100         psa_unmap_outvec(msg->handle, 0, data_length);
101     }
102 #endif
103     return status;
104 }
105 
tfm_its_get_info_req(const psa_msg_t * msg)106 static psa_status_t tfm_its_get_info_req(const psa_msg_t *msg)
107 {
108     psa_status_t status;
109     psa_storage_uid_t uid;
110     struct psa_storage_info_t info;
111     size_t num;
112 
113     if (msg->in_size[0] != sizeof(uid) ||
114         msg->out_size[0] != sizeof(info)) {
115         /* The size of one of the arguments is incorrect */
116         return PSA_ERROR_PROGRAMMER_ERROR;
117     }
118 
119     num = psa_read(msg->handle, 0, &uid, sizeof(uid));
120     if (num != sizeof(uid)) {
121         return PSA_ERROR_PROGRAMMER_ERROR;
122     }
123 
124     status = tfm_its_get_info(msg->client_id, uid, &info);
125     if (status == PSA_SUCCESS) {
126         psa_write(msg->handle, 0, &info, sizeof(info));
127     }
128 
129     return status;
130 }
131 
tfm_its_remove_req(const psa_msg_t * msg)132 static psa_status_t tfm_its_remove_req(const psa_msg_t *msg)
133 {
134     psa_storage_uid_t uid;
135     size_t num;
136 
137     if (msg->in_size[0] != sizeof(uid)) {
138         /* The input argument size is incorrect */
139         return PSA_ERROR_PROGRAMMER_ERROR;
140     }
141 
142     num = psa_read(msg->handle, 0, &uid, sizeof(uid));
143     if (num != sizeof(uid)) {
144         return PSA_ERROR_PROGRAMMER_ERROR;
145     }
146 
147     return tfm_its_remove(msg->client_id, uid);
148 }
149 
tfm_its_entry(void)150 psa_status_t tfm_its_entry(void)
151 {
152     return tfm_its_init();
153 }
154 
tfm_internal_trusted_storage_service_sfn(const psa_msg_t * msg)155 psa_status_t tfm_internal_trusted_storage_service_sfn(const psa_msg_t *msg)
156 {
157     switch (msg->type) {
158     case TFM_ITS_SET:
159         return tfm_its_set_req(msg);
160     case TFM_ITS_GET:
161         return tfm_its_get_req(msg);
162     case TFM_ITS_GET_INFO:
163         return tfm_its_get_info_req(msg);
164     case TFM_ITS_REMOVE:
165         return tfm_its_remove_req(msg);
166     default:
167         return PSA_ERROR_NOT_SUPPORTED;
168     }
169 
170     return PSA_ERROR_GENERIC_ERROR;
171 }
172 
173 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
174 static uint8_t *p_data;
its_req_mngr_get_vec_base(void)175 uint8_t *its_req_mngr_get_vec_base(void)
176 {
177     return p_data;
178 }
179 #else
its_req_mngr_read(uint8_t * buf,size_t num_bytes)180 size_t its_req_mngr_read(uint8_t *buf, size_t num_bytes)
181 {
182     return psa_read(handle, 1, buf, num_bytes);
183 }
184 
its_req_mngr_write(const uint8_t * buf,size_t num_bytes)185 void its_req_mngr_write(const uint8_t *buf, size_t num_bytes)
186 {
187     psa_write(handle, 0, buf, num_bytes);
188 }
189 #endif
190 
191