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, 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 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 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 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 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 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