xref: /optee_os/lib/libutee/tee_socket_pta.c (revision bc879b1765afacd8a2b7673236037181011cabea)
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 
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, 0, 0, NULL,
22 						   &sess, NULL);
23 
24 		if (res != TEE_SUCCESS)
25 			return res;
26 	}
27 
28 	return TEE_InvokeTACommand(sess, 0, cmd_id, param_types, params, NULL);
29 }
30 
31 TEE_Result __tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers,
32 				 const char *addr, uint16_t port,
33 				 uint32_t protocol, uint32_t *handle)
34 {
35 	TEE_Result res;
36 	uint32_t param_types;
37 	TEE_Param params[TEE_NUM_PARAMS];
38 
39 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
40 				      TEE_PARAM_TYPE_MEMREF_INPUT,
41 				      TEE_PARAM_TYPE_VALUE_INPUT,
42 				      TEE_PARAM_TYPE_VALUE_OUTPUT);
43 	memset(params, 0, sizeof(params));
44 
45 	switch (ip_vers) {
46 	case TEE_IP_VERSION_DC:
47 	case TEE_IP_VERSION_4:
48 	case TEE_IP_VERSION_6:
49 		params[0].value.a = ip_vers;
50 		break;
51 	default:
52 		return TEE_ERROR_BAD_PARAMETERS;
53 	}
54 
55 	params[0].value.b = port;
56 
57 	if (!addr)
58 		return TEE_ERROR_BAD_PARAMETERS;
59 	params[1].memref.buffer = (void *)addr;
60 	params[1].memref.size = strlen(addr) + 1;
61 
62 	switch (protocol) {
63 	case TEE_ISOCKET_PROTOCOLID_TCP:
64 	case TEE_ISOCKET_PROTOCOLID_UDP:
65 		params[2].value.a = protocol;
66 		break;
67 	default:
68 		return TEE_ERROR_BAD_PARAMETERS;
69 	}
70 
71 	res = invoke_socket_pta(PTA_SOCKET_OPEN, param_types, params);
72 	if (res == TEE_SUCCESS)
73 		*handle = params[3].value.a;
74 	return res;
75 }
76 
77 TEE_Result __tee_socket_pta_close(uint32_t handle)
78 {
79 	uint32_t param_types;
80 	TEE_Param params[TEE_NUM_PARAMS];
81 
82 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
83 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE,
84 				      TEE_PARAM_TYPE_NONE);
85 	memset(params, 0, sizeof(params));
86 
87 	params[0].value.a = handle;
88 	return invoke_socket_pta(PTA_SOCKET_CLOSE, param_types, params);
89 }
90 
91 TEE_Result __tee_socket_pta_send(uint32_t handle, const void *buf,
92 				 uint32_t *len, uint32_t timeout)
93 {
94 	TEE_Result res;
95 	uint32_t param_types;
96 	TEE_Param params[TEE_NUM_PARAMS];
97 
98 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
99 				      TEE_PARAM_TYPE_MEMREF_INPUT,
100 				      TEE_PARAM_TYPE_VALUE_OUTPUT,
101 				      TEE_PARAM_TYPE_NONE);
102 	memset(params, 0, sizeof(params));
103 
104 	params[0].value.a = handle;
105 	params[0].value.b = timeout;
106 
107 	params[1].memref.buffer = (void *)buf;
108 	params[1].memref.size = *len;
109 
110 	res = invoke_socket_pta(PTA_SOCKET_SEND, param_types, params);
111 	*len = params[2].value.a;
112 	return res;
113 }
114 
115 TEE_Result __tee_socket_pta_recv(uint32_t handle, void *buf, uint32_t *len,
116 				 uint32_t timeout)
117 
118 {
119 	TEE_Result res;
120 	uint32_t param_types;
121 	TEE_Param params[TEE_NUM_PARAMS];
122 
123 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
124 				      TEE_PARAM_TYPE_MEMREF_OUTPUT,
125 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
126 	memset(params, 0, sizeof(params));
127 
128 	params[0].value.a = handle;
129 	params[0].value.b = timeout;
130 
131 	params[1].memref.buffer = buf;
132 	params[1].memref.size = *len;
133 
134 	res = invoke_socket_pta(PTA_SOCKET_RECV, param_types, params);
135 	*len =  params[1].memref.size;
136 	return res;
137 }
138 
139 TEE_Result __tee_socket_pta_ioctl(uint32_t handle, uint32_t command, void *buf,
140 				  uint32_t *len)
141 {
142 	TEE_Result res;
143 	uint32_t param_types;
144 	TEE_Param params[TEE_NUM_PARAMS];
145 
146 	param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
147 				      TEE_PARAM_TYPE_MEMREF_INOUT,
148 				      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
149 	memset(params, 0, sizeof(params));
150 
151 	params[0].value.a = handle;
152 	params[0].value.b = command;
153 
154 	params[1].memref.buffer = buf;
155 	params[1].memref.size = *len;
156 
157 	res = invoke_socket_pta(PTA_SOCKET_IOCTL, param_types, params);
158 	*len =  params[1].memref.size;
159 	return res;
160 }
161