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