mcResult_t tlc_communicate(mc_comm_ctx *comm_ctx) {
	mcResult_t	mcRet;

	do {
		// -------------------------------------------------------------
		// Step 1: signal the Trustlet
		mcRet = mcNotify(&(comm_ctx->handle));
		if (MC_DRV_OK != mcRet) {
			LOG_E("Notify failed: %d", mcRet);
			break;
		}
		LOG_I("mcNotify is completed\n");

		// -------------------------------------------------------------
		// Step 2: Wait for the Trustlet response
		mcRet = mcWaitNotification(&(comm_ctx->handle), -1);
		if (MC_DRV_OK != mcRet) {
			LOG_E("Wait for response notification failed: %d", mcRet);
			break;
		}

		LOG_I("mcWaitNotification is completed");

	} while (false);

	return mcRet;
}
//------------------------------------------------------------------------------
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);
    }
}
Esempio n. 3
0
// -------------------------------------------------------------
static mcResult_t executeCmd(uint32_t *num1, uint32_t *num2, uint32_t *result, tciCommandId_t cmd)
{
	mcResult_t  ret;    

	if(NULL == tci) 
	{
	    LOG_E("TCI has not been set up properly - exiting");
	    return MC_DRV_ERR_NO_FREE_MEMORY;
	}

	tci->cmdfoo.header.commandId = cmd;
	tci->cmdfoo.len = 0;
	tci->cmdfoo.respLen = 0;
	tci->Num1 = *num1;
	tci->Num2 = *num2;    

	LOG_I("Preparing command message in TCI");

	LOG_I("Notifying the trustlet");
	ret = mcNotify(&sessionHandle);

	if (MC_DRV_OK != ret)
	{
	    LOG_E("Notify failed: %d", ret);
	    goto exit;
	}

	LOG_I("Waiting for the Trustlet response");
	ret = mcWaitNotification(&sessionHandle, -1);

	if (MC_DRV_OK != ret) 
	{
	    LOG_E("Wait for response notification failed: 0x%x", ret);
	    goto exit;
	}

	*result = tci->ResultData;

	LOG_I("Verifying that the Trustlet sent a response.");
	if (RSP_ID(cmd) != tci->rspfoo.header.responseId) 
	{
	    LOG_E("Trustlet did not send a response: %d",
	        tci->rspfoo.header.responseId);
	    ret = MC_DRV_ERR_INVALID_RESPONSE;
	    goto exit;
	}

	if (RET_OK != tci->rspfoo.header.returnCode) 
	{
	    LOG_E("Trustlet did not send a valid return code: %d",
	        tci->rspfoo.header.returnCode);
	    ret = tci->rspfoo.header.returnCode;
	}

	exit:
	return ret;
}
Esempio n. 4
0
// -------------------------------------------------------------
static mcResult_t executeCmd(uint32_t *index, uint32_t *result, tciCommandId_t cmd)
{
	mcResult_t  ret;    

	if(NULL == tci) 
	{
	    printf("TCI has not been set up properly - exiting\n");
	    return MC_DRV_ERR_NO_FREE_MEMORY;
	}

	tci->cmd.header.commandId = cmd;
	tci->cmd.len = 0;
	tci->cmd.respLen = 0;
	tci->index= *index; 

	printf("Preparing command message in TCI\n");

	printf("Notifying the trustlet\n");
	ret = mcNotify(&sessionHandle);

	if (MC_DRV_OK != ret)
	{
	    printf("Notify failed: %d\n", ret);
	    goto exit;
	}

	printf("Waiting for the Trustlet response\n");
	ret = mcWaitNotification(&sessionHandle, -1);

	if (MC_DRV_OK != ret) 
	{
	    printf("Wait for response notification failed: 0x%x\n", ret);
	    goto exit;
	}

	*result = tci->result;

	printf("Verifying that the Trustlet sent a response.\n");
	if (RSP_ID(cmd) != tci->rsp.header.responseId) 
	{
	    printf("Trustlet did not send a response: %d\n",
	        tci->rsp.header.responseId);
	    ret = MC_DRV_ERR_INVALID_RESPONSE;
	    goto exit;
	}

	if (RET_OK != tci->rsp.header.returnCode) 
	{
	    printf("Trustlet did not send a valid return code: %d\n",
	        tci->rsp.header.returnCode);
	    ret = tci->rsp.header.returnCode;
	}

	exit:
	return ret;
}
//------------------------------------------------------------------------------
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);
            switch (lastErr) {
            case 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;
                break;
            case ERR_SESSION_KILLED:
                teecError = TEEC_ERROR_TARGET_KILLED;
                break;
            case ERR_INVALID_SID:
            case ERR_SID_NOT_ACTIVE:
                LOG_E("mcWaitNotification failed (%08x)", mcRet);
                LOG_E("mcGetSessionErrorCode returned %d", lastErr);
                break;
            default:
                LOG_E("Target is DEAD");
                *returnOrigin = TEEC_ORIGIN_TEE;
                teecError = TEEC_ERROR_TARGET_DEAD;
                break;
            }
        }
    }
    // 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;
}