11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2a32a96edSJens Wiklander /*
3a32a96edSJens Wiklander * Copyright (c) 2016-2017, Linaro Limited
4a32a96edSJens Wiklander */
5a32a96edSJens Wiklander
6a32a96edSJens Wiklander #include <pta_socket.h>
7a32a96edSJens Wiklander #include <tee_internal_api.h>
8a32a96edSJens Wiklander #include <tee_isocket.h>
9a32a96edSJens Wiklander #include <tee_tcpsocket.h>
10a32a96edSJens Wiklander #include <__tee_tcpsocket_defines_extensions.h>
11a32a96edSJens Wiklander #include <tee_udpsocket.h>
12a32a96edSJens Wiklander
13a32a96edSJens Wiklander #include "tee_socket_private.h"
14a32a96edSJens Wiklander
15a32a96edSJens Wiklander struct socket_ctx {
16a32a96edSJens Wiklander uint32_t handle;
17a32a96edSJens Wiklander uint32_t proto_error;
18a32a96edSJens Wiklander };
19a32a96edSJens Wiklander
tcp_open(TEE_iSocketHandle * ctx,void * setup,uint32_t * proto_error)20a32a96edSJens Wiklander static TEE_Result tcp_open(TEE_iSocketHandle *ctx, void *setup,
21a32a96edSJens Wiklander uint32_t *proto_error)
22a32a96edSJens Wiklander {
23a32a96edSJens Wiklander TEE_Result res;
24a32a96edSJens Wiklander struct socket_ctx *sock_ctx;
25a32a96edSJens Wiklander TEE_tcpSocket_Setup *tcp_setup = setup;
26a32a96edSJens Wiklander
27a32a96edSJens Wiklander if (!ctx || !setup || !proto_error)
28a32a96edSJens Wiklander TEE_Panic(0);
29a32a96edSJens Wiklander
30a32a96edSJens Wiklander *proto_error = TEE_SUCCESS;
31a32a96edSJens Wiklander
32a32a96edSJens Wiklander sock_ctx = TEE_Malloc(sizeof(*sock_ctx), TEE_MALLOC_FILL_ZERO);
33a32a96edSJens Wiklander if (!sock_ctx)
34a32a96edSJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
35a32a96edSJens Wiklander
36a32a96edSJens Wiklander res = __tee_socket_pta_open(tcp_setup->ipVersion,
37a32a96edSJens Wiklander tcp_setup->server_addr,
38a32a96edSJens Wiklander tcp_setup->server_port,
39a32a96edSJens Wiklander TEE_ISOCKET_PROTOCOLID_TCP,
40a32a96edSJens Wiklander &sock_ctx->handle);
41a32a96edSJens Wiklander if (res != TEE_SUCCESS) {
42a32a96edSJens Wiklander TEE_Free(sock_ctx);
43a32a96edSJens Wiklander sock_ctx = NULL;
44a32a96edSJens Wiklander }
45a32a96edSJens Wiklander *ctx = (TEE_iSocketHandle)sock_ctx;
46a32a96edSJens Wiklander
47a32a96edSJens Wiklander switch (res) {
48a32a96edSJens Wiklander case TEE_ISOCKET_ERROR_HOSTNAME:
49a32a96edSJens Wiklander *proto_error = res;
50a32a96edSJens Wiklander return TEE_ISOCKET_ERROR_PROTOCOL;
51a32a96edSJens Wiklander case TEE_ISOCKET_TCP_WARNING_UNKNOWN_OUT_OF_BAND:
52a32a96edSJens Wiklander *proto_error = res;
53a32a96edSJens Wiklander return TEE_ISOCKET_WARNING_PROTOCOL;
54a32a96edSJens Wiklander default:
55a32a96edSJens Wiklander return res;
56a32a96edSJens Wiklander }
57a32a96edSJens Wiklander }
58a32a96edSJens Wiklander
udp_open(TEE_iSocketHandle * ctx,void * setup,uint32_t * proto_error)59a32a96edSJens Wiklander static TEE_Result udp_open(TEE_iSocketHandle *ctx, void *setup,
60a32a96edSJens Wiklander uint32_t *proto_error)
61a32a96edSJens Wiklander {
62a32a96edSJens Wiklander TEE_Result res;
63a32a96edSJens Wiklander struct socket_ctx *sock_ctx;
64a32a96edSJens Wiklander TEE_udpSocket_Setup *udp_setup = setup;
65a32a96edSJens Wiklander
66a32a96edSJens Wiklander if (!ctx || !setup || !proto_error)
67a32a96edSJens Wiklander TEE_Panic(0);
68a32a96edSJens Wiklander
69a32a96edSJens Wiklander *proto_error = TEE_SUCCESS;
70a32a96edSJens Wiklander
71a32a96edSJens Wiklander sock_ctx = TEE_Malloc(sizeof(*sock_ctx), TEE_MALLOC_FILL_ZERO);
72a32a96edSJens Wiklander if (!sock_ctx)
73a32a96edSJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
74a32a96edSJens Wiklander
75a32a96edSJens Wiklander res = __tee_socket_pta_open(udp_setup->ipVersion,
76a32a96edSJens Wiklander udp_setup->server_addr,
77a32a96edSJens Wiklander udp_setup->server_port,
78a32a96edSJens Wiklander TEE_ISOCKET_PROTOCOLID_UDP,
79a32a96edSJens Wiklander &sock_ctx->handle);
80a32a96edSJens Wiklander if (res != TEE_SUCCESS) {
81a32a96edSJens Wiklander TEE_Free(sock_ctx);
82a32a96edSJens Wiklander sock_ctx = NULL;
83a32a96edSJens Wiklander }
84a32a96edSJens Wiklander *ctx = (TEE_iSocketHandle)sock_ctx;
85a32a96edSJens Wiklander
86a32a96edSJens Wiklander switch (res) {
87a32a96edSJens Wiklander case TEE_ISOCKET_ERROR_HOSTNAME:
88a32a96edSJens Wiklander *proto_error = res;
89a32a96edSJens Wiklander return TEE_ISOCKET_ERROR_PROTOCOL;
90a32a96edSJens Wiklander case TEE_ISOCKET_UDP_WARNING_UNKNOWN_OUT_OF_BAND:
91a32a96edSJens Wiklander *proto_error = res;
92a32a96edSJens Wiklander return TEE_ISOCKET_WARNING_PROTOCOL;
93a32a96edSJens Wiklander default:
94a32a96edSJens Wiklander return res;
95a32a96edSJens Wiklander }
96a32a96edSJens Wiklander }
97a32a96edSJens Wiklander
sock_close(TEE_iSocketHandle ctx)98a32a96edSJens Wiklander static TEE_Result sock_close(TEE_iSocketHandle ctx)
99a32a96edSJens Wiklander {
100a32a96edSJens Wiklander TEE_Result res;
101a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
102a32a96edSJens Wiklander
103a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL)
104a32a96edSJens Wiklander return TEE_SUCCESS;
105a32a96edSJens Wiklander
106a32a96edSJens Wiklander res = __tee_socket_pta_close(sock_ctx->handle);
107a32a96edSJens Wiklander TEE_Free(sock_ctx);
108a32a96edSJens Wiklander
109a32a96edSJens Wiklander return res;
110a32a96edSJens Wiklander }
111a32a96edSJens Wiklander
sock_send(TEE_iSocketHandle ctx,const void * buf,uint32_t * length,uint32_t timeout)112a32a96edSJens Wiklander static TEE_Result sock_send(TEE_iSocketHandle ctx, const void *buf,
113a32a96edSJens Wiklander uint32_t *length, uint32_t timeout)
114a32a96edSJens Wiklander {
115a32a96edSJens Wiklander TEE_Result res;
116a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
117a32a96edSJens Wiklander
118a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !buf || !length)
119a32a96edSJens Wiklander TEE_Panic(0);
120a32a96edSJens Wiklander
121a32a96edSJens Wiklander res = __tee_socket_pta_send(sock_ctx->handle, buf, length, timeout);
122a32a96edSJens Wiklander sock_ctx->proto_error = res;
123a32a96edSJens Wiklander
124a32a96edSJens Wiklander return res;
125a32a96edSJens Wiklander }
126a32a96edSJens Wiklander
sock_recv(TEE_iSocketHandle ctx,void * buf,uint32_t * length,uint32_t timeout)127a32a96edSJens Wiklander static TEE_Result sock_recv(TEE_iSocketHandle ctx, void *buf, uint32_t *length,
128a32a96edSJens Wiklander uint32_t timeout)
129a32a96edSJens Wiklander {
130a32a96edSJens Wiklander TEE_Result res;
131a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
132a32a96edSJens Wiklander
133a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length))
134a32a96edSJens Wiklander TEE_Panic(0);
135a32a96edSJens Wiklander
136a32a96edSJens Wiklander res = __tee_socket_pta_recv(sock_ctx->handle, buf, length, timeout);
137a32a96edSJens Wiklander sock_ctx->proto_error = res;
138a32a96edSJens Wiklander
139a32a96edSJens Wiklander return res;
140a32a96edSJens Wiklander }
141a32a96edSJens Wiklander
sock_error(TEE_iSocketHandle ctx)142a32a96edSJens Wiklander static uint32_t sock_error(TEE_iSocketHandle ctx)
143a32a96edSJens Wiklander {
144a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
145a32a96edSJens Wiklander
146a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL)
147a32a96edSJens Wiklander TEE_Panic(0);
148a32a96edSJens Wiklander
149a32a96edSJens Wiklander return sock_ctx->proto_error;
150a32a96edSJens Wiklander }
151a32a96edSJens Wiklander
tcp_ioctl(TEE_iSocketHandle ctx,uint32_t commandCode,void * buf,uint32_t * length)152a32a96edSJens Wiklander static TEE_Result tcp_ioctl(TEE_iSocketHandle ctx, uint32_t commandCode,
153a32a96edSJens Wiklander void *buf, uint32_t *length)
154a32a96edSJens Wiklander {
155a32a96edSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC;
156a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
157a32a96edSJens Wiklander
158a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length))
159a32a96edSJens Wiklander TEE_Panic(0);
160a32a96edSJens Wiklander
161a32a96edSJens Wiklander if (__tee_socket_ioctl_cmd_to_proto(commandCode) == 0)
162a32a96edSJens Wiklander return TEE_SUCCESS;
163a32a96edSJens Wiklander
164a32a96edSJens Wiklander switch (commandCode) {
165a32a96edSJens Wiklander case TEE_TCP_SET_RECVBUF:
166a32a96edSJens Wiklander case TEE_TCP_SET_SENDBUF:
167a32a96edSJens Wiklander res = __tee_socket_pta_ioctl(sock_ctx->handle, commandCode,
168a32a96edSJens Wiklander buf, length);
169a32a96edSJens Wiklander break;
170a32a96edSJens Wiklander default:
171a32a96edSJens Wiklander TEE_Panic(0);
172a32a96edSJens Wiklander }
173a32a96edSJens Wiklander
174a32a96edSJens Wiklander sock_ctx->proto_error = res;
175a32a96edSJens Wiklander
176a32a96edSJens Wiklander return res;
177a32a96edSJens Wiklander }
178a32a96edSJens Wiklander
udp_ioctl(TEE_iSocketHandle ctx,uint32_t commandCode,void * buf,uint32_t * length)179a32a96edSJens Wiklander static TEE_Result udp_ioctl(TEE_iSocketHandle ctx, uint32_t commandCode,
180a32a96edSJens Wiklander void *buf, uint32_t *length)
181a32a96edSJens Wiklander {
182a32a96edSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC;
183a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx;
184a32a96edSJens Wiklander
185a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length))
186a32a96edSJens Wiklander TEE_Panic(0);
187a32a96edSJens Wiklander
188a32a96edSJens Wiklander if (__tee_socket_ioctl_cmd_to_proto(commandCode) == 0)
189a32a96edSJens Wiklander return TEE_SUCCESS;
190a32a96edSJens Wiklander
191a32a96edSJens Wiklander switch (commandCode) {
192a32a96edSJens Wiklander case TEE_UDP_CHANGEADDR:
193a32a96edSJens Wiklander case TEE_UDP_CHANGEPORT:
194a32a96edSJens Wiklander res = __tee_socket_pta_ioctl(sock_ctx->handle, commandCode,
195a32a96edSJens Wiklander buf, length);
196a32a96edSJens Wiklander break;
197a32a96edSJens Wiklander default:
198a32a96edSJens Wiklander TEE_Panic(0);
199a32a96edSJens Wiklander }
200a32a96edSJens Wiklander
201a32a96edSJens Wiklander sock_ctx->proto_error = res;
202a32a96edSJens Wiklander
203a32a96edSJens Wiklander return res;
204a32a96edSJens Wiklander }
205a32a96edSJens Wiklander
206a32a96edSJens Wiklander
207a32a96edSJens Wiklander
208a32a96edSJens Wiklander static TEE_iSocket tcp_socket_instance = {
209a32a96edSJens Wiklander .TEE_iSocketVersion = TEE_ISOCKET_VERSION,
210a32a96edSJens Wiklander .protocolID = TEE_ISOCKET_PROTOCOLID_TCP,
211*a1d0f5d2SJerome Forissier .open = tcp_open,
212*a1d0f5d2SJerome Forissier .close = sock_close,
213*a1d0f5d2SJerome Forissier .send = sock_send,
214*a1d0f5d2SJerome Forissier .recv = sock_recv,
215*a1d0f5d2SJerome Forissier .error = sock_error,
216*a1d0f5d2SJerome Forissier .ioctl = tcp_ioctl,
217a32a96edSJens Wiklander };
218a32a96edSJens Wiklander
219a32a96edSJens Wiklander static TEE_iSocket udp_socket_instance = {
220a32a96edSJens Wiklander .TEE_iSocketVersion = TEE_ISOCKET_VERSION,
221a32a96edSJens Wiklander .protocolID = TEE_ISOCKET_PROTOCOLID_UDP,
222*a1d0f5d2SJerome Forissier .open = udp_open,
223*a1d0f5d2SJerome Forissier .close = sock_close,
224*a1d0f5d2SJerome Forissier .send = sock_send,
225*a1d0f5d2SJerome Forissier .recv = sock_recv,
226*a1d0f5d2SJerome Forissier .error = sock_error,
227*a1d0f5d2SJerome Forissier .ioctl = udp_ioctl,
228a32a96edSJens Wiklander };
229a32a96edSJens Wiklander
230a32a96edSJens Wiklander TEE_iSocket *const TEE_tcpSocket = &tcp_socket_instance;
231a32a96edSJens Wiklander TEE_iSocket *const TEE_udpSocket = &udp_socket_instance;
232