// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2016-2017, Linaro Limited */ #include #include #include #include <__tee_tcpsocket_defines.h> #include <__tee_udpsocket_defines.h> #include "tee_socket_private.h" static TEE_Result invoke_socket_pta(uint32_t cmd_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { static TEE_TASessionHandle sess = TEE_HANDLE_NULL; static const TEE_UUID socket_uuid = PTA_SOCKET_UUID; if (sess == TEE_HANDLE_NULL) { TEE_Result res = TEE_OpenTASession(&socket_uuid, TEE_TIMEOUT_INFINITE, 0, NULL, &sess, NULL); if (res != TEE_SUCCESS) return res; } return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id, param_types, params, NULL); } TEE_Result __tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers, const char *addr, uint16_t port, uint32_t protocol, uint32_t *handle) { TEE_Result res; uint32_t param_types; TEE_Param params[TEE_NUM_PARAMS]; param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT); memset(params, 0, sizeof(params)); switch (ip_vers) { case TEE_IP_VERSION_DC: case TEE_IP_VERSION_4: case TEE_IP_VERSION_6: params[0].value.a = ip_vers; break; default: return TEE_ERROR_BAD_PARAMETERS; } params[0].value.b = port; if (!addr) return TEE_ERROR_BAD_PARAMETERS; params[1].memref.buffer = (void *)addr; params[1].memref.size = strlen(addr) + 1; switch (protocol) { case TEE_ISOCKET_PROTOCOLID_TCP: case TEE_ISOCKET_PROTOCOLID_UDP: params[2].value.a = protocol; break; default: return TEE_ERROR_BAD_PARAMETERS; } res = invoke_socket_pta(PTA_SOCKET_OPEN, param_types, params); if (res == TEE_SUCCESS) *handle = params[3].value.a; return res; } TEE_Result __tee_socket_pta_close(uint32_t handle) { uint32_t param_types; TEE_Param params[TEE_NUM_PARAMS]; param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); memset(params, 0, sizeof(params)); params[0].value.a = handle; return invoke_socket_pta(PTA_SOCKET_CLOSE, param_types, params); } TEE_Result __tee_socket_pta_send(uint32_t handle, const void *buf, uint32_t *len, uint32_t timeout) { TEE_Result res; uint32_t param_types; TEE_Param params[TEE_NUM_PARAMS]; param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE); memset(params, 0, sizeof(params)); params[0].value.a = handle; params[0].value.b = timeout; params[1].memref.buffer = (void *)buf; params[1].memref.size = *len; res = invoke_socket_pta(PTA_SOCKET_SEND, param_types, params); *len = params[2].value.a; return res; } TEE_Result __tee_socket_pta_recv(uint32_t handle, void *buf, uint32_t *len, uint32_t timeout) { TEE_Result res; uint32_t param_types; TEE_Param params[TEE_NUM_PARAMS]; param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); memset(params, 0, sizeof(params)); params[0].value.a = handle; params[0].value.b = timeout; params[1].memref.buffer = buf; params[1].memref.size = *len; res = invoke_socket_pta(PTA_SOCKET_RECV, param_types, params); *len = params[1].memref.size; return res; } TEE_Result __tee_socket_pta_ioctl(uint32_t handle, uint32_t command, void *buf, uint32_t *len) { TEE_Result res; uint32_t param_types; TEE_Param params[TEE_NUM_PARAMS]; param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); memset(params, 0, sizeof(params)); params[0].value.a = handle; params[0].value.b = command; params[1].memref.buffer = buf; params[1].memref.size = *len; res = invoke_socket_pta(PTA_SOCKET_IOCTL, param_types, params); *len = params[1].memref.size; return res; }