blob: 5475d26b64d75def80470e9da4e3eb5955ad0f69 [file] [log] [blame]
Mark Horvath652b9002020-09-08 20:42:05 +02001/*
2 * Copyright (c) 2020, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdint.h>
9
10#include "psa/service.h"
11#include "psa_manifest/tfm_psa_proxy.h"
12#include "tfm_pools.h"
13#include "psa_manifest/sid.h"
14#include "tfm_multi_core_api.h"
15#include "tfm_ns_mailbox.h"
16#include "platform_multicore.h"
17#include "psa_proxy_shared_mem_mngr.h"
18
19#define NON_SECURE_CLIENT_ID (-1)
20
21/* Maximum number of connections supported, should be platform/configuration
22 * specific */
23#define SE_CONN_MAX_NUM (16)
24
25TFM_POOL_DECLARE(forward_handle_pool, sizeof(psa_handle_t),
26 SE_CONN_MAX_NUM);
27
28static inline void init_forward_handle_pool(void)
29{
30 tfm_pool_init(forward_handle_pool,
31 POOL_BUFFER_SIZE(forward_handle_pool),
32 sizeof(psa_handle_t),
33 SE_CONN_MAX_NUM);
34}
35
36static inline psa_handle_t * allocate_forward_handle(void)
37{
38 return (psa_handle_t *) tfm_pool_alloc(forward_handle_pool);
39}
40
41static inline void deallocate_forward_handle(psa_handle_t *h)
42{
43 tfm_pool_free(h);
44}
45
46static psa_status_t forward_psa_call_to_secure_enclave(const psa_msg_t *msg)
47{
48 psa_status_t status;
49 psa_handle_t *forward_handle_ptr = (psa_handle_t *)msg->rhandle;
50 struct psa_client_params_t params;
51 mailbox_msg_handle_t mailbox_handle;
52 int32_t ret;
53
54 params.psa_call_params.handle = *forward_handle_ptr;
55 params.psa_call_params.type = PSA_IPC_CALL;
56
57 status = psa_proxy_put_msg_into_shared_mem(msg, &params);
58
59 if (status != PSA_SUCCESS) {
60 return status;
61 }
62
63 mailbox_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CALL, &params,
64 NON_SECURE_CLIENT_ID);
65
66 /* Waiting for mailbox answer */
67 while(!tfm_ns_mailbox_is_msg_replied(mailbox_handle)) {
68 ;
69 }
70
71 ret = tfm_ns_mailbox_rx_client_reply(mailbox_handle, (int32_t *)&status);
72
73 if (ret != MAILBOX_SUCCESS) {
74 status = PSA_ERROR_COMMUNICATION_FAILURE;
75 }
76
77 if (status == PSA_SUCCESS) {
78 psa_proxy_write_back_results_from_shared_mem(msg);
79 }
80
81 return status;
82}
83
84static void psa_disconnect_from_secure_enclave(psa_msg_t *msg)
85{
86 psa_handle_t *forward_handle_ptr = (psa_handle_t *)msg->rhandle;
87 struct psa_client_params_t params;
88 mailbox_msg_handle_t mailbox_handle;
89 int32_t reply;
90
91 params.psa_close_params.handle = *forward_handle_ptr;
92
93 mailbox_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CLOSE, &params,
94 NON_SECURE_CLIENT_ID);
95
96 /* Waiting for mailbox answer */
97 while(!tfm_ns_mailbox_is_msg_replied(mailbox_handle)) {
98 ;
99 }
100
101 tfm_ns_mailbox_rx_client_reply(mailbox_handle, (int32_t *)&reply);
102
103 deallocate_forward_handle(forward_handle_ptr);
104}
105
106static void get_sid_and_version_for_signal(psa_signal_t signal, uint32_t *sid,
107 uint32_t *version)
108{
109 switch (signal) {
110 case TFM_CRYPTO_SIGNAL:
111 *sid = TFM_CRYPTO_SID;
112 *version = TFM_CRYPTO_VERSION;
113 break;
114 case TFM_ATTEST_GET_TOKEN_SIGNAL:
115 *sid = TFM_ATTEST_GET_TOKEN_SID;
116 *version = TFM_ATTEST_GET_TOKEN_VERSION;
117 break;
118 case TFM_ATTEST_GET_TOKEN_SIZE_SIGNAL:
119 *sid = TFM_ATTEST_GET_TOKEN_SIZE_SID;
120 *version = TFM_ATTEST_GET_TOKEN_SIZE_VERSION;
121 break;
122 case TFM_ATTEST_GET_PUBLIC_KEY_SIGNAL:
123 *sid = TFM_ATTEST_GET_PUBLIC_KEY_SID;
124 *version = TFM_ATTEST_GET_PUBLIC_KEY_VERSION;
125 break;
126 case TFM_ITS_SET_SIGNAL:
127 *sid = TFM_ITS_SET_SID;
128 *version = TFM_ITS_SET_VERSION;
129 break;
130 case TFM_ITS_GET_SIGNAL:
131 *sid = TFM_ITS_GET_SID;
132 *version = TFM_ITS_GET_VERSION;
133 break;
134 case TFM_ITS_GET_INFO_SIGNAL:
135 *sid = TFM_ITS_GET_INFO_SID;
136 *version = TFM_ITS_GET_INFO_VERSION;
137 break;
138 case TFM_ITS_REMOVE_SIGNAL:
139 *sid = TFM_ITS_REMOVE_SID;
140 *version = TFM_ITS_REMOVE_VERSION;
141 break;
142 case TFM_SP_PLATFORM_SYSTEM_RESET_SIGNAL:
143 *sid = TFM_SP_PLATFORM_SYSTEM_RESET_SID;
144 *version = TFM_SP_PLATFORM_SYSTEM_RESET_VERSION;
145 break;
146 case TFM_SP_PLATFORM_IOCTL_SIGNAL:
147 *sid = TFM_SP_PLATFORM_IOCTL_SID;
148 *version = TFM_SP_PLATFORM_IOCTL_VERSION;
149 break;
150 case TFM_SP_PLATFORM_NV_COUNTER_SIGNAL:
151 *sid = TFM_SP_PLATFORM_NV_COUNTER_SID;
152 *version = TFM_SP_PLATFORM_NV_COUNTER_VERSION;
153 break;
154 case TFM_PS_SET_SIGNAL:
155 *sid = TFM_PS_SET_SID;
156 *version = TFM_PS_SET_VERSION;
157 break;
158 case TFM_PS_GET_SIGNAL:
159 *sid = TFM_PS_GET_SID;
160 *version = TFM_PS_GET_VERSION;
161 break;
162 case TFM_PS_GET_INFO_SIGNAL:
163 *sid = TFM_PS_GET_INFO_SID;
164 *version = TFM_PS_GET_INFO_VERSION;
165 break;
166 case TFM_PS_REMOVE_SIGNAL:
167 *sid = TFM_PS_REMOVE_SID;
168 *version = TFM_PS_REMOVE_VERSION;
169 break;
170 case TFM_PS_GET_SUPPORT_SIGNAL:
171 *sid = TFM_PS_GET_SUPPORT_SID;
172 *version = TFM_PS_GET_SUPPORT_VERSION;
173 break;
174 default:
175 psa_panic();
176 break;
177 }
178}
179
180static psa_status_t psa_connect_to_secure_enclave(psa_signal_t signal,
181 psa_msg_t *msg)
182{
183 psa_handle_t *forward_handle_ptr;
184 struct psa_client_params_t params;
185 mailbox_msg_handle_t mailbox_handle;
186 int32_t ret;
187
188 forward_handle_ptr = allocate_forward_handle();
189
190 if (forward_handle_ptr != NULL) {
191
192 get_sid_and_version_for_signal(signal, &params.psa_connect_params.sid,
193 &params.psa_connect_params.version);
194
195 /* Fixme: All messages sent with the same client id */
196 mailbox_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CONNECT,
197 &params,
198 NON_SECURE_CLIENT_ID);
199
200 /* Waiting for mailbox answer */
201 while (!tfm_ns_mailbox_is_msg_replied(mailbox_handle)) {
202 ;
203 }
204
205 ret = tfm_ns_mailbox_rx_client_reply(mailbox_handle,
206 (int32_t *)forward_handle_ptr);
207
208 if (ret != MAILBOX_SUCCESS) {
209 *forward_handle_ptr = PSA_NULL_HANDLE;
210 }
211
212 if ( *forward_handle_ptr > 0) {
213 psa_set_rhandle(msg->handle, (void *)forward_handle_ptr);
214 return PSA_SUCCESS;
215 } else {
216 deallocate_forward_handle(forward_handle_ptr);
217 return *forward_handle_ptr;
218 }
219 } else {
220 return PSA_ERROR_INSUFFICIENT_MEMORY;
221 }
222}
223
224static void handle_signal(psa_signal_t signal)
225{
226 psa_msg_t msg;
227 psa_status_t status;
228
229 status = psa_get(signal, &msg);
230 switch (msg.type) {
231 case PSA_IPC_CONNECT:
232 status = psa_connect_to_secure_enclave(signal, &msg);
233 psa_reply(msg.handle, status);
234 break;
235 case PSA_IPC_CALL:
236 status = forward_psa_call_to_secure_enclave(&msg);
237 psa_reply(msg.handle, status);
238 break;
239 case PSA_IPC_DISCONNECT:
240 psa_disconnect_from_secure_enclave(&msg);
241 psa_reply(msg.handle, PSA_SUCCESS);
242 break;
243 default:
244 psa_panic();
245 break;
246 }
247}
248
249static psa_status_t psa_proxy_init(void)
250{
251 int32_t ret;
252
253 if (tfm_platform_ns_wait_for_s_cpu_ready()) {
254 return PSA_ERROR_HARDWARE_FAILURE;
255 }
256
257 ret = tfm_ns_mailbox_init(psa_proxy_get_ns_mailbox_queue());
258 if (ret != MAILBOX_SUCCESS) {
259 return PSA_ERROR_GENERIC_ERROR;
260 }
261
262 init_forward_handle_pool();
263
264 return PSA_SUCCESS;
265}
266
267psa_status_t psa_proxy_sp_init(void)
268{
269 psa_signal_t signal;
270 psa_status_t err;
271
272 err = psa_proxy_init();
273 if ( err != PSA_SUCCESS ) {
274 psa_panic();
275 }
276
277 while (1) {
278 /* Control is given back to SPM */
279 signal = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
280 handle_signal(signal);
281 }
282
283 return PSA_SUCCESS;
284}