12e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/** 22e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Copyright(c) 2011 Trusted Logic. All rights reserved. 32e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * 42e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Redistribution and use in source and binary forms, with or without 52e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * modification, are permitted provided that the following conditions 62e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * are met: 72e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * 82e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * * Redistributions of source code must retain the above copyright 92e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * notice, this list of conditions and the following disclaimer. 102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * * Redistributions in binary form must reproduce the above copyright 112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * notice, this list of conditions and the following disclaimer in 122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * the documentation and/or other materials provided with the 132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * distribution. 142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * * Neither the name Trusted Logic nor the names of its 152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * contributors may be used to endorse or promote products derived 162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * from this software without specific prior written permission. 172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * 182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "tee_client_api.h" 322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "schannel6_protocol.h" 332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "s_error.h" 342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "s_version.h" 352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdlib.h> 372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdio.h> 382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <ctype.h> 392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <string.h> 402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <stdarg.h> 412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <assert.h> 422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/ioctl.h> 442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/types.h> 452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/stat.h> 462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/mman.h> 472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <unistd.h> 482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <fcntl.h> 492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <errno.h> 502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <unistd.h> 512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <linux/limits.h> 522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <time.h> 532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <sys/time.h> 542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* 562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * SCX_VERSION_INFORMATION_BUFFER structure description 572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Description of the sVersionBuffer handed over from user space to kernel space 582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * This field is filled after an IOCTL call and handed back to user space 592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleytypedef struct 612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint8_t sDriverDescription[65]; 632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint8_t sSecureWorldDescription[65]; 642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} SCX_VERSION_INFORMATION_BUFFER; 652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* The IOCTLs to the driver */ 682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define IOCTL_SCX_GET_VERSION \ 692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley _IO('z', 0) 702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define IOCTL_SCX_EXCHANGE \ 722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley _IOWR('z', 1, SCHANNEL6_COMMAND) 732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define IOCTL_SCX_GET_DESCRIPTION \ 752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley _IOR('z', 2, SCX_VERSION_INFORMATION_BUFFER) 762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* Expected driver interface version. */ 792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define SM_DRIVER_VERSION 0x04000000 802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define SCX_DEFAULT_DEVICE_NAME "tf_driver" 822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define SCX_PARAM_TYPE_GET(nParamTypes, i) (((nParamTypes) >> (4*i)) & 0xF) 842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define VAR_NOT_USED(variable) do{(void)(variable);}while(0); 862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define SIZE_4KB 0x1000 882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define SIZE_1MB 0x100000 892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* UTILS */ 922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef NDEBUG 942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* Compile-out the traces */ 952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define TRACE_ERROR(...) 962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define TRACE_WARNING(...) 972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define TRACE_INFO(...) 982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else 992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void TRACE_ERROR(const char* format, ...) 1002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 1012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_list ap; 1022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_start(ap, format); 1032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "TRACE: ERROR: "); 1042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley vfprintf(stderr, format, ap); 1052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "\n"); 1062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_end(ap); 1072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 1082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void TRACE_WARNING(const char* format, ...) 1102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 1112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_list ap; 1122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_start(ap, format); 1132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "TRACE: WARNING: "); 1142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley vfprintf(stderr, format, ap); 1152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "\n"); 1162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_end(ap); 1172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 1182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void TRACE_INFO(const char* format, ...) 1202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 1212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_list ap; 1222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_start(ap, format); 1232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "TRACE: "); 1242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley vfprintf(stderr, format, ap); 1252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fprintf(stderr, "\n"); 1262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley va_end(ap); 1272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 1282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif /* NDEBUG */ 1292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* 1322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * ==================================================== 1332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Internal functions 1342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * ===================================================== 1352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley*/ 1362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void scxYield(void) 1382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 1392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sleep(0); 1402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 1412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 1432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* 1462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Exchange a message with the Secure World 1472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * by calling the ioctl command of the linux driver 1482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * 1492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pContext 1502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pCommand a SChannel command message that must have been filled except for the operation parameters 1512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pAnswer a placeholder for the SChannel answer 1522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * @param pOperation a TEEC_Operation structure that contains the operation parameters (and types) 1532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * and is updated with the SChannel answer data as appropriate. This parameter is 1542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * used only for the open and invoke operations 1552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 1562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result scxExchangeMessage( 1572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley IN TEEC_Context* pContext, 1582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley IN SCHANNEL6_COMMAND* pCommand, 1592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley OUT SCHANNEL6_ANSWER* pAnswer, 1602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley IN TEEC_Operation* pOperation) 1612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 1622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nResult = TEEC_SUCCESS; 1632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("scxExchangeMessage[0x%X]\n",pContext); 1652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pOperation != NULL) 1672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Determine message parameters from operation parameters */ 1692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t i; 1702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND_PARAM* pSCXParams; 1712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Note that nParamType is at the same position in an open and an invoke message */ 1732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pCommand->sHeader.nMessageInfo = pOperation->paramTypes; 1742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pCommand->sHeader.nMessageType == SCX_OPEN_CLIENT_SESSION) 1762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParams = pCommand->sOpenClientSession.sParams; 1782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 1792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 1802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* An invoke-command */ 1822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParams = pCommand->sInvokeClientCommand.sParams; 1832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 1842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley for (i = 0; i < 4; i++) 1862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nTEECParamType = SCX_PARAM_TYPE_GET(pOperation->paramTypes, i); 1882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Parameter* pTEECParam = &pOperation->params[i]; 1892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND_PARAM* pSCXParam = &pSCXParams[i]; 1902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 1912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nTEECParamType & SCX_PARAM_TYPE_MEMREF_FLAG) 1922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nTEECParamType & SCX_PARAM_TYPE_REGISTERED_MEMREF_FLAG) 1942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* A registered memref */ 1962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sMemref.hBlock = pTEECParam->memref.parent->imp._hBlock; 1972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nTEECParamType == TEEC_MEMREF_WHOLE) 1982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 1992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* A memref on the whole shared memory */ 2002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Set the direction from the shared memory flags */ 2012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pCommand->sInvokeClientCommand.nParamTypes |= 2022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley (pTEECParam->memref.parent->flags & (SCX_PARAM_TYPE_INPUT_FLAG | SCX_PARAM_TYPE_OUTPUT_FLAG)) 2032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley << (4*i); 2042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sMemref.nSize = pTEECParam->memref.parent->size; 2052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sMemref.nOffset = 0; 2062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 2082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* A partial memref */ 2102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sMemref.nSize = pTEECParam->memref.size; 2112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sMemref.nOffset = pTEECParam->memref.offset; 2122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 2152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* A temporary memref */ 2172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Set nOffset to the address in the client. This allows the server 2182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley to allocate a block with the same alignment and also to 2192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley detect a NULL tmpref. 2202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 2212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sTempMemref.nOffset = (uint32_t)pTEECParam->tmpref.buffer; 2222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sTempMemref.nDescriptor = (uint32_t)pTEECParam->tmpref.buffer; 2232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sTempMemref.nSize = pTEECParam->tmpref.size; 2242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else if (nTEECParamType & SCX_PARAM_TYPE_INPUT_FLAG) 2272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* An input value */ 2292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sValue.a = pTEECParam->value.a; 2302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXParam->sValue.b = pTEECParam->value.b; 2312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pCommand->sHeader.nOperationID = (uint32_t)pAnswer; 2362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = ioctl((S_HANDLE)pContext->imp._hConnection, IOCTL_SCX_EXCHANGE, pCommand); 2382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult != S_SUCCESS) 2392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("scxExchangeMessage[0x%X]: Ioctl returned error: 0x%x (0x%x - %d)\n",pContext,nResult,errno,errno); 2412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley switch(errno) 2422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley case ENOMEM: 2442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult=TEEC_ERROR_OUT_OF_MEMORY; 2452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 2462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley case EACCES: 2472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult=TEEC_ERROR_ACCESS_DENIED; 2482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 2492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley default: 2502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult=TEEC_ERROR_COMMUNICATION; 2512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 2522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pOperation != NULL) 2562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Update the operation parameters from the answer message */ 2582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t i; 2592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER_PARAM * pSCXAnswers; 2602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pAnswer->sHeader.nMessageType == SCX_OPEN_CLIENT_SESSION) 2612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Open session */ 2632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXAnswers = pAnswer->sOpenClientSession.sAnswers; 2642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 2662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Invoke case */ 2682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSCXAnswers = pAnswer->sInvokeClientCommand.sAnswers; 2692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley for (i = 0; i < 4; i++) 2722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nSCXParamType; 2742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nSCXParamType = SCX_GET_PARAM_TYPE(pCommand->sHeader.nMessageInfo, i); 2752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nSCXParamType & SCX_PARAM_TYPE_OUTPUT_FLAG) 2762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nSCXParamType & SCX_PARAM_TYPE_MEMREF_FLAG) 2782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Trick: the size field is at the same position in a memref or a tmpref */ 2802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pOperation->params[i].memref.size = pSCXAnswers[i].sSize.nSize; 2812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 2832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 2842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* An output value */ 2852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pOperation->params[i].value.a = pSCXAnswers[i].sValue.a; 2862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pOperation->params[i].value.b = pSCXAnswers[i].sValue.b; 2872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 2912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nResult; 2932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 2942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 2962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 2972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void* scxAllocateSharedMemory( 2982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley IN uint32_t nLength) 2992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 3002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nLength == 0) 3012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* This is valid, although we don't want to call mmap. 3032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley Just return a dummy non-NULL pointer */ 3042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return (void*)0x10; 3052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 3072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return mmap( 3092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 0,nLength, 3102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley PROT_READ | PROT_WRITE, 3112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley MAP_SHARED | MAP_ANONYMOUS, 3122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 0,0); 3132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 3152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 3172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void scxReleaseSharedMemory(IN void* pBuffer, 3192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley IN uint32_t nLength) 3202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 3212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nLength == 0) 3222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return; 3242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (munmap(pBuffer, nLength)!= 0) 3262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_WARNING("scxReleaseSharedMemory returned 0x%x \n",errno); 3282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 3302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 3312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyuint64_t scxGetCurrentTime(void) 3332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 3342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint64_t currentTime = 0; 3352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley struct timeval now; 3362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley gettimeofday(&now,NULL); 3382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley currentTime = now.tv_sec; 3392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley currentTime = (currentTime * 1000) + (now.tv_usec / 1000); 3402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return currentTime; 3422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 3432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* ------------------------------------------------------------------------ */ 3442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* 3462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * ==================================================== 3472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * TEE Client API 3482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * ===================================================== 3492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley*/ 3502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/** 3522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Get a time-limit equal to now + relative timeout expressed in milliseconds. 3532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley **/ 3542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_GetTimeLimit( 3552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* sContext, 3562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nTimeout, 3572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_TimeLimit* sTimeLimit) 3582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 3592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint64_t nTimeLimit = 0; 3602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley VAR_NOT_USED(sContext); 3612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_GetTimeLimit(0x%X, %u ms)", sContext, nTimeout); 3632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nTimeout == 0xFFFFFFFF ) 3652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Infinite timeout */ 3672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nTimeLimit = SCTIME_INFINITE; 3682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 3702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nTimeLimit = scxGetCurrentTime() + nTimeout; 3722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("GetTimeLimit %ld\n",nTimeLimit); 3742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memcpy(sTimeLimit, &nTimeLimit, sizeof(TEEC_TimeLimit)); 3752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 3762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 3782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_InitializeContext( 3792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley const char* pDeviceName, 3802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* pContext) 3812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 3822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nError = TEEC_SUCCESS; 3842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley S_HANDLE hDriver = S_HANDLE_NULL; 3852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley char sFullDeviceName[PATH_MAX]; 3862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nVersion; 3872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if(pDeviceName == NULL) 3892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pDeviceName = SCX_DEFAULT_DEVICE_NAME; 3912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 3922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley strcpy(sFullDeviceName, "/dev/"); 3932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley strcat(sFullDeviceName, pDeviceName); 3942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley hDriver = open(sFullDeviceName, O_RDWR, 0); 3962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 3972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (hDriver == (uint32_t)-1) 3982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 3992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("scxOpen: open() failed 0x%x\n", errno); 4002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley switch(errno) 4012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 4022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley case ENOMEM: 4032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = TEEC_ERROR_OUT_OF_MEMORY; 4042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 4052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley case EINTR: 4062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 4072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley default: 4082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = TEEC_ERROR_COMMUNICATION; 4092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 4102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fcntl(hDriver, F_SETFD, FD_CLOEXEC); 4132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nVersion = ioctl(hDriver, IOCTL_SCX_GET_VERSION); 4142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nVersion != SM_DRIVER_VERSION) 4152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 4162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("scxOpen: Not expected driver version: 0x%x instead of 0x%x\n", nVersion,SM_DRIVER_VERSION); 4172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley switch(errno) 4182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 4192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley case ENOMEM: 4202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError=TEEC_ERROR_OUT_OF_MEMORY; 4212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 4222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley default: 4232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError=TEEC_ERROR_COMMUNICATION; 4242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley break; 4252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley close(hDriver); 4272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyerror: 4292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if(nError == TEEC_SUCCESS) 4302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 4312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pContext->imp._hConnection = hDriver; 4322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 4342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 4352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("scxOpen failed 0x%x\n", nError); 4362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pContext->imp._hConnection = 0; 4372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 4382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nError; 4402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 4412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 4432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_FinalizeContext(TEEC_Context* pContext) 4442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 4452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_FinalizeContext[0x%X]", pContext); 4462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pContext == NULL) return; 4482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley close(pContext->imp._hConnection); 4502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pContext->imp._hConnection = 0; 4512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 4522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 4542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_OpenSession ( 4552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 4562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Session* session, /* OUT */ 4572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley const TEEC_UUID* destination, /* The trusted application UUID we want to open the session with */ 4582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t connectionMethod, /* LoginType*/ 4592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley void* connectionData, /* LoginData */ 4602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Operation* operation, /* payload. If operation is NULL then no data buffers are exchanged with the Trusted Application, and the operation cannot be cancelled by the Client Application */ 4612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t* errorOrigin) 4622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 4632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_OpenSessionEx(context, 4642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley session, 4652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley NULL, 4662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley destination, 4672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley connectionMethod, 4682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley connectionData, 4692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation, 4702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley errorOrigin); 4712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 4722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 4742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_CloseSession (TEEC_Session* session) 4752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 4762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context; 4772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 4782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sCommand; 4792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (session == NULL) return; 4802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley context = session->imp._pContext; 4812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sCommand,0,sizeof(sCommand)); 4822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageType = SCX_CLOSE_CLIENT_SESSION; 4832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_CLOSE_CLIENT_SESSION_COMMAND) 4842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t); 4852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sCloseClientSession.hClientSession = session->imp._hClientSession; 4862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley scxExchangeMessage(context, &sCommand, &sAnswer, NULL); 4872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* we ignore the error code of scxExchangeMessage */ 4882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley session->imp._hClientSession = S_HANDLE_NULL; 4892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley session->imp._pContext = NULL; 4902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 4912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 4922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 4932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_InvokeCommand( 4942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Session* session, 4952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t commandID, 4962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Operation* operation, 4972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t* errorOrigin) 4982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 4992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_InvokeCommandEx(session, 5002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley NULL, 5012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley commandID, 5022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation, 5032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley errorOrigin); 5042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 5052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 5082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* Used to implement both register and allocate */ 5092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic TEEC_Result TEEC_RegisterSharedMemory0( 5102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 5112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_SharedMemory* sharedMem) 5122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 5132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nResult; 5142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sCommand; 5152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 5162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_RegisterSharedMemory0 (%p, %p)",context, sharedMem); 5182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sCommand, 0, sizeof(sCommand)); 5192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nMessageSize = (sizeof(SCHANNEL6_REGISTER_SHARED_MEMORY_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/4; 5212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nMessageType = SCX_REGISTER_SHARED_MEMORY; 5222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nMemoryFlags = sharedMem->flags; 5232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nSharedMemSize = sharedMem->size; 5242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nSharedMemStartOffset = 0; 5252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sRegisterSharedMemory.nSharedMemDescriptors[0] = (uint32_t)sharedMem->buffer; 5262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = scxExchangeMessage(context, 5272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley &sCommand, 5282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley &sAnswer, 5292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley NULL); 5302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult == TEEC_SUCCESS) 5312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 5322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = sAnswer.sRegisterSharedMemory.nErrorCode; 5332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 5342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult == TEEC_SUCCESS) 5352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 5362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._pContext = context; 5372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._hBlock = sAnswer.sRegisterSharedMemory.hBlock; 5382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 5392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nResult; 5402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 5412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 5442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_RegisterSharedMemory( 5452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 5462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_SharedMemory* sharedMem) 5472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 5482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_RegisterSharedMemory (%p)",context); 5492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._pContext = NULL; 5502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._hBlock = S_HANDLE_NULL; 5512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._bAllocated = false; 5522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_RegisterSharedMemory0(context, sharedMem); 5532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 5542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 5562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_AllocateSharedMemory( 5572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 5582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_SharedMemory* sharedMem) 5592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 5602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nResult; 5612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_AllocateSharedMemory (%p)",context); 5622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._pContext = NULL; 5642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._hBlock = S_HANDLE_NULL; 5652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->buffer = scxAllocateSharedMemory(sharedMem->size); 5662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (sharedMem->buffer == NULL) 5672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 5682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_ERROR_OUT_OF_MEMORY; 5692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 5702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._bAllocated = true; 5712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = TEEC_RegisterSharedMemory0(context, sharedMem); 5722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult != TEEC_SUCCESS) 5732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 5742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley scxReleaseSharedMemory(sharedMem->buffer,sharedMem->size); 5752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->buffer = NULL; 5762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 5772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nResult; 5782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 5792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 5812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_ReleaseSharedMemory ( 5822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_SharedMemory* sharedMem) 5832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 5842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 5852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sMessage; 5862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context; 5872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 5882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley context = (TEEC_Context *)sharedMem->imp._pContext; 5892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sMessage, 0, sizeof(SCHANNEL6_COMMAND)); 5902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sReleaseSharedMemory.nMessageType = SCX_RELEASE_SHARED_MEMORY; 5912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sReleaseSharedMemory.nMessageSize = (sizeof(SCHANNEL6_RELEASE_SHARED_MEMORY_COMMAND) 5922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t); 5932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sReleaseSharedMemory.hBlock = sharedMem->imp._hBlock; 5942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley scxExchangeMessage(context,&sMessage, &sAnswer, NULL); 5952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (sharedMem->imp._bAllocated) 5962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 5972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley scxReleaseSharedMemory(sharedMem->buffer,sharedMem->size); 5982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Update parameters: 5992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * In this case the Implementation MUST set the buffer and size fields of the sharedMem structure 6002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * to NULL and 0 respectively before returning. 6012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 6022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->buffer = NULL; 6032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->size = 0; 6042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._pContext = NULL; 6062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sharedMem->imp._hBlock = S_HANDLE_NULL; 6072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 6082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 6102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_RequestCancellation(TEEC_Operation* operation) 6112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 6122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nOperationState; 6132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nResult; 6142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (operation == NULL) return; 6162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyretry: 6182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nOperationState = operation->started; 6192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nOperationState == 2) 6202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Operation already finished. Return immediately */ 6222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return; 6232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else if (nOperationState == 1) 6252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Operation is in progress */ 6272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context; 6282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 6292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sMessage; 6302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley context = operation->imp._pContext; 6322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sMessage,0,sizeof(sMessage)); 6342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sHeader.nMessageType = SCX_CANCEL_CLIENT_OPERATION; 6352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sHeader.nMessageSize = (sizeof(SCHANNEL6_CANCEL_CLIENT_OPERATION_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/4; 6362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sCancelClientOperation.hClientSession = operation->imp._hSession; 6372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sMessage.sCancelClientOperation.nCancellationID = (uint32_t)operation; 6382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = scxExchangeMessage(context,&sMessage, &sAnswer, NULL); 6392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult != TEEC_SUCCESS) 6412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Communication failure. Ignore the error: the operation is already cancelled anyway */ 6432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return; 6442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (sAnswer.sCancelClientOperation.nErrorCode == S_SUCCESS) 6462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Command was successfully cancelled */ 6482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return; 6492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Otherwise, the command has not yet reached the secure world or has already finished and we must retry */ 6512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* This applies as well when nOperationState == 0. In this case, the operation has not yet 6532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley started yet and we don't even have a pointer to the context */ 6542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley scxYield(); 6552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto retry; 6562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 6572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 6602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_ReadSignatureFile( 6612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley void** ppSignatureFile, 6622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t* pnSignatureFileLength) 6632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 6642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nErrorCode = TEEC_SUCCESS; 6652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nBytesRead; 6672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nSignatureSize = 0; 6682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint8_t* pSignature = NULL; 6692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley FILE* pSignatureFile = NULL; 6702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley char sFileName[PATH_MAX + 1 + 5]; /* Allocate room for the signature extension */ 6712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley long nFileSize; 6722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *pnSignatureFileLength = 0; 6742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *ppSignatureFile = NULL; 6752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (realpath("/proc/self/exe", sFileName) == NULL) 6772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_ReadSignatureFile: realpath failed [%d]", errno); 6792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_ERROR_OS; 6802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Work out the signature file name */ 6832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley strcat(sFileName, ".ssig"); 6842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSignatureFile = fopen(sFileName, "rb"); 6862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pSignatureFile == NULL) 6872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* Signature doesn't exist */ 6892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return TEEC_ERROR_ITEM_NOT_FOUND; 6902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 6922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (fseek(pSignatureFile, 0, SEEK_END) != 0) 6932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 6942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_ReadSignatureFile: fseek(%s) failed [%d]", 6952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sFileName, errno); 6962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nErrorCode = TEEC_ERROR_OS; 6972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 6982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 6992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nFileSize = ftell(pSignatureFile); 7012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nFileSize < 0) 7022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_ReadSignatureFile: ftell(%s) failed [%d]", 7042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sFileName, errno); 7052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nErrorCode = TEEC_ERROR_OS; 7062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 7072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nSignatureSize = (uint32_t)nFileSize; 7102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nSignatureSize != 0) 7122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley pSignature = malloc(nSignatureSize); 7142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (pSignature == NULL) 7152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_ReadSignatureFile: Heap - Out of memory for %u bytes", 7172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nSignatureSize); 7182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nErrorCode = TEEC_ERROR_OUT_OF_MEMORY; 7192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 7202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley rewind(pSignatureFile); 7232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nBytesRead = fread(pSignature, 1, nSignatureSize, pSignatureFile); 7252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nBytesRead < nSignatureSize) 7262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_ReadSignatureFile: fread failed [%d]", errno); 7282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nErrorCode = TEEC_ERROR_OS; 7292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley goto error; 7302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fclose(pSignatureFile); 7342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *pnSignatureFileLength = nSignatureSize; 7362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *ppSignatureFile = pSignature; 7372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return S_SUCCESS; 7392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyerror: 7412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley fclose(pSignatureFile); 7422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley free(pSignature); 7432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nErrorCode; 7452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 7462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 7482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_OpenSessionEx ( 7492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 7502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Session* session, /* OUT */ 7512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley const TEEC_TimeLimit* timeLimit, 7522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley const TEEC_UUID* destination, /* The trusted application UUID we want to open the session with */ 7532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t connectionMethod, /* LoginType*/ 7542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley void* connectionData, /* LoginData */ 7552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Operation* operation, /* payload. If operation is NULL then no data buffers are exchanged with the Trusted Application, and the operation cannot be cancelled by the Client Application */ 7562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t* returnOrigin) 7572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 7582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nError; 7592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nReturnOrigin; 7602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 7612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sCommand; 7622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sCommand, 0, sizeof(SCHANNEL6_COMMAND)); 7642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageType = SCX_OPEN_CLIENT_SESSION; 7662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_OPEN_CLIENT_SESSION_COMMAND) - 20 -sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t); 7672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (timeLimit == NULL) 7682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sOpenClientSession.sTimeout = SCTIME_INFINITE; 7702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 7722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sOpenClientSession.sTimeout = *(uint64_t*)timeLimit; 7742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sOpenClientSession.sDestinationUUID = *((S_UUID*)destination); 7762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sOpenClientSession.nLoginType = connectionMethod; 7772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if ((connectionMethod == TEEC_LOGIN_GROUP)||(connectionMethod == TEEC_LOGIN_GROUP_APPLICATION)) 7782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* connectionData MUST point to a uint32_t which contains the group 7802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * which this Client Application wants to connect as. The Linux Driver 7812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * is responsible for securely ensuring that the Client Application 7822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * instance is actually a member of this group. 7832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 7842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (connectionData != NULL) 7852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *(uint32_t*)sCommand.sOpenClientSession.sLoginData = *(uint32_t*)connectionData; 7872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageSize += sizeof(uint32_t); 7882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sOpenClientSession.nCancellationID = (uint32_t)operation; // used for TEEC_RequestCancellation 7912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (operation != NULL) 7932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 7942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._pContext = context; 7952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._hSession = S_HANDLE_NULL; 7962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->started = 1; 7972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 7982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 7992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = scxExchangeMessage(context, &sCommand, &sAnswer, operation); 8002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (operation != NULL) operation->started = 2; 8022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nError != TEEC_SUCCESS) 8042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nReturnOrigin = TEEC_ORIGIN_COMMS; 8062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 8082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = sAnswer.sOpenClientSession.nErrorCode; 8102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nReturnOrigin = sAnswer.sOpenClientSession.nReturnOrigin; 8112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (returnOrigin != NULL) *returnOrigin = nReturnOrigin; 8142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nError == S_SUCCESS) 8162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley session->imp._hClientSession = sAnswer.sOpenClientSession.hClientSession; 8182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley session->imp._pContext = context; 8192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nError; 8222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 8232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 8252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyTEEC_Result TEEC_InvokeCommandEx( 8262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Session* session, 8272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley const TEEC_TimeLimit* timeLimit, 8282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t commandID, 8292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Operation* operation, 8302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t* returnOrigin) 8312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 8322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Result nError; 8332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_ANSWER sAnswer; 8342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCHANNEL6_COMMAND sCommand; 8352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nReturnOrigin; 8362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context * context; 8372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley context = (TEEC_Context *)session->imp._pContext; 8392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(&sCommand, 0, sizeof(SCHANNEL6_COMMAND)); 8402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageType = SCX_INVOKE_CLIENT_COMMAND; 8422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sHeader.nMessageSize = (sizeof(SCHANNEL6_INVOKE_CLIENT_COMMAND_COMMAND) - sizeof(SCHANNEL6_COMMAND_HEADER))/sizeof(uint32_t); 8432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sInvokeClientCommand.nClientCommandIdentifier = commandID; 8442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (timeLimit == NULL) 8452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sInvokeClientCommand.sTimeout = SCTIME_INFINITE; 8472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 8492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sInvokeClientCommand.sTimeout = *(uint64_t*)timeLimit; 8512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sInvokeClientCommand.hClientSession = session->imp._hClientSession; 8532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley sCommand.sInvokeClientCommand.nCancellationID = (uint32_t)operation; // used for TEEC_RequestCancellation 8542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (operation != NULL) 8562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._pContext = session->imp._pContext; 8582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._hSession = session->imp._hClientSession; 8592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->started = 1; 8602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = scxExchangeMessage(context, &sCommand, &sAnswer, operation); 8632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (operation != NULL) 8652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->started = 2; 8672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._hSession = S_HANDLE_NULL; 8682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley operation->imp._pContext = NULL; 8692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nError != TEEC_SUCCESS) 8722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nReturnOrigin = TEEC_ORIGIN_COMMS; 8742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley else 8762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 8772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nError = sAnswer.sInvokeClientCommand.nErrorCode; 8782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nReturnOrigin = sAnswer.sInvokeClientCommand.nReturnOrigin; 8792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 8802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (returnOrigin != NULL) *returnOrigin = nReturnOrigin; 8822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return nError; 8842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 8862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley//----------------------------------------------------------------------------------------------------- 8882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* 8892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Retrieves information about the implementation 8902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */ 8912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_GetImplementationInfo( 8922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_Context* context, 8932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_ImplementationInfo* description) 8942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 8952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_INFO("TEEC_GetImplementationInfo"); 8962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(description, 0, sizeof(TEEC_ImplementationInfo)); 8982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 8992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley strcpy(description->apiDescription, S_VERSION_STRING); 9002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 9012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (context != NULL) 9022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 9032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley SCX_VERSION_INFORMATION_BUFFER sInfoBuffer; 9042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley uint32_t nResult; 9052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 9062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley nResult = ioctl((S_HANDLE)context->imp._hConnection, IOCTL_SCX_GET_DESCRIPTION, &sInfoBuffer); 9072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley if (nResult != S_SUCCESS) 9082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley { 9092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TRACE_ERROR("TEEC_GetImplementationInfo[0x%X]: ioctl returned error: 0x%x ( %d)\n",context, nResult, errno); 9102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley return; 9112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 9122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 9132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memcpy(description->commsDescription, sInfoBuffer.sDriverDescription, 64); 9142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley description->commsDescription[64] = 0; 9152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memcpy(description->TEEDescription, sInfoBuffer.sSecureWorldDescription, 64); 9162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley description->TEEDescription[64] = 0; 9172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 9182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley} 9192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 9202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid TEEC_GetImplementationLimits( 9212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley TEEC_ImplementationLimits* limits) 9222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{ 9232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley memset(limits, 0, sizeof(TEEC_ImplementationLimits)); 9242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley 9252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley /* A temp mem ref can not be mapped on more than 1Mb */ 9262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley limits->pageSize = SIZE_4KB; 9272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley limits->tmprefMaxSize = SIZE_1MB; 9282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley limits->sharedMemMaxSize = SIZE_1MB * 8; 9292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley } 930