1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  * All rights reserved.
5  */
6 
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ta_socket.h>
10 #include <tee_internal_api.h>
11 #include <tee_isocket.h>
12 #include <tee_tcpsocket.h>
13 #include <tee_udpsocket.h>
14 #include <trace.h>
15 
TA_CreateEntryPoint(void)16 TEE_Result TA_CreateEntryPoint(void)
17 {
18 	return TEE_SUCCESS;
19 }
20 
TA_DestroyEntryPoint(void)21 void TA_DestroyEntryPoint(void)
22 {
23 }
24 
TA_OpenSessionEntryPoint(uint32_t param_types,TEE_Param params[4],void ** session_ctx)25 TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
26 				    TEE_Param params[4],
27 				    void **session_ctx)
28 {
29 	(void)param_types;
30 	(void)params;
31 	(void)session_ctx;
32 	return TEE_SUCCESS;
33 }
34 
TA_CloseSessionEntryPoint(void * session_ctx)35 void TA_CloseSessionEntryPoint(void *session_ctx)
36 {
37 	(void)session_ctx;
38 }
39 
40 struct sock_handle {
41 	TEE_iSocketHandle ctx;
42 	TEE_iSocket *socket;
43 };
44 
ta_entry_tcp_open(uint32_t param_types,TEE_Param params[4])45 static TEE_Result ta_entry_tcp_open(uint32_t param_types, TEE_Param params[4])
46 {
47 	TEE_Result res = TEE_ERROR_GENERIC;
48 	struct sock_handle h = { };
49 	TEE_tcpSocket_Setup setup = { };
50 	uint32_t req_param_types =
51 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
52 				TEE_PARAM_TYPE_MEMREF_INPUT,
53 				TEE_PARAM_TYPE_MEMREF_OUTPUT,
54 				TEE_PARAM_TYPE_VALUE_OUTPUT);
55 
56 	if (param_types != req_param_types) {
57 		EMSG("got param_types 0x%x, expected 0x%x",
58 			param_types, req_param_types);
59 		return TEE_ERROR_BAD_PARAMETERS;
60 	}
61 
62 	if (params[2].memref.size < sizeof(struct sock_handle)) {
63 		params[2].memref.size = sizeof(struct sock_handle);
64 		return TEE_ERROR_SHORT_BUFFER;
65 	}
66 
67 	setup.ipVersion = params[0].value.a;
68 	setup.server_port = params[0].value.b;
69 	setup.server_addr = strndup(params[1].memref.buffer,
70 				    params[1].memref.size);
71 	if (!setup.server_addr)
72 		return TEE_ERROR_OUT_OF_MEMORY;
73 
74 	h.socket = TEE_tcpSocket;
75 	res = h.socket->open(&h.ctx, &setup, &params[3].value.a);
76 	free(setup.server_addr);
77 	if (res == TEE_SUCCESS) {
78 		memcpy(params[2].memref.buffer, &h, sizeof(h));
79 		params[2].memref.size = sizeof(h);
80 	}
81 	return res;
82 }
83 
ta_entry_udp_open(uint32_t param_types,TEE_Param params[4])84 static TEE_Result ta_entry_udp_open(uint32_t param_types, TEE_Param params[4])
85 {
86 	TEE_Result res = TEE_ERROR_GENERIC;
87 	struct sock_handle h = { };
88 	TEE_udpSocket_Setup setup = { };
89 	uint32_t req_param_types =
90 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
91 				TEE_PARAM_TYPE_MEMREF_INPUT,
92 				TEE_PARAM_TYPE_MEMREF_OUTPUT,
93 				TEE_PARAM_TYPE_VALUE_OUTPUT);
94 
95 	if (param_types != req_param_types) {
96 		EMSG("got param_types 0x%x, expected 0x%x",
97 			param_types, req_param_types);
98 		return TEE_ERROR_BAD_PARAMETERS;
99 	}
100 
101 	if (params[2].memref.size < sizeof(struct sock_handle)) {
102 		params[2].memref.size = sizeof(struct sock_handle);
103 		return TEE_ERROR_SHORT_BUFFER;
104 	}
105 
106 	setup.ipVersion = params[0].value.a;
107 	setup.server_port = params[0].value.b;
108 	setup.server_addr = strndup(params[1].memref.buffer,
109 				    params[1].memref.size);
110 	if (!setup.server_addr)
111 		return TEE_ERROR_OUT_OF_MEMORY;
112 
113 	h.socket = TEE_udpSocket;
114 	res = h.socket->open(&h.ctx, &setup, &params[3].value.a);
115 	free(setup.server_addr);
116 	if (res == TEE_SUCCESS) {
117 		memcpy(params[2].memref.buffer, &h, sizeof(h));
118 		params[2].memref.size = sizeof(h);
119 	}
120 	return res;
121 }
122 
ta_entry_close(uint32_t param_types,TEE_Param params[4])123 static TEE_Result ta_entry_close(uint32_t param_types, TEE_Param params[4])
124 {
125 	struct sock_handle *h = NULL;
126 	uint32_t req_param_types =
127 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
128 				TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE,
129 				TEE_PARAM_TYPE_NONE);
130 
131 	if (param_types != req_param_types) {
132 		EMSG("got param_types 0x%x, expected 0x%x",
133 			param_types, req_param_types);
134 		return TEE_ERROR_BAD_PARAMETERS;
135 	}
136 
137 	if (params[0].memref.size != sizeof(struct sock_handle))
138 		return TEE_ERROR_BAD_PARAMETERS;
139 
140 	h = params[0].memref.buffer;
141 	return h->socket->close(h->ctx);
142 }
143 
ta_entry_send(uint32_t param_types,TEE_Param params[4])144 static TEE_Result ta_entry_send(uint32_t param_types, TEE_Param params[4])
145 {
146 	struct sock_handle *h = NULL;
147 	uint32_t req_param_types =
148 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
149 				TEE_PARAM_TYPE_MEMREF_INPUT,
150 				TEE_PARAM_TYPE_VALUE_INOUT,
151 				TEE_PARAM_TYPE_NONE);
152 
153 	if (param_types != req_param_types) {
154 		EMSG("got param_types 0x%x, expected 0x%x",
155 			param_types, req_param_types);
156 		return TEE_ERROR_BAD_PARAMETERS;
157 	}
158 
159 	if (params[0].memref.size != sizeof(*h))
160 		return TEE_ERROR_BAD_PARAMETERS;
161 
162 	h = params[0].memref.buffer;
163 	params[2].value.b = params[1].memref.size;
164 	return h->socket->send(h->ctx, params[1].memref.buffer,
165 			       &params[2].value.b, params[2].value.a);
166 }
167 
ta_entry_recv(uint32_t param_types,TEE_Param params[4])168 static TEE_Result ta_entry_recv(uint32_t param_types, TEE_Param params[4])
169 {
170 	struct sock_handle *h = NULL;
171 	uint32_t req_param_types =
172 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
173 				TEE_PARAM_TYPE_MEMREF_OUTPUT,
174 				TEE_PARAM_TYPE_VALUE_INPUT,
175 				TEE_PARAM_TYPE_NONE);
176 
177 	if (param_types != req_param_types) {
178 		EMSG("got param_types 0x%x, expected 0x%x",
179 			param_types, req_param_types);
180 		return TEE_ERROR_BAD_PARAMETERS;
181 	}
182 
183 	if (params[0].memref.size != sizeof(struct sock_handle))
184 		return TEE_ERROR_BAD_PARAMETERS;
185 
186 	h = params[0].memref.buffer;
187 	return h->socket->recv(h->ctx, params[1].memref.buffer,
188 			       &params[1].memref.size, params[2].value.a);
189 }
190 
ta_entry_error(uint32_t param_types,TEE_Param params[4])191 static TEE_Result ta_entry_error(uint32_t param_types, TEE_Param params[4])
192 {
193 	struct sock_handle *h = NULL;
194 	uint32_t req_param_types =
195 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
196 				TEE_PARAM_TYPE_VALUE_OUTPUT,
197 				TEE_PARAM_TYPE_NONE,
198 				TEE_PARAM_TYPE_NONE);
199 
200 	if (param_types != req_param_types) {
201 		EMSG("got param_types 0x%x, expected 0x%x",
202 			param_types, req_param_types);
203 		return TEE_ERROR_BAD_PARAMETERS;
204 	}
205 
206 	if (params[0].memref.size != sizeof(struct sock_handle))
207 		return TEE_ERROR_BAD_PARAMETERS;
208 
209 	h = params[0].memref.buffer;
210 	params[1].value.a = h->socket->error(h->ctx);
211 	return TEE_SUCCESS;
212 }
213 
ta_entry_ioctl(uint32_t param_types,TEE_Param params[4])214 static TEE_Result ta_entry_ioctl(uint32_t param_types, TEE_Param params[4])
215 {
216 	struct sock_handle *h = NULL;
217 	uint32_t req_param_types =
218 		TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
219 				TEE_PARAM_TYPE_MEMREF_INOUT,
220 				TEE_PARAM_TYPE_VALUE_INPUT,
221 				TEE_PARAM_TYPE_NONE);
222 
223 	if (param_types != req_param_types) {
224 		EMSG("got param_types 0x%x, expected 0x%x",
225 			param_types, req_param_types);
226 		return TEE_ERROR_BAD_PARAMETERS;
227 	}
228 
229 	if (params[0].memref.size != sizeof(struct sock_handle))
230 		return TEE_ERROR_BAD_PARAMETERS;
231 
232 	h = params[0].memref.buffer;
233 	return h->socket->ioctl(h->ctx, params[2].value.a,
234 				params[1].memref.buffer,
235 				&params[1].memref.size);
236 }
237 
238 
239 
TA_InvokeCommandEntryPoint(void * session_ctx,uint32_t cmd_id,uint32_t param_types,TEE_Param params[4])240 TEE_Result TA_InvokeCommandEntryPoint(void *session_ctx,
241 				      uint32_t cmd_id, uint32_t param_types,
242 				      TEE_Param params[4])
243 {
244 	(void)session_ctx;
245 
246 	switch (cmd_id) {
247 	case TA_SOCKET_CMD_TCP_OPEN:
248 		return ta_entry_tcp_open(param_types, params);
249 	case TA_SOCKET_CMD_UDP_OPEN:
250 		return ta_entry_udp_open(param_types, params);
251 	case TA_SOCKET_CMD_CLOSE:
252 		return ta_entry_close(param_types, params);
253 	case TA_SOCKET_CMD_SEND:
254 		return ta_entry_send(param_types, params);
255 	case TA_SOCKET_CMD_RECV:
256 		return ta_entry_recv(param_types, params);
257 	case TA_SOCKET_CMD_ERROR:
258 		return ta_entry_error(param_types, params);
259 	case TA_SOCKET_CMD_IOCTL:
260 		return ta_entry_ioctl(param_types, params);
261 	default:
262 		return TEE_ERROR_BAD_PARAMETERS;
263 	}
264 }
265