blob: 3fb6658962097d79abf0fd7b73721b0520560369 [file] [log] [blame]
Jens Wiklander02389a92016-12-16 11:13:38 +01001/*
2 * Copyright (c) 2016, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <stdlib.h>
29#include <string.h>
30#include <ta_socket.h>
31#include <tee_internal_api.h>
32#include <tee_isocket.h>
33#include <tee_tcpsocket.h>
34#include <tee_udpsocket.h>
35#include <trace.h>
36
37TEE_Result TA_CreateEntryPoint(void)
38{
39 return TEE_SUCCESS;
40}
41
42void TA_DestroyEntryPoint(void)
43{
44}
45
46TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
47 TEE_Param params[4],
48 void **session_ctx)
49{
50 (void)param_types;
51 (void)params;
52 (void)session_ctx;
53 return TEE_SUCCESS;
54}
55
56void TA_CloseSessionEntryPoint(void *session_ctx)
57{
58 (void)session_ctx;
59}
60
61struct sock_handle {
62 TEE_iSocketHandle ctx;
63 TEE_iSocket *socket;
64};
65
66static TEE_Result ta_entry_tcp_open(uint32_t param_types, TEE_Param params[4])
67{
68 TEE_Result res;
69 struct sock_handle h;
70 TEE_tcpSocket_Setup setup;
71 uint32_t req_param_types =
72 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
73 TEE_PARAM_TYPE_MEMREF_INPUT,
74 TEE_PARAM_TYPE_MEMREF_OUTPUT,
75 TEE_PARAM_TYPE_VALUE_OUTPUT);
76
77 if (param_types != req_param_types) {
78 EMSG("got param_types 0x%x, expected 0x%x",
79 param_types, req_param_types);
80 return TEE_ERROR_BAD_PARAMETERS;
81 }
82
83 if (params[2].memref.size < sizeof(struct sock_handle)) {
84 params[2].memref.size = sizeof(struct sock_handle);
85 return TEE_ERROR_SHORT_BUFFER;
86 }
87
88 setup.ipVersion = params[0].value.a;
89 setup.server_port = params[0].value.b;
90 setup.server_addr = strndup(params[1].memref.buffer,
91 params[1].memref.size);
92 if (!setup.server_addr)
93 return TEE_ERROR_OUT_OF_MEMORY;
94
95 h.socket = TEE_tcpSocket;
96 res = h.socket->open(&h.ctx, &setup, &params[3].value.a);
97 free(setup.server_addr);
98 if (res == TEE_SUCCESS) {
99 memcpy(params[2].memref.buffer, &h, sizeof(h));
100 params[2].memref.size = sizeof(h);
101 }
102 return res;
103}
104
105static TEE_Result ta_entry_udp_open(uint32_t param_types, TEE_Param params[4])
106{
107 TEE_Result res;
108 struct sock_handle h;
109 TEE_udpSocket_Setup setup;
110 uint32_t req_param_types =
111 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
112 TEE_PARAM_TYPE_MEMREF_INPUT,
113 TEE_PARAM_TYPE_MEMREF_OUTPUT,
114 TEE_PARAM_TYPE_VALUE_OUTPUT);
115
116 if (param_types != req_param_types) {
117 EMSG("got param_types 0x%x, expected 0x%x",
118 param_types, req_param_types);
119 return TEE_ERROR_BAD_PARAMETERS;
120 }
121
122 if (params[2].memref.size < sizeof(struct sock_handle)) {
123 params[2].memref.size = sizeof(struct sock_handle);
124 return TEE_ERROR_SHORT_BUFFER;
125 }
126
127 setup.ipVersion = params[0].value.a;
128 setup.server_port = params[0].value.b;
129 setup.server_addr = strndup(params[1].memref.buffer,
130 params[1].memref.size);
131 if (!setup.server_addr)
132 return TEE_ERROR_OUT_OF_MEMORY;
133
134 h.socket = TEE_udpSocket;
135 res = h.socket->open(&h.ctx, &setup, &params[3].value.a);
136 free(setup.server_addr);
137 if (res == TEE_SUCCESS) {
138 memcpy(params[2].memref.buffer, &h, sizeof(h));
139 params[2].memref.size = sizeof(h);
140 }
141 return res;
142}
143
144static TEE_Result ta_entry_close(uint32_t param_types, TEE_Param params[4])
145{
146 struct sock_handle *h;
147 uint32_t req_param_types =
148 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
149 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE,
150 TEE_PARAM_TYPE_NONE);
151
152 if (param_types != req_param_types) {
153 EMSG("got param_types 0x%x, expected 0x%x",
154 param_types, req_param_types);
155 return TEE_ERROR_BAD_PARAMETERS;
156 }
157
158 if (params[0].memref.size != sizeof(struct sock_handle))
159 return TEE_ERROR_BAD_PARAMETERS;
160
161 h = params[0].memref.buffer;
162 return h->socket->close(h->ctx);
163}
164
165static TEE_Result ta_entry_send(uint32_t param_types, TEE_Param params[4])
166{
167 struct sock_handle *h;
168 uint32_t req_param_types =
169 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
170 TEE_PARAM_TYPE_MEMREF_INPUT,
171 TEE_PARAM_TYPE_VALUE_INOUT,
172 TEE_PARAM_TYPE_NONE);
173
174 if (param_types != req_param_types) {
175 EMSG("got param_types 0x%x, expected 0x%x",
176 param_types, req_param_types);
177 return TEE_ERROR_BAD_PARAMETERS;
178 }
179
180 if (params[0].memref.size != sizeof(*h))
181 return TEE_ERROR_BAD_PARAMETERS;
182
183 h = params[0].memref.buffer;
184 params[2].value.b = params[1].memref.size;
185 return h->socket->send(h->ctx, params[1].memref.buffer,
186 &params[2].value.b, params[2].value.a);
187}
188
189static TEE_Result ta_entry_recv(uint32_t param_types, TEE_Param params[4])
190{
191 struct sock_handle *h;
192 uint32_t req_param_types =
193 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
194 TEE_PARAM_TYPE_MEMREF_OUTPUT,
195 TEE_PARAM_TYPE_VALUE_INPUT,
196 TEE_PARAM_TYPE_NONE);
197
198 if (param_types != req_param_types) {
199 EMSG("got param_types 0x%x, expected 0x%x",
200 param_types, req_param_types);
201 return TEE_ERROR_BAD_PARAMETERS;
202 }
203
204 if (params[0].memref.size != sizeof(struct sock_handle))
205 return TEE_ERROR_BAD_PARAMETERS;
206
207 h = params[0].memref.buffer;
208 return h->socket->recv(h->ctx, params[1].memref.buffer,
209 &params[1].memref.size, params[2].value.a);
210}
211
212static TEE_Result ta_entry_error(uint32_t param_types, TEE_Param params[4])
213{
214 struct sock_handle *h;
215 uint32_t req_param_types =
216 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
217 TEE_PARAM_TYPE_VALUE_OUTPUT,
218 TEE_PARAM_TYPE_NONE,
219 TEE_PARAM_TYPE_NONE);
220
221 if (param_types != req_param_types) {
222 EMSG("got param_types 0x%x, expected 0x%x",
223 param_types, req_param_types);
224 return TEE_ERROR_BAD_PARAMETERS;
225 }
226
227 if (params[0].memref.size != sizeof(struct sock_handle))
228 return TEE_ERROR_BAD_PARAMETERS;
229
230 h = params[0].memref.buffer;
231 params[1].value.a = h->socket->error(h->ctx);
232 return TEE_SUCCESS;
233}
234
235static TEE_Result ta_entry_ioctl(uint32_t param_types, TEE_Param params[4])
236{
237 struct sock_handle *h;
238 uint32_t req_param_types =
239 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
240 TEE_PARAM_TYPE_MEMREF_INOUT,
241 TEE_PARAM_TYPE_VALUE_INPUT,
242 TEE_PARAM_TYPE_NONE);
243
244 if (param_types != req_param_types) {
245 EMSG("got param_types 0x%x, expected 0x%x",
246 param_types, req_param_types);
247 return TEE_ERROR_BAD_PARAMETERS;
248 }
249
250 if (params[0].memref.size != sizeof(struct sock_handle))
251 return TEE_ERROR_BAD_PARAMETERS;
252
253 h = params[0].memref.buffer;
254 return h->socket->ioctl(h->ctx, params[2].value.a,
255 params[1].memref.buffer,
256 &params[1].memref.size);
257}
258
259
260
261TEE_Result TA_InvokeCommandEntryPoint(void *session_ctx,
262 uint32_t cmd_id, uint32_t param_types,
263 TEE_Param params[4])
264{
265 (void)session_ctx;
266
267 switch (cmd_id) {
268 case TA_SOCKET_CMD_TCP_OPEN:
269 return ta_entry_tcp_open(param_types, params);
270 case TA_SOCKET_CMD_UDP_OPEN:
271 return ta_entry_udp_open(param_types, params);
272 case TA_SOCKET_CMD_CLOSE:
273 return ta_entry_close(param_types, params);
274 case TA_SOCKET_CMD_SEND:
275 return ta_entry_send(param_types, params);
276 case TA_SOCKET_CMD_RECV:
277 return ta_entry_recv(param_types, params);
278 case TA_SOCKET_CMD_ERROR:
279 return ta_entry_error(param_types, params);
280 case TA_SOCKET_CMD_IOCTL:
281 return ta_entry_ioctl(param_types, params);
282 default:
283 return TEE_ERROR_BAD_PARAMETERS;
284 }
285}