blob: 7864ef6849303676ad9ef005abba443e6d7f3309 [file] [log] [blame]
Mark Horvath652b9002020-09-08 20:42:05 +02001/*
David Hu1bd1c7b2020-05-09 14:13:20 +08002 * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
Mark Horvath652b9002020-09-08 20:42:05 +02003 *
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;
Mark Horvath652b9002020-09-08 20:42:05 +020051 int32_t ret;
52
53 params.psa_call_params.handle = *forward_handle_ptr;
54 params.psa_call_params.type = PSA_IPC_CALL;
55
56 status = psa_proxy_put_msg_into_shared_mem(msg, &params);
57
58 if (status != PSA_SUCCESS) {
59 return status;
60 }
61
David Hu1bd1c7b2020-05-09 14:13:20 +080062 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_CALL, &params,
63 NON_SECURE_CLIENT_ID, (int32_t *)&status);
Mark Horvath652b9002020-09-08 20:42:05 +020064 if (ret != MAILBOX_SUCCESS) {
65 status = PSA_ERROR_COMMUNICATION_FAILURE;
66 }
67
68 if (status == PSA_SUCCESS) {
69 psa_proxy_write_back_results_from_shared_mem(msg);
70 }
71
72 return status;
73}
74
75static void psa_disconnect_from_secure_enclave(psa_msg_t *msg)
76{
77 psa_handle_t *forward_handle_ptr = (psa_handle_t *)msg->rhandle;
78 struct psa_client_params_t params;
Mark Horvath652b9002020-09-08 20:42:05 +020079 int32_t reply;
80
81 params.psa_close_params.handle = *forward_handle_ptr;
82
David Hu1bd1c7b2020-05-09 14:13:20 +080083 (void)tfm_ns_mailbox_client_call(MAILBOX_PSA_CLOSE, &params,
84 NON_SECURE_CLIENT_ID, &reply);
Mark Horvath652b9002020-09-08 20:42:05 +020085
86 deallocate_forward_handle(forward_handle_ptr);
87}
88
89static void get_sid_and_version_for_signal(psa_signal_t signal, uint32_t *sid,
90 uint32_t *version)
91{
92 switch (signal) {
93 case TFM_CRYPTO_SIGNAL:
94 *sid = TFM_CRYPTO_SID;
95 *version = TFM_CRYPTO_VERSION;
96 break;
97 case TFM_ATTEST_GET_TOKEN_SIGNAL:
98 *sid = TFM_ATTEST_GET_TOKEN_SID;
99 *version = TFM_ATTEST_GET_TOKEN_VERSION;
100 break;
101 case TFM_ATTEST_GET_TOKEN_SIZE_SIGNAL:
102 *sid = TFM_ATTEST_GET_TOKEN_SIZE_SID;
103 *version = TFM_ATTEST_GET_TOKEN_SIZE_VERSION;
104 break;
105 case TFM_ATTEST_GET_PUBLIC_KEY_SIGNAL:
106 *sid = TFM_ATTEST_GET_PUBLIC_KEY_SID;
107 *version = TFM_ATTEST_GET_PUBLIC_KEY_VERSION;
108 break;
109 case TFM_ITS_SET_SIGNAL:
110 *sid = TFM_ITS_SET_SID;
111 *version = TFM_ITS_SET_VERSION;
112 break;
113 case TFM_ITS_GET_SIGNAL:
114 *sid = TFM_ITS_GET_SID;
115 *version = TFM_ITS_GET_VERSION;
116 break;
117 case TFM_ITS_GET_INFO_SIGNAL:
118 *sid = TFM_ITS_GET_INFO_SID;
119 *version = TFM_ITS_GET_INFO_VERSION;
120 break;
121 case TFM_ITS_REMOVE_SIGNAL:
122 *sid = TFM_ITS_REMOVE_SID;
123 *version = TFM_ITS_REMOVE_VERSION;
124 break;
125 case TFM_SP_PLATFORM_SYSTEM_RESET_SIGNAL:
126 *sid = TFM_SP_PLATFORM_SYSTEM_RESET_SID;
127 *version = TFM_SP_PLATFORM_SYSTEM_RESET_VERSION;
128 break;
129 case TFM_SP_PLATFORM_IOCTL_SIGNAL:
130 *sid = TFM_SP_PLATFORM_IOCTL_SID;
131 *version = TFM_SP_PLATFORM_IOCTL_VERSION;
132 break;
133 case TFM_SP_PLATFORM_NV_COUNTER_SIGNAL:
134 *sid = TFM_SP_PLATFORM_NV_COUNTER_SID;
135 *version = TFM_SP_PLATFORM_NV_COUNTER_VERSION;
136 break;
137 case TFM_PS_SET_SIGNAL:
138 *sid = TFM_PS_SET_SID;
139 *version = TFM_PS_SET_VERSION;
140 break;
141 case TFM_PS_GET_SIGNAL:
142 *sid = TFM_PS_GET_SID;
143 *version = TFM_PS_GET_VERSION;
144 break;
145 case TFM_PS_GET_INFO_SIGNAL:
146 *sid = TFM_PS_GET_INFO_SID;
147 *version = TFM_PS_GET_INFO_VERSION;
148 break;
149 case TFM_PS_REMOVE_SIGNAL:
150 *sid = TFM_PS_REMOVE_SID;
151 *version = TFM_PS_REMOVE_VERSION;
152 break;
153 case TFM_PS_GET_SUPPORT_SIGNAL:
154 *sid = TFM_PS_GET_SUPPORT_SID;
155 *version = TFM_PS_GET_SUPPORT_VERSION;
156 break;
157 default:
158 psa_panic();
159 break;
160 }
161}
162
163static psa_status_t psa_connect_to_secure_enclave(psa_signal_t signal,
164 psa_msg_t *msg)
165{
166 psa_handle_t *forward_handle_ptr;
167 struct psa_client_params_t params;
Mark Horvath652b9002020-09-08 20:42:05 +0200168 int32_t ret;
169
170 forward_handle_ptr = allocate_forward_handle();
171
172 if (forward_handle_ptr != NULL) {
173
174 get_sid_and_version_for_signal(signal, &params.psa_connect_params.sid,
175 &params.psa_connect_params.version);
176
177 /* Fixme: All messages sent with the same client id */
David Hu1bd1c7b2020-05-09 14:13:20 +0800178 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_CONNECT, &params,
179 NON_SECURE_CLIENT_ID,
180 (int32_t *)forward_handle_ptr);
Mark Horvath652b9002020-09-08 20:42:05 +0200181 if (ret != MAILBOX_SUCCESS) {
182 *forward_handle_ptr = PSA_NULL_HANDLE;
183 }
184
185 if ( *forward_handle_ptr > 0) {
186 psa_set_rhandle(msg->handle, (void *)forward_handle_ptr);
187 return PSA_SUCCESS;
188 } else {
189 deallocate_forward_handle(forward_handle_ptr);
190 return *forward_handle_ptr;
191 }
192 } else {
193 return PSA_ERROR_INSUFFICIENT_MEMORY;
194 }
195}
196
197static void handle_signal(psa_signal_t signal)
198{
199 psa_msg_t msg;
200 psa_status_t status;
201
202 status = psa_get(signal, &msg);
203 switch (msg.type) {
204 case PSA_IPC_CONNECT:
205 status = psa_connect_to_secure_enclave(signal, &msg);
206 psa_reply(msg.handle, status);
207 break;
208 case PSA_IPC_CALL:
209 status = forward_psa_call_to_secure_enclave(&msg);
210 psa_reply(msg.handle, status);
211 break;
212 case PSA_IPC_DISCONNECT:
213 psa_disconnect_from_secure_enclave(&msg);
214 psa_reply(msg.handle, PSA_SUCCESS);
215 break;
216 default:
217 psa_panic();
218 break;
219 }
220}
221
222static psa_status_t psa_proxy_init(void)
223{
224 int32_t ret;
225
226 if (tfm_platform_ns_wait_for_s_cpu_ready()) {
227 return PSA_ERROR_HARDWARE_FAILURE;
228 }
229
230 ret = tfm_ns_mailbox_init(psa_proxy_get_ns_mailbox_queue());
231 if (ret != MAILBOX_SUCCESS) {
232 return PSA_ERROR_GENERIC_ERROR;
233 }
234
235 init_forward_handle_pool();
236
237 return PSA_SUCCESS;
238}
239
240psa_status_t psa_proxy_sp_init(void)
241{
242 psa_signal_t signal;
243 psa_status_t err;
244
245 err = psa_proxy_init();
246 if ( err != PSA_SUCCESS ) {
247 psa_panic();
248 }
249
250 while (1) {
251 /* Control is given back to SPM */
252 signal = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
253 handle_signal(signal);
254 }
255
256 return PSA_SUCCESS;
257}