summaryrefslogtreecommitdiff
path: root/mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp')
-rw-r--r--mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp849
1 files changed, 0 insertions, 849 deletions
diff --git a/mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp b/mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp
deleted file mode 100644
index 0568935..0000000
--- a/mobicore/MobiCoreDriverLib/ClientLib/GP/tee_client_api.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#undef LOG_TAG
-#define LOG_TAG "GpClient"
-#include "tee_client_api.h"
-#include "log.h"
-#include "MobiCoreDriverApi.h"
-#include "Mci/mcinq.h"
-#include <stdlib.h>
-#include <sys/mman.h>
-#include "GpTci.h"
-#include "../Session.h"
-
-//------------------------------------------------------------------------------
-// Macros
-#define _TEEC_GET_PARAM_TYPE(t, i) (((t) >> (4*i)) & 0xF)
-
-//Parameter number
-#define _TEEC_PARAMETER_NUMBER 4
-
-
-//------------------------------------------------------------------------------
-//Local satic functions
-static void _libUuidToArray(
- const TEEC_UUID *uuid,
- uint8_t *uuid_str);
-
-
-static TEEC_Result _TEEC_UnwindOperation(
- _TEEC_TCI *tci,
- mcSessionHandle_t *handle,
- TEEC_Operation *operation,
- bool copyValues,
- uint32_t *returnOrigin);
-
-static TEEC_Result _TEEC_SetupOperation(
- _TEEC_TCI *tci,
- mcSessionHandle_t *handle,
- TEEC_Operation *operation,
- uint32_t *returnOrigin);
-
-//------------------------------------------------------------------------------
-static void _libUuidToArray(
- const TEEC_UUID *uuid,
- uint8_t *uuidArr)
-{
- uint8_t *pIdentifierCursor = (uint8_t *)uuid;
- /* offsets and syntax constants. See explanations above */
-#ifdef S_BIG_ENDIAN
- uint32_t offsets = 0;
-#else
- uint32_t offsets = 0xF1F1DF13;
-#endif
- uint32_t i;
-
- for (i = 0; i < sizeof(TEEC_UUID); i++) {
- /* Two-digit hex number */
- uint8_t number;
- int32_t offset = ((int32_t)((offsets & 0xF) << 28)) >> 28;
- number = pIdentifierCursor[offset];
- offsets >>= 4;
- pIdentifierCursor++;
-
- uuidArr[i] = number;
- }
-}
-
-//------------------------------------------------------------------------------
-static TEEC_Result _TEEC_SetupOperation(
- _TEEC_TCI *tci,
- mcSessionHandle_t *handle,
- TEEC_Operation *operation,
- uint32_t *returnOrigin)
-{
- uint32_t i;
- _TEEC_ParameterInternal *imp;
- TEEC_Parameter *ext;
- mcResult_t mcRet = MC_DRV_OK;
- TEEC_Result teecResult = TEEC_SUCCESS;
-
- LOG_I(" %s()", __func__);
-
- tci->operation.isCancelled = false;
- tci->operation.paramTypes = 0;
-
- //operation can be NULL
- if (operation != NULL) {
-
- operation->started = 1;
-
- //This design allows a non-NULL buffer with a size of 0 bytes to allow trivial integration with any
- //implementations of the C library malloc, in which is valid to allocate a zero byte buffer and receive a non-
- //NULL pointer which may not be de-referenced in return.
-
- for (i = 0; i < _TEEC_PARAMETER_NUMBER; i++) {
- uint8_t paramType = _TEEC_GET_PARAM_TYPE(operation->paramTypes, i);
-
- imp = &tci->operation.params[i];
- ext = &operation->params[i];
-
- switch (paramType) {
- case TEEC_VALUE_OUTPUT:
- LOG_I(" cycle %d, TEEC_VALUE_OUTPUT", i);
- break;
- case TEEC_NONE:
- LOG_I(" cycle %d, TEEC_NONE", i);
- break;
- case TEEC_VALUE_INPUT:
- case TEEC_VALUE_INOUT: {
- LOG_I(" cycle %d, TEEC_VALUE_IN*", i);
- imp->value.a = ext->value.a;
- imp->value.b = ext->value.b;
- break;
- }
- case TEEC_MEMREF_TEMP_INPUT:
- case TEEC_MEMREF_TEMP_OUTPUT:
- case TEEC_MEMREF_TEMP_INOUT: {
- //TODO: A Temporary Memory Reference may be null, which can be used to denote a special case for the
- //parameter. Output Memory References that are null are typically used to request the required output size.
- LOG_I(" cycle %d, TEEC_TEMP_IN*", i);
- imp->memref.mapInfo.sVirtualLen = 0;
- if ((ext->tmpref.size) && (ext->tmpref.buffer)) {
- mcRet = mcMap(handle, ext->tmpref.buffer, ext->tmpref.size, &imp->memref.mapInfo);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
- *returnOrigin = TEEC_ORIGIN_COMMS;
- i = _TEEC_PARAMETER_NUMBER;
- }
- } else {
- LOG_I(" cycle %d, TEEC_TEMP_IN* - zero pointer or size", i);
- }
- break;
- }
- case TEEC_MEMREF_WHOLE: {
- LOG_I(" cycle %d, TEEC_MEMREF_WHOLE", i);
- imp->memref.mapInfo.sVirtualLen = 0;
- if (ext->memref.parent->size) {
- mcRet = mcMap(handle, ext->memref.parent->buffer, ext->memref.parent->size, &imp->memref.mapInfo);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
- *returnOrigin = TEEC_ORIGIN_COMMS;
- i = _TEEC_PARAMETER_NUMBER;
- }
- }
- /* We don't transmit that the mem ref is the whole shared mem */
- /* Magic number 4 means that it is a mem ref */
- paramType = ext->memref.parent->flags | 4;
- break;
- }
- case TEEC_MEMREF_PARTIAL_INPUT:
- case TEEC_MEMREF_PARTIAL_OUTPUT:
- case TEEC_MEMREF_PARTIAL_INOUT: {
- LOG_I(" cycle %d, TEEC_PARTIAL_IN*", i);
- //Check data flow consistency
- if ((((ext->memref.parent->flags & (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) == TEEC_MEM_INPUT) &&
- (paramType == TEEC_MEMREF_PARTIAL_OUTPUT)) ||
- (((ext->memref.parent->flags & (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) == TEEC_MEM_OUTPUT) &&
- (paramType == TEEC_MEMREF_PARTIAL_INPUT))) {
- LOG_E("PARTIAL data flow inconsistency");
- *returnOrigin = TEEC_ORIGIN_API;
- teecResult = TEEC_ERROR_BAD_PARAMETERS;
- i = _TEEC_PARAMETER_NUMBER;
- break;
- }
- /* We don't transmit that the mem ref is partial */
- paramType &= TEEC_MEMREF_TEMP_INOUT;
-
- if (ext->memref.offset + ext->memref.size > ext->memref.parent->size) {
- LOG_E("PARTIAL offset/size error");
- *returnOrigin = TEEC_ORIGIN_API;
- teecResult = TEEC_ERROR_BAD_PARAMETERS;
- i = _TEEC_PARAMETER_NUMBER;
- break;
- }
- imp->memref.mapInfo.sVirtualLen = 0;
- if (ext->memref.size) {
- mcRet = mcMap(handle, (uint8_t *)ext->memref.parent->buffer + ext->memref.offset, ext->memref.size, &imp->memref.mapInfo);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcMap failed, mcRet=0x%08X", mcRet);
- *returnOrigin = TEEC_ORIGIN_COMMS;
- i = _TEEC_PARAMETER_NUMBER;
- }
- }
- break;
- }
- default:
- LOG_E("cycle %d, default", i);
- *returnOrigin = TEEC_ORIGIN_API;
- teecResult = TEEC_ERROR_BAD_PARAMETERS;
- i = _TEEC_PARAMETER_NUMBER;
- break;
- }
- tci->operation.paramTypes |= (paramType<<i*4);
- }
-
- if (tci->operation.isCancelled) {
- LOG_E("the operation has been cancelled in COMMS");
- *returnOrigin = TEEC_ORIGIN_COMMS;
- teecResult = TEEC_ERROR_CANCEL;
- }
-
- if ((mcRet != MC_DRV_OK) || (teecResult != TEEC_SUCCESS)) {
- uint32_t retOrigIgnored;
- _TEEC_UnwindOperation(tci, handle, operation, false, &retOrigIgnored);
- //Zeroing out tci->operation
- memset(&tci->operation, 0, sizeof(tci->operation));
- if (teecResult != TEEC_SUCCESS) return teecResult;
- return TEEC_ERROR_GENERIC;
- }
- }
-
- //Copy version indicator field
- memcpy(tci->header, "TCIGP000", sizeof(tci->header));
-
- // Fill in invalid values for secure world to overwrite
- tci->returnStatus = TEEC_ERROR_BAD_STATE;
-
- // Signal completion of request writing
- tci->ready = 1;
-
- return teecResult;
-}
-
-//------------------------------------------------------------------------------
-static TEEC_Result _TEEC_UnwindOperation(
- _TEEC_TCI *tci,
- mcSessionHandle_t *handle,
- TEEC_Operation *operation,
- bool copyValues,
- uint32_t *returnOrigin)
-{
- uint32_t i;
- _TEEC_ParameterInternal *imp;
- TEEC_Parameter *ext;
- uint8_t *buffer;
-
- //operation can be NULL
- if (operation == NULL) return TEEC_SUCCESS;
-
- LOG_I(" %s()", __func__);
-
- operation->started = 2;
-
- // Some sanity checks
- if (tci->returnOrigin == 0 ||
- ((tci->returnOrigin != TEEC_ORIGIN_TRUSTED_APP) && (tci->returnStatus != TEEC_SUCCESS))) {
- *returnOrigin = TEEC_ORIGIN_COMMS;
- return TEEC_ERROR_COMMUNICATION;
- }
- *returnOrigin = tci->returnOrigin;
-
- //Clear sVirtualLen to unMap further
- for (i = 0; i < _TEEC_PARAMETER_NUMBER; i++) {
- imp = &tci->operation.params[i];
- ext = &operation->params[i];
- buffer = NULL;
-
- switch (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i)) {
- case TEEC_VALUE_INPUT:
- LOG_I(" cycle %d, TEEC_VALUE_INPUT", i);
- break;
- case TEEC_NONE:
- LOG_I(" cycle %d, TEEC_NONE", i);
- break;
- case TEEC_VALUE_OUTPUT:
- case TEEC_VALUE_INOUT: {
- LOG_I(" cycle %d, TEEC_VALUE_*OUT", i);
- if (copyValues) {
- ext->value.a = imp->value.a;
- ext->value.b = imp->value.b;
- }
- break;
- }
- case TEEC_MEMREF_TEMP_OUTPUT:
- case TEEC_MEMREF_TEMP_INPUT:
- case TEEC_MEMREF_TEMP_INOUT: {
- LOG_I(" cycle %d, TEEC_TEMP*", i);
- if ((copyValues) && (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) != TEEC_MEMREF_TEMP_INPUT)) {
- ext->tmpref.size = imp->memref.outputSize;
- }
- buffer = (uint8_t *)ext->tmpref.buffer;
- break;
- }
- case TEEC_MEMREF_WHOLE: {
- LOG_I(" cycle %d, TEEC_MEMREF_WHOLE", i);
- if ((copyValues) && (ext->memref.parent->flags != TEEC_MEM_INPUT)) {
- ext->memref.size = imp->memref.outputSize;
- }
- buffer = (uint8_t *)ext->memref.parent->buffer;
- break;
- }
-
- case TEEC_MEMREF_PARTIAL_OUTPUT:
- case TEEC_MEMREF_PARTIAL_INOUT:
- case TEEC_MEMREF_PARTIAL_INPUT: {
- LOG_I(" cycle %d, TEEC_MEMREF_PARTIAL*", i);
- if ((copyValues) && (_TEEC_GET_PARAM_TYPE(operation->paramTypes, i) != TEEC_MEMREF_PARTIAL_INPUT)) {
- ext->memref.size = imp->memref.outputSize;
- }
- buffer = (uint8_t *)ext->memref.parent->buffer + ext->memref.offset;
- break;
- }
- default:
- LOG_E("cycle %d, bad parameter", i);
- break;
- }
-
- if ((buffer != NULL) && (imp->memref.mapInfo.sVirtualLen != 0)) {
- // This function assumes that we cannot handle error of mcUnmap
- (void)mcUnmap(handle, buffer, &imp->memref.mapInfo);
- }
- }
-
- return tci->returnStatus;
-}
-
-//------------------------------------------------------------------------------
-//TEEC_InitializeContext: TEEC_SUCCESS, Another error code from Table 4-2.
-//MC_DRV_OK, MC_DRV_ERR_INVALID_OPERATION, MC_DRV_ERR_DAEMON_UNREACHABLE, MC_DRV_ERR_UNKNOWN_DEVICE, MC_DRV_ERR_INVALID_DEVICE_FILE
-TEEC_Result TEEC_InitializeContext(
- const char */*name*/,
- TEEC_Context *context)
-{
- LOG_I("== %s() ==============", __func__);
-
- if (context == NULL) return TEEC_ERROR_BAD_PARAMETERS;
- context->imp.reserved = MC_DEVICE_ID_DEFAULT;
-
- switch (mcOpenDevice(MC_DEVICE_ID_DEFAULT)) {
- case MC_DRV_OK:
- return TEEC_SUCCESS;
- case MC_DRV_ERR_DAEMON_UNREACHABLE:
- return TEEC_ERROR_COMMUNICATION;
- case MC_DRV_ERR_UNKNOWN_DEVICE:
- return TEEC_ERROR_BAD_PARAMETERS;
- case MC_DRV_ERR_INVALID_DEVICE_FILE:
- return TEEC_ERROR_COMMUNICATION;
- }
-
- return TEEC_ERROR_GENERIC;
-}
-
-//------------------------------------------------------------------------------
-//mcCloseDevice: MC_DRV_OK, MC_DRV_ERR_UNKNOWN_DEVICE, MC_DRV_ERR_SESSION_PENDING, MC_DRV_ERR_DAEMON_UNREACHABLE
-//TEEC_FinalizeContext: void
-
-//TODO: The implementation of this function MUST NOT be able to fail: after this function returns the Client
-//Application must be able to consider that the Context has been closed.
-
-void TEEC_FinalizeContext(TEEC_Context *context)
-{
- mcResult_t mcRet;
-
- LOG_I("== %s() ==============", __func__);
-
- //The parameter context MUST point to an initialized TEE Context.
- //Just realized: The function implementation MUST do nothing if context is NULL.
- if (context == NULL) {
- LOG_E("context is NULL");
- return;
- }
-
- //The implementation of this function MUST NOT be able to fail: after this function returns the Client
- //Application must be able to consider that the Context has been closed.
- mcRet = mcCloseDevice(context->imp.reserved);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcCloseDevice failed (%08x)", mcRet);
- /* continue even in case of error */;
- }
-}
-
-//------------------------------------------------------------------------------
-static TEEC_Result _TEEC_CallTA(
- TEEC_Session *session,
- TEEC_Operation *operation,
- uint32_t *returnOrigin)
-{
- mcResult_t mcRet;
- TEEC_Result teecRes;
- TEEC_Result teecError = TEEC_SUCCESS;
-
- LOG_I(" %s()", __func__);
-
- // Phase 1: start the operation and wait for the result
- teecRes = _TEEC_SetupOperation((_TEEC_TCI *)session->imp.tci, &session->imp.handle, operation, returnOrigin);
- if (teecRes != TEEC_SUCCESS ) {
- LOG_E("_TEEC_SetupOperation failed (%08x)", teecRes);
- return teecRes;
- }
-
- // Signal the Trusted App
- mcRet = mcNotify(&session->imp.handle);
- if (MC_DRV_OK != mcRet) {
- LOG_E("Notify failed (%08x)", mcRet);
- teecError = TEEC_ERROR_COMMUNICATION;
- goto end;
- }
-
- // -------------------------------------------------------------
- // Wait for the Trusted App response
- mcRet = mcWaitNotification(&session->imp.handle, MC_INFINITE_TIMEOUT);
- if (mcRet != MC_DRV_OK) {
- teecError = TEEC_ERROR_COMMUNICATION;
- if (mcRet == MC_DRV_INFO_NOTIFICATION) {
- int32_t lastErr = SESSION_ERR_NO;
- mcGetSessionErrorCode(&session->imp.handle, &lastErr);
- if (lastErr == TA_EXIT_CODE_FINISHED) {
- // We may get here if the TA_OpenSessionEntryPoint returns an error and TA goes fast through DestroyEntryPoint and exits the TA.
- teecError = TEEC_SUCCESS;
- } else if (lastErr != ERR_INVALID_SID && lastErr != ERR_SID_NOT_ACTIVE) {
- LOG_E("Target is DEAD");
-
- *returnOrigin = TEEC_ORIGIN_TEE;
- teecError = TEEC_ERROR_TARGET_DEAD;
- } else {
- LOG_E("mcWaitNotification failed (%08x)", mcRet);
- LOG_E("mcGetSessionErrorCode returned %d", lastErr);
- }
- }
- }
- // Phase 2: Return values and cleanup
-end:
- // unmap memory and copy values if no error
- teecRes = _TEEC_UnwindOperation((_TEEC_TCI *)session->imp.tci, &session->imp.handle, operation,
- (teecError == TEEC_SUCCESS), returnOrigin);
- if (teecRes != TEEC_SUCCESS ) {
- LOG_E("_TEEC_UnwindOperation (%08x)", teecRes);
- /* continue even in case of error */;
- }
-
- // Cleanup
- if (teecError != TEEC_SUCCESS) {
- // Previous interactions failed, either TA is dead or communication error
- mcRet = mcCloseSession(&session->imp.handle);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcCloseSession failed (%08x)", mcRet);
- /* continue even in case of error */;
- }
- session->imp.active = false;
- if (teecError == TEEC_ERROR_COMMUNICATION) {
- *returnOrigin = TEEC_ORIGIN_COMMS;
- }
- munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
- session->imp.tci = NULL;
- }
- return teecError;
-}
-
-//------------------------------------------------------------------------------
-__MC_CLIENT_LIB_API mcResult_t mcOpenGPTA(
- mcSessionHandle_t *session,
- const mcUuid_t *uuid,
- uint8_t *tci,
- uint32_t len
-);
-//------------------------------------------------------------------------------
-//TEEC_OpenSession: if the returnOrigin is different from TEEC_ORIGIN_TRUSTED_APP, an error code from Table 4-2
-// If the returnOrigin is equal to TEEC_ORIGIN_TRUSTED_APP, a return code defined by the
-//protocol between the Client Application and the Trusted Application.
-TEEC_Result TEEC_OpenSession (
- TEEC_Context *context,
- TEEC_Session *session,
- const TEEC_UUID *destination,
- uint32_t connectionMethod,
- void */*connectionData*/,
- TEEC_Operation *operation,
- uint32_t *returnOrigin)
-{
- mcResult_t mcRet;
- TEEC_Result teecRes;
- uint32_t returnOrigin_local;
- mcUuid_t tauuid;
-
- LOG_I("== %s() ==============", __func__);
- // -------------------------------------------------------------
- //The parameter context MUST point to an initialized TEE Context.
- if (context == NULL) {
- LOG_E("context is NULL");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_BAD_PARAMETERS;
- }
-
- if (session == NULL) {
- LOG_E("session is NULL");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_BAD_PARAMETERS;
- }
-
- if (connectionMethod != TEEC_LOGIN_PUBLIC) {
- //JACKET: Client authorization is not supported. The connectionMethod parameter
- //must be TEEC LOGIN PUBLIC, otherwise return TEEC ERROR NOT IMPLEMENTED.
- LOG_E("connectionMethod != TEEC_LOGIN_PUBLIC");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_NOT_IMPLEMENTED;
- }
-
- // -------------------------------------------------------------
- session->imp.active = false;
-
- _libUuidToArray((TEEC_UUID *)destination, (uint8_t *)tauuid.value);
-
- if (operation) operation->imp.session = &session->imp;
-
- //Allocate a 4kB page with mmap, zero it out, and set session->imp.tci to its address.
- session->imp.tci = NULL;
- void *bulkBuf = (void *)mmap(0, sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (bulkBuf == MAP_FAILED) {
- LOG_E("mmap failed on tci buffer allocation");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_OUT_OF_MEMORY;
- }
-
- session->imp.tci = bulkBuf;
- memset(session->imp.tci, 0, sysconf(_SC_PAGESIZE));
-
- pthread_mutex_init(&session->imp.mutex_tci, NULL);
- pthread_mutex_lock(&session->imp.mutex_tci);
-
- //Fill the TCI buffer session.tci with the destination UUID.
- memcpy(&(((_TEEC_TCI *)session->imp.tci)->destination), destination, sizeof(TEEC_UUID));
- // -------------------------------------------------------------
- memset(&session->imp.handle, 0, sizeof(mcSessionHandle_t));
- session->imp.handle.deviceId = context->imp.reserved ; // The device ID (default device is used)
- mcRet = mcOpenGPTA(
- &session->imp.handle,
- &tauuid,
- (uint8_t *)session->imp.tci,
- sizeof(_TEEC_TCI));
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcOpenGPTA failed (%08x)", mcRet);
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_COMMS;
- if (mcRet == MC_DRV_ERR_TRUSTED_APPLICATION_NOT_FOUND) {
- teecRes = TEEC_ERROR_ITEM_NOT_FOUND;
- } else {
- //TODO: Improve the error codes
- teecRes = TEEC_ERROR_GENERIC;
- }
- goto error;
- }
-
- session->imp.active = true;
-
- // Let TA go through entry points
- LOG_I(" let TA go through entry points");
- ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_OPEN_SESSION;
- teecRes = _TEEC_CallTA(session, operation, &returnOrigin_local);
-
- // Check for error on communication level
- if (teecRes != TEEC_SUCCESS ) {
- LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
- // Nothing to do here because _TEEC_CallTA closes broken sessions
- if (returnOrigin != NULL) *returnOrigin = returnOrigin_local;
- goto error;
- }
- LOG_I(" no errors in com layer");
-
- // Check for error from TA
- if (returnOrigin != NULL) *returnOrigin = ((_TEEC_TCI *)session->imp.tci)->returnOrigin;
- teecRes = ((_TEEC_TCI *)session->imp.tci)->returnStatus;
- if (teecRes != TEEC_SUCCESS ) {
- LOG_E("TA OpenSession EP failed(%08x)", teecRes);
- goto error;
- }
-
- LOG_I(" %s() = TEEC_SUCCESS ", __func__);
- pthread_mutex_unlock(&session->imp.mutex_tci);
-
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_TRUSTED_APP;
- return TEEC_SUCCESS;
-
- // -------------------------------------------------------------
-error:
- if (session->imp.active) {
- // After notifying us, TA went to Destry EP, so close session now
- mcRet = mcCloseSession(&session->imp.handle);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcCloseSession failed (%08x)", mcRet);
- /* continue even in case of error */;
- }
- session->imp.active = false;
- }
-
- pthread_mutex_unlock(&session->imp.mutex_tci);
- pthread_mutex_destroy(&session->imp.mutex_tci);
- if (session->imp.tci) {
- munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
- session->imp.tci = NULL;
- }
-
- LOG_I(" %s() = 0x%x", __func__, teecRes);
- return teecRes;
-}
-
-//------------------------------------------------------------------------------
-TEEC_Result TEEC_InvokeCommand(
- TEEC_Session *session,
- uint32_t commandID,
- TEEC_Operation *operation,
- uint32_t *returnOrigin)
-{
- TEEC_Result teecRes;
- uint32_t returnOrigin_local;
-
- LOG_I("== %s() ==============", __func__);
-
- // -------------------------------------------------------------
- if (session == NULL) {
- LOG_E("session is NULL");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_BAD_PARAMETERS;
- }
-
- if (!session->imp.active) {
- LOG_E("session is inactive");
- if (returnOrigin != NULL) *returnOrigin = TEEC_ORIGIN_API;
- return TEEC_ERROR_BAD_STATE;
- }
- // -------------------------------------------------------------
- if (operation) operation->imp.session = &session->imp;
-
- pthread_mutex_lock(&session->imp.mutex_tci);
-
- // Call TA
- ((_TEEC_TCI *)session->imp.tci)->operation.commandId = commandID;
- ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_INVOKE_COMMAND;
- teecRes = _TEEC_CallTA(session, operation, &returnOrigin_local);
- if (teecRes != TEEC_SUCCESS ) {
- LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
- if (returnOrigin != NULL) *returnOrigin = returnOrigin_local;
- } else {
- if (returnOrigin != NULL) *returnOrigin = ((_TEEC_TCI *)session->imp.tci)->returnOrigin;
- teecRes = ((_TEEC_TCI *)session->imp.tci)->returnStatus;
- }
-
- pthread_mutex_unlock(&session->imp.mutex_tci);
- LOG_I(" %s() = 0x%x", __func__, teecRes);
- return teecRes;
-}
-
-//------------------------------------------------------------------------------
-void TEEC_CloseSession(TEEC_Session *session)
-{
- mcResult_t mcRet;
- TEEC_Result teecRes = TEEC_SUCCESS;
- uint32_t returnOrigin;
-
- LOG_I("== %s() ==============", __func__);
-
- // -------------------------------------------------------------
- //The Implementation MUST do nothing if the session parameter is NULL.
- if (session == NULL) {
- LOG_E("session is NULL");
- return;
- }
-
- // -------------------------------------------------------------
- if (session->imp.active) {
- // Let TA go through CloseSession and Destroy entry points
- LOG_I(" let TA go through close entry points");
- pthread_mutex_lock(&session->imp.mutex_tci);
- ((_TEEC_TCI *)session->imp.tci)->operation.type = _TA_OPERATION_CLOSE_SESSION;
- teecRes = _TEEC_CallTA(session, NULL, &returnOrigin);
- if (teecRes != TEEC_SUCCESS ) {
- /* continue even in case of error */;
- LOG_E("_TEEC_CallTA failed(%08x)", teecRes);
- }
-
- if (session->imp.active) {
- // Close Session
- mcRet = mcCloseSession(&session->imp.handle);
- if (mcRet != MC_DRV_OK) {
- LOG_E("mcCloseSession failed (%08x)", mcRet);
- /* ignore error and also there shouldn't be one */
- }
- }
- pthread_mutex_unlock(&session->imp.mutex_tci);
- }
-
- pthread_mutex_destroy(&session->imp.mutex_tci);
- if (session->imp.tci) {
- munmap(session->imp.tci, sysconf(_SC_PAGESIZE));
- session->imp.tci = NULL;
- }
- session->imp.active = false;
-
- LOG_I(" %s() = 0x%x", __func__, teecRes);
-}
-
-//------------------------------------------------------------------------------
-TEEC_Result TEEC_RegisterSharedMemory(
- TEEC_Context *context,
- TEEC_SharedMemory *sharedMem)
-{
- LOG_I("== %s() ==============", __func__);
-
- //The parameter context MUST point to an initialized TEE Context.
- if (context == NULL) {
- LOG_E("context is NULL");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- //The parameter sharedMem MUST point to the Shared Memory structure defining
- //the memory region to register.
- if (sharedMem == NULL) {
- LOG_E("sharedMem is NULL");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- //The buffer field MUST point to the memory region to be shared, and MUST not be NULL.
- if (sharedMem->buffer == NULL) {
- LOG_E("sharedMem->buffer is NULL");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- if ((sharedMem->flags & ~(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) != 0) {
- LOG_E("sharedMem->flags is incorrect");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- if (sharedMem->flags == 0) {
- LOG_E("sharedMem->flags is incorrect");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
-
- sharedMem->imp.implementation_allocated = false;
- return TEEC_SUCCESS;
-}
-
-//------------------------------------------------------------------------------
-TEEC_Result TEEC_AllocateSharedMemory(
- TEEC_Context *context,
- TEEC_SharedMemory *sharedMem)
-{
- //No connection to "context"?
- LOG_I("== %s() ==============", __func__);
-
- //The parameter context MUST point to an initialized TEE Context.
- if (context == NULL) {
- LOG_E("context is NULL");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- //The parameter sharedMem MUST point to the Shared Memory structure defining
- //the memory region to register.
- if (sharedMem == NULL) {
- LOG_E("sharedMem is NULL");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- if ((sharedMem->flags & ~(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) != 0) {
- LOG_E("sharedMem->flags is incorrect");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
- if (sharedMem->flags == 0) {
- LOG_E("sharedMem->flags is incorrect");
- return TEEC_ERROR_BAD_PARAMETERS;
- }
-
- sharedMem->buffer = malloc(sharedMem->size);
- if (sharedMem->buffer == NULL) {
- LOG_E("malloc failed");
- return TEEC_ERROR_OUT_OF_MEMORY;
- }
- sharedMem->imp.implementation_allocated = true;
-
- return TEEC_SUCCESS;
-}
-
-//------------------------------------------------------------------------------
-void TEEC_ReleaseSharedMemory (
- TEEC_SharedMemory *sharedMem)
-{
- //No connection to "context"?
- LOG_I("== %s() ==============", __func__);
-
- //The Implementation MUST do nothing if the sharedMem parameter is NULL
- if (sharedMem == NULL) {
- LOG_E("sharedMem is NULL");
- return;
- }
-
- //For a memory buffer allocated using TEEC_AllocateSharedMemory the Implementation
- //MUST free the underlying memory
- if (sharedMem->imp.implementation_allocated) {
- if (sharedMem->buffer) {
- free(sharedMem->buffer);
- sharedMem->buffer = NULL;
- sharedMem->size = 0;
- }
- }
-
- //TODO: Attempting to release Shared Memory which is used by a pending operation.
-
-}
-
-//------------------------------------------------------------------------------
-void TEEC_RequestCancellation(
- TEEC_Operation *operation)
-{
- LOG_I("== %s() ==============", __func__);
-
- while (operation->started == 0);
-
- LOG_I("while(operation->started ==0) passed");
-
- if (operation->started > 1) {
- LOG_I("The operation has finished");
- return;
- }
-
- TEEC_Session_IMP *session = operation->imp.session;
- operation->started = 2;
-
- if (!session->active) {
- LOG_I("Corresponding session is not active");
- return;
- }
- ((_TEEC_TCI *)session->tci)->operation.isCancelled = true;
-
- // Step 4.3: signal the Trustlet
- mcResult_t mcRet = mcNotify(&session->handle);
- if (MC_DRV_OK != mcRet) {
- LOG_E("Notify failed (%08x)", mcRet);
- }
-}
-
-//------------------------------------------------------------------------------