1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2016-2017, Linaro Limited
4  */
5 
6 #include <pta_socket.h>
7 #include <string.h>
8 #include <tee_internal_api.h>
9 #include <__tee_tcpsocket_defines.h>
10 #include <__tee_udpsocket_defines.h>
11 
12 #include "tee_socket_private.h"
13 
invoke_socket_pta(uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])14 static TEE_Result invoke_socket_pta(uint32_t cmd_id, uint32_t param_types,
15 				    TEE_Param params[TEE_NUM_PARAMS])
16 {
17 	static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
18 	static const TEE_UUID socket_uuid = PTA_SOCKET_UUID;
19 
20 	if (sess == TEE_HANDLE_NULL) {
21 		TEE_Result res = TEE_OpenTASession(&socket_uuid,
22 						   TEE_TIMEOUT_INFINITE,
23 						   0, NULL, &sess, NULL);
24 
25 		if (res != TEE_SUCCESS)
26 			return res;
27 	}
28 
29 	return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id,
30 				   param_types, params, NULL);
31 }
32 
__tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers,const char * addr,uint16_t port,uint32_t protocol,uint32_t * handle)33 TEE_Result __tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers,
34 				 const char *addr, uint16_t port,
35 				 uint32_t protocol, uint32_t *handle)
36 {
37 	TEE_Result res;
38 	uint32_t param_types;
39 	TEE_Param params[TEE_NUM_PARAMS];
40 
41 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
42 				      TEE_PARAM_TYPE_MEMREF_INPUT,
43 				      TEE_PARAM_TYPE_VALUE_INPUT,
44 				      TEE_PARAM_TYPE_VALUE_OUTPUT);
45 	memset(params, 0, sizeof(params));
46 
47 	switch (ip_vers) {
48 	case TEE_IP_VERSION_DC:
49 	case TEE_IP_VERSION_4:
50 	case TEE_IP_VERSION_6:
51 		params[0].value.a = ip_vers;
52 		break;
53 	default:
54 		return TEE_ERROR_BAD_PARAMETERS;
55 	}
56 
57 	params[0].value.b = port;
58 
59 	if (!addr)
60 		return TEE_ERROR_BAD_PARAMETERS;
61 	params[1].memref.buffer = (void *)addr;
62 	params[1].memref.size = strlen(addr) + 1;
63 
64 	switch (protocol) {
65 	case TEE_ISOCKET_PROTOCOLID_TCP:
66 	case TEE_ISOCKET_PROTOCOLID_UDP:
67 		params[2].value.a = protocol;
68 		break;
69 	default:
70 		return TEE_ERROR_BAD_PARAMETERS;
71 	}
72 
73 	res = invoke_socket_pta(PTA_SOCKET_OPEN, param_types, params);
74 	if (res == TEE_SUCCESS)
75 		*handle = params[3].value.a;
76 	return res;
77 }
78 
__tee_socket_pta_close(uint32_t handle)79 TEE_Result __tee_socket_pta_close(uint32_t handle)
80 {
81 	uint32_t param_types;
82 	TEE_Param params[TEE_NUM_PARAMS];
83 
84 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
85 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE,
86 				      TEE_PARAM_TYPE_NONE);
87 	memset(params, 0, sizeof(params));
88 
89 	params[0].value.a = handle;
90 	return invoke_socket_pta(PTA_SOCKET_CLOSE, param_types, params);
91 }
92 
__tee_socket_pta_send(uint32_t handle,const void * buf,uint32_t * len,uint32_t timeout)93 TEE_Result __tee_socket_pta_send(uint32_t handle, const void *buf,
94 				 uint32_t *len, uint32_t timeout)
95 {
96 	TEE_Result res;
97 	uint32_t param_types;
98 	TEE_Param params[TEE_NUM_PARAMS];
99 
100 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
101 				      TEE_PARAM_TYPE_MEMREF_INPUT,
102 				      TEE_PARAM_TYPE_VALUE_OUTPUT,
103 				      TEE_PARAM_TYPE_NONE);
104 	memset(params, 0, sizeof(params));
105 
106 	params[0].value.a = handle;
107 	params[0].value.b = timeout;
108 
109 	params[1].memref.buffer = (void *)buf;
110 	params[1].memref.size = *len;
111 
112 	res = invoke_socket_pta(PTA_SOCKET_SEND, param_types, params);
113 	*len = params[2].value.a;
114 	return res;
115 }
116 
__tee_socket_pta_recv(uint32_t handle,void * buf,uint32_t * len,uint32_t timeout)117 TEE_Result __tee_socket_pta_recv(uint32_t handle, void *buf, uint32_t *len,
118 				 uint32_t timeout)
119 
120 {
121 	TEE_Result res;
122 	uint32_t param_types;
123 	TEE_Param params[TEE_NUM_PARAMS];
124 
125 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
126 				      TEE_PARAM_TYPE_MEMREF_OUTPUT,
127 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
128 	memset(params, 0, sizeof(params));
129 
130 	params[0].value.a = handle;
131 	params[0].value.b = timeout;
132 
133 	params[1].memref.buffer = buf;
134 	params[1].memref.size = *len;
135 
136 	res = invoke_socket_pta(PTA_SOCKET_RECV, param_types, params);
137 	*len =  params[1].memref.size;
138 	return res;
139 }
140 
__tee_socket_pta_ioctl(uint32_t handle,uint32_t command,void * buf,uint32_t * len)141 TEE_Result __tee_socket_pta_ioctl(uint32_t handle, uint32_t command, void *buf,
142 				  uint32_t *len)
143 {
144 	TEE_Result res;
145 	uint32_t param_types;
146 	TEE_Param params[TEE_NUM_PARAMS];
147 
148 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
149 				      TEE_PARAM_TYPE_MEMREF_INOUT,
150 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
151 	memset(params, 0, sizeof(params));
152 
153 	params[0].value.a = handle;
154 	params[0].value.b = command;
155 
156 	params[1].memref.buffer = buf;
157 	params[1].memref.size = *len;
158 
159 	res = invoke_socket_pta(PTA_SOCKET_IOCTL, param_types, params);
160 	*len =  params[1].memref.size;
161 	return res;
162 }
163