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