1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016-2017, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <pta_socket.h> 30 #include <string.h> 31 #include <tee_internal_api.h> 32 #include <__tee_tcpsocket_defines.h> 33 #include <__tee_udpsocket_defines.h> 34 35 #include "tee_socket_private.h" 36 37 static TEE_Result invoke_socket_pta(uint32_t cmd_id, uint32_t param_types, 38 TEE_Param params[TEE_NUM_PARAMS]) 39 { 40 static TEE_TASessionHandle sess = TEE_HANDLE_NULL; 41 static const TEE_UUID socket_uuid = PTA_SOCKET_UUID; 42 43 if (sess == TEE_HANDLE_NULL) { 44 TEE_Result res = TEE_OpenTASession(&socket_uuid, 0, 0, NULL, 45 &sess, NULL); 46 47 if (res != TEE_SUCCESS) 48 return res; 49 } 50 51 return TEE_InvokeTACommand(sess, 0, cmd_id, param_types, params, NULL); 52 } 53 54 TEE_Result __tee_socket_pta_open(TEE_ipSocket_ipVersion ip_vers, 55 const char *addr, uint16_t port, 56 uint32_t protocol, uint32_t *handle) 57 { 58 TEE_Result res; 59 uint32_t param_types; 60 TEE_Param params[TEE_NUM_PARAMS]; 61 62 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 63 TEE_PARAM_TYPE_MEMREF_INPUT, 64 TEE_PARAM_TYPE_VALUE_INPUT, 65 TEE_PARAM_TYPE_VALUE_OUTPUT); 66 memset(params, 0, sizeof(params)); 67 68 switch (ip_vers) { 69 case TEE_IP_VERSION_DC: 70 case TEE_IP_VERSION_4: 71 case TEE_IP_VERSION_6: 72 params[0].value.a = ip_vers; 73 break; 74 default: 75 return TEE_ERROR_BAD_PARAMETERS; 76 } 77 78 params[0].value.b = port; 79 80 if (!addr) 81 return TEE_ERROR_BAD_PARAMETERS; 82 params[1].memref.buffer = (void *)addr; 83 params[1].memref.size = strlen(addr) + 1; 84 85 switch (protocol) { 86 case TEE_ISOCKET_PROTOCOLID_TCP: 87 case TEE_ISOCKET_PROTOCOLID_UDP: 88 params[2].value.a = protocol; 89 break; 90 default: 91 return TEE_ERROR_BAD_PARAMETERS; 92 } 93 94 res = invoke_socket_pta(PTA_SOCKET_OPEN, param_types, params); 95 if (res == TEE_SUCCESS) 96 *handle = params[3].value.a; 97 return res; 98 } 99 100 TEE_Result __tee_socket_pta_close(uint32_t handle) 101 { 102 uint32_t param_types; 103 TEE_Param params[TEE_NUM_PARAMS]; 104 105 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 106 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, 107 TEE_PARAM_TYPE_NONE); 108 memset(params, 0, sizeof(params)); 109 110 params[0].value.a = handle; 111 return invoke_socket_pta(PTA_SOCKET_CLOSE, param_types, params); 112 } 113 114 TEE_Result __tee_socket_pta_send(uint32_t handle, const void *buf, 115 uint32_t *len, uint32_t timeout) 116 { 117 TEE_Result res; 118 uint32_t param_types; 119 TEE_Param params[TEE_NUM_PARAMS]; 120 121 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 122 TEE_PARAM_TYPE_MEMREF_INPUT, 123 TEE_PARAM_TYPE_VALUE_OUTPUT, 124 TEE_PARAM_TYPE_NONE); 125 memset(params, 0, sizeof(params)); 126 127 params[0].value.a = handle; 128 params[0].value.b = timeout; 129 130 params[1].memref.buffer = (void *)buf; 131 params[1].memref.size = *len; 132 133 res = invoke_socket_pta(PTA_SOCKET_SEND, param_types, params); 134 *len = params[2].value.a; 135 return res; 136 } 137 138 TEE_Result __tee_socket_pta_recv(uint32_t handle, void *buf, uint32_t *len, 139 uint32_t timeout) 140 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_OUTPUT, 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 = timeout; 153 154 params[1].memref.buffer = buf; 155 params[1].memref.size = *len; 156 157 res = invoke_socket_pta(PTA_SOCKET_RECV, param_types, params); 158 *len = params[1].memref.size; 159 return res; 160 } 161 162 TEE_Result __tee_socket_pta_ioctl(uint32_t handle, uint32_t command, void *buf, 163 uint32_t *len) 164 { 165 TEE_Result res; 166 uint32_t param_types; 167 TEE_Param params[TEE_NUM_PARAMS]; 168 169 param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 170 TEE_PARAM_TYPE_MEMREF_INOUT, 171 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); 172 memset(params, 0, sizeof(params)); 173 174 params[0].value.a = handle; 175 params[0].value.b = command; 176 177 params[1].memref.buffer = buf; 178 params[1].memref.size = *len; 179 180 res = invoke_socket_pta(PTA_SOCKET_IOCTL, param_types, params); 181 *len = params[1].memref.size; 182 return res; 183 } 184