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