1*1bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2a32a96edSJens Wiklander /* 3a32a96edSJens Wiklander * Copyright (c) 2016-2017, Linaro Limited 4a32a96edSJens Wiklander * All rights reserved. 5a32a96edSJens Wiklander * 6a32a96edSJens Wiklander * Redistribution and use in source and binary forms, with or without 7a32a96edSJens Wiklander * modification, are permitted provided that the following conditions are met: 8a32a96edSJens Wiklander * 9a32a96edSJens Wiklander * 1. Redistributions of source code must retain the above copyright notice, 10a32a96edSJens Wiklander * this list of conditions and the following disclaimer. 11a32a96edSJens Wiklander * 12a32a96edSJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright notice, 13a32a96edSJens Wiklander * this list of conditions and the following disclaimer in the documentation 14a32a96edSJens Wiklander * and/or other materials provided with the distribution. 15a32a96edSJens Wiklander * 16a32a96edSJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17a32a96edSJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18a32a96edSJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19a32a96edSJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20a32a96edSJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21a32a96edSJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22a32a96edSJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23a32a96edSJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24a32a96edSJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25a32a96edSJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26a32a96edSJens Wiklander * POSSIBILITY OF SUCH DAMAGE. 27a32a96edSJens Wiklander */ 28a32a96edSJens Wiklander 29a32a96edSJens Wiklander #include <pta_socket.h> 30a32a96edSJens Wiklander #include <tee_internal_api.h> 31a32a96edSJens Wiklander #include <tee_isocket.h> 32a32a96edSJens Wiklander #include <tee_tcpsocket.h> 33a32a96edSJens Wiklander #include <__tee_tcpsocket_defines_extensions.h> 34a32a96edSJens Wiklander #include <tee_udpsocket.h> 35a32a96edSJens Wiklander 36a32a96edSJens Wiklander #include "tee_socket_private.h" 37a32a96edSJens Wiklander 38a32a96edSJens Wiklander struct socket_ctx { 39a32a96edSJens Wiklander uint32_t handle; 40a32a96edSJens Wiklander uint32_t proto_error; 41a32a96edSJens Wiklander }; 42a32a96edSJens Wiklander 43a32a96edSJens Wiklander static TEE_Result tcp_open(TEE_iSocketHandle *ctx, void *setup, 44a32a96edSJens Wiklander uint32_t *proto_error) 45a32a96edSJens Wiklander { 46a32a96edSJens Wiklander TEE_Result res; 47a32a96edSJens Wiklander struct socket_ctx *sock_ctx; 48a32a96edSJens Wiklander TEE_tcpSocket_Setup *tcp_setup = setup; 49a32a96edSJens Wiklander 50a32a96edSJens Wiklander if (!ctx || !setup || !proto_error) 51a32a96edSJens Wiklander TEE_Panic(0); 52a32a96edSJens Wiklander 53a32a96edSJens Wiklander *proto_error = TEE_SUCCESS; 54a32a96edSJens Wiklander 55a32a96edSJens Wiklander sock_ctx = TEE_Malloc(sizeof(*sock_ctx), TEE_MALLOC_FILL_ZERO); 56a32a96edSJens Wiklander if (!sock_ctx) 57a32a96edSJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 58a32a96edSJens Wiklander 59a32a96edSJens Wiklander res = __tee_socket_pta_open(tcp_setup->ipVersion, 60a32a96edSJens Wiklander tcp_setup->server_addr, 61a32a96edSJens Wiklander tcp_setup->server_port, 62a32a96edSJens Wiklander TEE_ISOCKET_PROTOCOLID_TCP, 63a32a96edSJens Wiklander &sock_ctx->handle); 64a32a96edSJens Wiklander if (res != TEE_SUCCESS) { 65a32a96edSJens Wiklander TEE_Free(sock_ctx); 66a32a96edSJens Wiklander sock_ctx = NULL; 67a32a96edSJens Wiklander } 68a32a96edSJens Wiklander *ctx = (TEE_iSocketHandle)sock_ctx; 69a32a96edSJens Wiklander 70a32a96edSJens Wiklander switch (res) { 71a32a96edSJens Wiklander case TEE_ISOCKET_ERROR_HOSTNAME: 72a32a96edSJens Wiklander *proto_error = res; 73a32a96edSJens Wiklander return TEE_ISOCKET_ERROR_PROTOCOL; 74a32a96edSJens Wiklander case TEE_ISOCKET_TCP_WARNING_UNKNOWN_OUT_OF_BAND: 75a32a96edSJens Wiklander *proto_error = res; 76a32a96edSJens Wiklander return TEE_ISOCKET_WARNING_PROTOCOL; 77a32a96edSJens Wiklander default: 78a32a96edSJens Wiklander return res; 79a32a96edSJens Wiklander } 80a32a96edSJens Wiklander } 81a32a96edSJens Wiklander 82a32a96edSJens Wiklander static TEE_Result udp_open(TEE_iSocketHandle *ctx, void *setup, 83a32a96edSJens Wiklander uint32_t *proto_error) 84a32a96edSJens Wiklander { 85a32a96edSJens Wiklander TEE_Result res; 86a32a96edSJens Wiklander struct socket_ctx *sock_ctx; 87a32a96edSJens Wiklander TEE_udpSocket_Setup *udp_setup = setup; 88a32a96edSJens Wiklander 89a32a96edSJens Wiklander if (!ctx || !setup || !proto_error) 90a32a96edSJens Wiklander TEE_Panic(0); 91a32a96edSJens Wiklander 92a32a96edSJens Wiklander *proto_error = TEE_SUCCESS; 93a32a96edSJens Wiklander 94a32a96edSJens Wiklander sock_ctx = TEE_Malloc(sizeof(*sock_ctx), TEE_MALLOC_FILL_ZERO); 95a32a96edSJens Wiklander if (!sock_ctx) 96a32a96edSJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 97a32a96edSJens Wiklander 98a32a96edSJens Wiklander res = __tee_socket_pta_open(udp_setup->ipVersion, 99a32a96edSJens Wiklander udp_setup->server_addr, 100a32a96edSJens Wiklander udp_setup->server_port, 101a32a96edSJens Wiklander TEE_ISOCKET_PROTOCOLID_UDP, 102a32a96edSJens Wiklander &sock_ctx->handle); 103a32a96edSJens Wiklander if (res != TEE_SUCCESS) { 104a32a96edSJens Wiklander TEE_Free(sock_ctx); 105a32a96edSJens Wiklander sock_ctx = NULL; 106a32a96edSJens Wiklander } 107a32a96edSJens Wiklander *ctx = (TEE_iSocketHandle)sock_ctx; 108a32a96edSJens Wiklander 109a32a96edSJens Wiklander switch (res) { 110a32a96edSJens Wiklander case TEE_ISOCKET_ERROR_HOSTNAME: 111a32a96edSJens Wiklander *proto_error = res; 112a32a96edSJens Wiklander return TEE_ISOCKET_ERROR_PROTOCOL; 113a32a96edSJens Wiklander case TEE_ISOCKET_UDP_WARNING_UNKNOWN_OUT_OF_BAND: 114a32a96edSJens Wiklander *proto_error = res; 115a32a96edSJens Wiklander return TEE_ISOCKET_WARNING_PROTOCOL; 116a32a96edSJens Wiklander default: 117a32a96edSJens Wiklander return res; 118a32a96edSJens Wiklander } 119a32a96edSJens Wiklander } 120a32a96edSJens Wiklander 121a32a96edSJens Wiklander static TEE_Result sock_close(TEE_iSocketHandle ctx) 122a32a96edSJens Wiklander { 123a32a96edSJens Wiklander TEE_Result res; 124a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 125a32a96edSJens Wiklander 126a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL) 127a32a96edSJens Wiklander return TEE_SUCCESS; 128a32a96edSJens Wiklander 129a32a96edSJens Wiklander res = __tee_socket_pta_close(sock_ctx->handle); 130a32a96edSJens Wiklander TEE_Free(sock_ctx); 131a32a96edSJens Wiklander 132a32a96edSJens Wiklander return res; 133a32a96edSJens Wiklander } 134a32a96edSJens Wiklander 135a32a96edSJens Wiklander static TEE_Result sock_send(TEE_iSocketHandle ctx, const void *buf, 136a32a96edSJens Wiklander uint32_t *length, uint32_t timeout) 137a32a96edSJens Wiklander { 138a32a96edSJens Wiklander TEE_Result res; 139a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 140a32a96edSJens Wiklander 141a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !buf || !length) 142a32a96edSJens Wiklander TEE_Panic(0); 143a32a96edSJens Wiklander 144a32a96edSJens Wiklander res = __tee_socket_pta_send(sock_ctx->handle, buf, length, timeout); 145a32a96edSJens Wiklander sock_ctx->proto_error = res; 146a32a96edSJens Wiklander 147a32a96edSJens Wiklander return res; 148a32a96edSJens Wiklander } 149a32a96edSJens Wiklander 150a32a96edSJens Wiklander static TEE_Result sock_recv(TEE_iSocketHandle ctx, void *buf, uint32_t *length, 151a32a96edSJens Wiklander uint32_t timeout) 152a32a96edSJens Wiklander { 153a32a96edSJens Wiklander TEE_Result res; 154a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 155a32a96edSJens Wiklander 156a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length)) 157a32a96edSJens Wiklander TEE_Panic(0); 158a32a96edSJens Wiklander 159a32a96edSJens Wiklander res = __tee_socket_pta_recv(sock_ctx->handle, buf, length, timeout); 160a32a96edSJens Wiklander sock_ctx->proto_error = res; 161a32a96edSJens Wiklander 162a32a96edSJens Wiklander return res; 163a32a96edSJens Wiklander } 164a32a96edSJens Wiklander 165a32a96edSJens Wiklander static uint32_t sock_error(TEE_iSocketHandle ctx) 166a32a96edSJens Wiklander { 167a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 168a32a96edSJens Wiklander 169a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL) 170a32a96edSJens Wiklander TEE_Panic(0); 171a32a96edSJens Wiklander 172a32a96edSJens Wiklander return sock_ctx->proto_error; 173a32a96edSJens Wiklander } 174a32a96edSJens Wiklander 175a32a96edSJens Wiklander static TEE_Result tcp_ioctl(TEE_iSocketHandle ctx, uint32_t commandCode, 176a32a96edSJens Wiklander void *buf, uint32_t *length) 177a32a96edSJens Wiklander { 178a32a96edSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 179a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 180a32a96edSJens Wiklander 181a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length)) 182a32a96edSJens Wiklander TEE_Panic(0); 183a32a96edSJens Wiklander 184a32a96edSJens Wiklander if (__tee_socket_ioctl_cmd_to_proto(commandCode) == 0) 185a32a96edSJens Wiklander return TEE_SUCCESS; 186a32a96edSJens Wiklander 187a32a96edSJens Wiklander switch (commandCode) { 188a32a96edSJens Wiklander case TEE_TCP_SET_RECVBUF: 189a32a96edSJens Wiklander case TEE_TCP_SET_SENDBUF: 190a32a96edSJens Wiklander res = __tee_socket_pta_ioctl(sock_ctx->handle, commandCode, 191a32a96edSJens Wiklander buf, length); 192a32a96edSJens Wiklander break; 193a32a96edSJens Wiklander default: 194a32a96edSJens Wiklander TEE_Panic(0); 195a32a96edSJens Wiklander } 196a32a96edSJens Wiklander 197a32a96edSJens Wiklander sock_ctx->proto_error = res; 198a32a96edSJens Wiklander 199a32a96edSJens Wiklander return res; 200a32a96edSJens Wiklander } 201a32a96edSJens Wiklander 202a32a96edSJens Wiklander static TEE_Result udp_ioctl(TEE_iSocketHandle ctx, uint32_t commandCode, 203a32a96edSJens Wiklander void *buf, uint32_t *length) 204a32a96edSJens Wiklander { 205a32a96edSJens Wiklander TEE_Result res = TEE_ERROR_GENERIC; 206a32a96edSJens Wiklander struct socket_ctx *sock_ctx = (struct socket_ctx *)ctx; 207a32a96edSJens Wiklander 208a32a96edSJens Wiklander if (ctx == TEE_HANDLE_NULL || !length || (!buf && *length)) 209a32a96edSJens Wiklander TEE_Panic(0); 210a32a96edSJens Wiklander 211a32a96edSJens Wiklander if (__tee_socket_ioctl_cmd_to_proto(commandCode) == 0) 212a32a96edSJens Wiklander return TEE_SUCCESS; 213a32a96edSJens Wiklander 214a32a96edSJens Wiklander switch (commandCode) { 215a32a96edSJens Wiklander case TEE_UDP_CHANGEADDR: 216a32a96edSJens Wiklander case TEE_UDP_CHANGEPORT: 217a32a96edSJens Wiklander res = __tee_socket_pta_ioctl(sock_ctx->handle, commandCode, 218a32a96edSJens Wiklander buf, length); 219a32a96edSJens Wiklander break; 220a32a96edSJens Wiklander default: 221a32a96edSJens Wiklander TEE_Panic(0); 222a32a96edSJens Wiklander } 223a32a96edSJens Wiklander 224a32a96edSJens Wiklander sock_ctx->proto_error = res; 225a32a96edSJens Wiklander 226a32a96edSJens Wiklander return res; 227a32a96edSJens Wiklander } 228a32a96edSJens Wiklander 229a32a96edSJens Wiklander 230a32a96edSJens Wiklander 231a32a96edSJens Wiklander static TEE_iSocket tcp_socket_instance = { 232a32a96edSJens Wiklander .TEE_iSocketVersion = TEE_ISOCKET_VERSION, 233a32a96edSJens Wiklander .protocolID = TEE_ISOCKET_PROTOCOLID_TCP, 234a32a96edSJens Wiklander .open = &tcp_open, 235a32a96edSJens Wiklander .close = &sock_close, 236a32a96edSJens Wiklander .send = &sock_send, 237a32a96edSJens Wiklander .recv = &sock_recv, 238a32a96edSJens Wiklander .error = &sock_error, 239a32a96edSJens Wiklander .ioctl = &tcp_ioctl, 240a32a96edSJens Wiklander }; 241a32a96edSJens Wiklander 242a32a96edSJens Wiklander static TEE_iSocket udp_socket_instance = { 243a32a96edSJens Wiklander .TEE_iSocketVersion = TEE_ISOCKET_VERSION, 244a32a96edSJens Wiklander .protocolID = TEE_ISOCKET_PROTOCOLID_UDP, 245a32a96edSJens Wiklander .open = &udp_open, 246a32a96edSJens Wiklander .close = &sock_close, 247a32a96edSJens Wiklander .send = &sock_send, 248a32a96edSJens Wiklander .recv = &sock_recv, 249a32a96edSJens Wiklander .error = &sock_error, 250a32a96edSJens Wiklander .ioctl = &udp_ioctl, 251a32a96edSJens Wiklander }; 252a32a96edSJens Wiklander 253a32a96edSJens Wiklander TEE_iSocket *const TEE_tcpSocket = &tcp_socket_instance; 254a32a96edSJens Wiklander TEE_iSocket *const TEE_udpSocket = &udp_socket_instance; 255