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