summaryrefslogtreecommitdiff
path: root/peripheral/keystore/chaabi/libcc54/tee_client_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'peripheral/keystore/chaabi/libcc54/tee_client_api.c')
-rw-r--r--peripheral/keystore/chaabi/libcc54/tee_client_api.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/peripheral/keystore/chaabi/libcc54/tee_client_api.c b/peripheral/keystore/chaabi/libcc54/tee_client_api.c
new file mode 100644
index 0000000..0302571
--- /dev/null
+++ b/peripheral/keystore/chaabi/libcc54/tee_client_api.c
@@ -0,0 +1,406 @@
+/*******************************************************************
+* (c) Copyright 2011-2012 Discretix Technologies Ltd. *
+* This file is licensed under the terms provided in the file *
+* libcc54/LICENSE in this directory or a parent directory *
+********************************************************************/
+
+#define DX_PAL_LOG_CUR_COMPONENT DX_LOG_MASK_CCLIB
+
+/* \file tee_client_api.c
+ Implementation of the TEE Client API Specification Version 1.0
+*/
+
+#include "dx_pal_log.h"
+#include "applet_mgr_error.h"
+#include "dx_pal_compiler.h"
+#include "driver_interface.h"
+#include "tee_client_api.h"
+
+
+/* Structure for implementation-specific part of the TEEC data structures */
+struct TEEC_SharedMemory_imp {
+ DxDI_SepAppContext_t *contextP; /* Associated context */
+ dxdi_memref_id_t memrefId;
+} DX_PAL_COMPILER_TYPE_MAY_ALIAS;
+struct TEEC_Session_imp {
+ DxDI_SepAppContext_t *contextP; /* Associated context */
+ dxdi_sepapp_session_id_t sessionId;
+} DX_PAL_COMPILER_TYPE_MAY_ALIAS;
+
+/* Verify imp[] part of TEEC API structures can accomodate DxDI objects */
+DX_PAL_COMPILER_ASSERT(sizeof(DxDI_SepAppContext_t) <= DX_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(TEEC_Context, imp),
+ "TEEC_Context.imp[] is too small");
+DX_PAL_COMPILER_ASSERT(sizeof(struct TEEC_Session_imp) <= DX_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(TEEC_Session, imp),
+ "TEEC_Session.imp[] is too small");
+DX_PAL_COMPILER_ASSERT(sizeof(struct TEEC_SharedMemory_imp) <= DX_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(TEEC_SharedMemory, imp),
+ "TEEC_SharedMemory.imp[] is too small");
+
+static TEEC_Result appletMgrErr2TeecRetCode(uint32_t appletMgrErr)
+{
+ switch (appletMgrErr) {
+ case DX_APP_MNG_SESSION_TBL_IS_FULL_ERROR:
+ return TEEC_ERROR_OUT_OF_MEMORY;
+ case DX_APP_MNG_ILLEGAL_SESSION_ERROR:
+ case DX_APP_MNG_ILLEGAL_APPLET_NUM_ERROR:
+ case DX_APP_MNG_APPLET_NOT_FOUND_ERROR:
+ return TEEC_ERROR_ITEM_NOT_FOUND;
+ case DX_APP_MNG_ILLEGAL_PARAM_ERROR:
+ return TEEC_ERROR_BAD_PARAMETERS;
+ case DX_APP_MNG_ILLEGAL_OP_FOR_NONPRIV_APPLET_ERROR:
+ return TEEC_ERROR_ACCESS_DENIED;
+ case DX_APP_MNG_ILLEGAL_SLOT_NUM_ERROR:
+ return TEEC_ERROR_ITEM_NOT_FOUND;
+ case DX_APP_MNG_SRAM_APPLET_CALL_NONPRIV_APPLET_ERROR:
+ return TEEC_ERROR_ACCESS_DENIED;
+ default: /* All the other errors are not supposed to happen here*/
+ DX_PAL_LOG_DEBUG("Invalid error from applet manager = 0x%08X\n", appletMgrErr);
+ }
+ return TEEC_ERROR_GENERIC;
+}
+
+/*!
+ * Convert from DriverInterface return code to TEEC_Result
+ *
+ * \param diRc DriverInterface return code
+ * \return TEEC_Result
+ */
+static TEEC_Result diRetCodeToTeecResult(DxDI_RetCode_t diRc, uint32_t retOrigin, uint32_t sepRetCode)
+{
+ switch (diRc) {
+ case DXDI_RET_OK: return TEEC_SUCCESS;
+ case DXDI_RET_ENODEV: return TEEC_ERROR_ITEM_NOT_FOUND;
+ case DXDI_RET_EINTERNAL: return TEEC_ERROR_GENERIC;
+ case DXDI_RET_ENOTSUP: return TEEC_ERROR_NOT_SUPPORTED;
+ case DXDI_RET_ENOPERM: return TEEC_ERROR_ACCESS_DENIED;
+ case DXDI_RET_EINVAL: return TEEC_ERROR_BAD_PARAMETERS;
+ case DXDI_RET_ENORSC: return TEEC_ERROR_OUT_OF_MEMORY;
+ case DXDI_RET_ESEP:
+ if (retOrigin == TEEC_ORIGIN_TRUSTED_APP) /* Return code from the applet */
+ return sepRetCode;
+ else /* Return code from the applet manager */
+ return appletMgrErr2TeecRetCode(sepRetCode);
+ case DXDI_RET_EHW: return TEEC_ERROR_COMMUNICATION;
+ default: return TEEC_ERROR_GENERIC;
+ }
+}
+
+static uint32_t sepModuleToTeecOrigin(enum dxdi_sep_module sepModule)
+{
+ switch (sepModule) {
+ case DXDI_SEP_MODULE_HOST_DRIVER: return TEEC_ORIGIN_API;
+ case DXDI_SEP_MODULE_SW_QUEUE : return TEEC_ORIGIN_COMMS;
+ case DXDI_SEP_MODULE_APP_MGR : return TEEC_ORIGIN_TEE;
+ case DXDI_SEP_MODULE_APP : return TEEC_ORIGIN_TRUSTED_APP;
+ case DXDI_SEP_MODULE_RPC_AGENT : return TEEC_ORIGIN_TEE; /* Not supposed to happen for SepApp stack */
+ case DXDI_SEP_MODULE_SYM_CRYPTO : return TEEC_ORIGIN_TEE; /* Not supposed to happen for SepApp stack */
+ default: return TEEC_ORIGIN_API;
+ }
+}
+
+/*!
+ * Convert from TEEC data direction flags to DxDI data direction
+ * This functions is used for memory registration flags and for operation parameters direction
+ * It assumes the directions within an operand are always holding at
+ * lowest 2 bits the direction flags (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)
+ *
+ * \param teecDataDirFlags
+ *
+ * \return dxdi_data_direction
+ */
+static enum dxdi_data_direction TeecDataDirToDxDiDataDir(uint32_t teecDataDirFlags)
+{
+ enum dxdi_data_direction diDir = DXDI_DATA_NULL;
+
+ if (teecDataDirFlags & TEEC_MEM_INPUT)
+ diDir = DXDI_DATA_TO_DEVICE;
+ if (teecDataDirFlags & TEEC_MEM_OUTPUT)
+ diDir |= DXDI_DATA_FROM_DEVICE;
+
+ return diDir;
+}
+
+/*!
+ * Convert from TEEC API operation type to DxDI parameters type
+ *
+ * \param The operation context (of the associated Session)
+ * \param TeecOp
+ * \param appParams DxDI format of the client parameters
+ *
+ * \return int 0 on success, EINVAL for invalid paramters
+ */
+static int TeecOperationToSepAppParams(DxDI_SepAppContext_t *context,
+ TEEC_Operation *TeecOp, struct dxdi_sepapp_params *appParams)
+{
+ int i;
+ uint8_t curParamType;
+ struct TEEC_SharedMemory_imp *SharedMemDataP;
+
+ for (i = 0; i < 4; i++) {
+
+ appParams->params[i].val.copy_dir = DXDI_DATA_NULL; /* default */
+ if (TeecOp == NULL) {
+ curParamType = TEEC_NONE; /* Default for non-existing operation */
+ } else {
+ curParamType = TEEC_PARAM_TYPE_GET(TeecOp->paramTypes, i);
+ }
+
+ switch (curParamType) {
+ case TEEC_NONE :
+ appParams->params_types[i] = DXDI_SEPAPP_PARAM_NULL;
+ break;
+
+ case TEEC_VALUE_INPUT :
+ /*FALLTHROUGH*/
+ case TEEC_VALUE_INOUT :
+ /* copy-in data by value */
+ appParams->params[i].val.data[0] = TeecOp->params[i].value.a;
+ appParams->params[i].val.data[1] = TeecOp->params[i].value.b;
+ /*FALLTROUGH*/
+ case TEEC_VALUE_OUTPUT :
+ appParams->params[i].val.copy_dir = TeecDataDirToDxDiDataDir(curParamType);
+ appParams->params_types[i] = DXDI_SEPAPP_PARAM_VAL;
+ break;
+
+ case TEEC_MEMREF_TEMP_INPUT :
+ case TEEC_MEMREF_TEMP_OUTPUT :
+ case TEEC_MEMREF_TEMP_INOUT :
+ appParams->params[i].memref.ref_id = DXDI_MEMREF_ID_NULL;
+ appParams->params[i].memref.start_or_offset = (unsigned long)TeecOp->params[i].tmpref.buffer;
+ appParams->params[i].memref.size = TeecOp->params[i].tmpref.size;
+ appParams->params[i].memref.dma_direction = TeecDataDirToDxDiDataDir(curParamType);
+ appParams->params_types[i] = DXDI_SEPAPP_PARAM_MEMREF;
+ break;
+
+ case TEEC_MEMREF_WHOLE :
+ SharedMemDataP = (struct TEEC_SharedMemory_imp *)&TeecOp->params[i].memref.parent->imp[0];
+ if (SharedMemDataP->contextP != context)
+ return EINVAL;
+ appParams->params[i].memref.ref_id = SharedMemDataP->memrefId;
+ appParams->params[i].memref.start_or_offset = 0;
+ /* Size and direction are taken from the parent (registered memory) */
+ appParams->params[i].memref.size = TeecOp->params[i].memref.parent->size;
+ appParams->params[i].memref.dma_direction = TeecDataDirToDxDiDataDir(TeecOp->params[i].memref.parent->flags);
+ appParams->params_types[i] = DXDI_SEPAPP_PARAM_MEMREF;
+ break;
+
+ case TEEC_MEMREF_PARTIAL_INPUT :
+ case TEEC_MEMREF_PARTIAL_OUTPUT:
+ case TEEC_MEMREF_PARTIAL_INOUT :
+ SharedMemDataP = (struct TEEC_SharedMemory_imp *)&TeecOp->params[i].memref.parent->imp[0];
+ if (SharedMemDataP->contextP != context)
+ return EINVAL;
+ appParams->params[i].memref.ref_id = SharedMemDataP->memrefId;
+ appParams->params[i].memref.start_or_offset = (unsigned long)TeecOp->params[i].memref.offset;
+ appParams->params[i].memref.size = TeecOp->params[i].memref.size;
+ appParams->params[i].memref.dma_direction = TeecDataDirToDxDiDataDir(curParamType);
+ appParams->params_types[i] = DXDI_SEPAPP_PARAM_MEMREF;
+ break;
+
+ default: /* Invalid parameter type */
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ * Copy back to "VAL" parameters of type "OUT" or "INOUT"
+ *
+ * \param TeecOp
+ * \param appParams
+ */
+static void CopyBackValParams(TEEC_Operation *TeecOp, struct dxdi_sepapp_params *appParams)
+{
+ int i;
+ uint8_t curParamType;
+
+ if (TeecOp == NULL)
+ return;
+
+ for (i = 0; i < 4; i++) {
+ curParamType = TEEC_PARAM_TYPE_GET(TeecOp->paramTypes, i);
+ if ((curParamType == TEEC_VALUE_OUTPUT) ||
+ (curParamType == TEEC_VALUE_INOUT)) {
+ TeecOp->params[i].value.a = appParams->params[i].val.data[0];
+ TeecOp->params[i].value.b = appParams->params[i].val.data[1];
+ }
+ }
+}
+
+/* 4.5.2 */
+TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context)
+{
+ DxDI_RetCode_t diRc;
+
+ if (context == NULL)
+ return TEEC_ERROR_BAD_PARAMETERS;
+ /* "name" is ignored - we have only one SeP in the system */
+ diRc = DxDI_SepAppContextAlloc(name, (DxDI_SepAppContext_t *)context);
+
+ return diRetCodeToTeecResult(diRc, TEEC_ORIGIN_API, 0);
+}
+
+/* 4.5.3 */
+void TEEC_FinalizeContext(TEEC_Context *context)
+{
+ if (context == NULL)
+ return;
+ DxDI_SepAppContextFree((DxDI_SepAppContext_t *)context);
+}
+
+/* 4.5.4 */
+TEEC_Result TEEC_RegisterSharedMemory(
+ TEEC_Context* context,
+ TEEC_SharedMemory* sharedMem)
+{
+ struct TEEC_SharedMemory_imp *impDataP = (struct TEEC_SharedMemory_imp *)&sharedMem->imp[0];
+ DxDI_RetCode_t diRc;
+ struct dxdi_memref memRef;
+
+ if ((context == NULL) || (sharedMem == NULL))
+ return TEEC_ERROR_BAD_PARAMETERS;
+
+ memRef.ref_id = DXDI_MEMREF_ID_NULL;
+ memRef.start_or_offset = (unsigned long)sharedMem->buffer;
+ memRef.size = sharedMem->size;
+
+ /* Convert TEE flags to DXDI flags */
+ memRef.dma_direction = 0;
+ if (sharedMem->flags & TEEC_MEM_INPUT)
+ memRef.dma_direction = DXDI_DATA_TO_DEVICE;
+ if (sharedMem->flags & TEEC_MEM_OUTPUT)
+ memRef.dma_direction |= DXDI_DATA_FROM_DEVICE;
+
+ diRc = DxDI_RegisterMemForDma((DxDI_SepAppContext_t *)context, &memRef, &impDataP->memrefId);
+ impDataP->contextP = (DxDI_SepAppContext_t *)context;
+
+ return diRetCodeToTeecResult(diRc, TEEC_ORIGIN_API, 0);
+}
+
+/* 4.5.5 */
+TEEC_Result TEEC_AllocateSharedMemory(
+ TEEC_Context* context,
+ TEEC_SharedMemory* sharedMem)
+{
+ return TEEC_ERROR_NOT_IMPLEMENTED;
+}
+
+/* 4.5.6 */
+void TEEC_ReleaseSharedMemory (
+ TEEC_SharedMemory* sharedMem)
+{
+ struct TEEC_SharedMemory_imp *impDataP = (struct TEEC_SharedMemory_imp *)&sharedMem->imp[0];
+
+ if (sharedMem != NULL)
+ (void)DxDI_FreeMemForDma(impDataP->contextP, impDataP->memrefId);
+}
+
+/* 4.5.7 */
+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)
+{
+ struct TEEC_Session_imp *diSessionP = (struct TEEC_Session_imp *)&session->imp;
+ enum dxdi_sep_module sepRetOrigin;
+ uint32_t sepRetCode;
+ DxDI_RetCode_t diRc;
+ struct dxdi_sepapp_params sepAppParams;
+ struct dxdi_sepapp_params *sepAppParamsP;
+
+ if ((context == NULL) || (session == NULL)) {
+ *returnOrigin = TEEC_ORIGIN_API;
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+
+ if (operation == NULL) {
+ sepAppParamsP = NULL;
+ } else {
+ sepAppParamsP = &sepAppParams;
+ if (TeecOperationToSepAppParams((DxDI_SepAppContext_t *)context,
+ operation, &sepAppParams) != 0) {
+ *returnOrigin = TEEC_ORIGIN_API;
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+ }
+
+ /* TODO: Map TEEC API login methods (TEEC_LOGIN_*) to DI's (DXDI_SEPAPP_AUTH_METHOD_*) */
+
+ diSessionP->contextP = (DxDI_SepAppContext_t *)context;
+ diRc = DxDI_SepAppSessionOpen(diSessionP->contextP,
+ (dxdi_sepapp_uuid_t *)destination, connectionMethod, connectionData, sepAppParamsP,
+ &diSessionP->sessionId, &sepRetOrigin, &sepRetCode);
+
+ if (diRc == DXDI_RET_OK) {
+ CopyBackValParams(operation, sepAppParamsP);
+ }
+ *returnOrigin = sepModuleToTeecOrigin(sepRetOrigin);
+
+ return diRetCodeToTeecResult(diRc, *returnOrigin, sepRetCode);
+}
+
+/* 4.5.8 */
+void TEEC_CloseSession (
+ TEEC_Session* session)
+{
+ struct TEEC_Session_imp *diSessionP = (struct TEEC_Session_imp *)&session->imp;
+
+ if (session != NULL)
+ (void)DxDI_SepAppSessionClose(diSessionP->contextP, diSessionP->sessionId);
+}
+
+/* 4.5.9 */
+TEEC_Result TEEC_InvokeCommand(
+ TEEC_Session *session,
+ uint32_t commandID,
+ TEEC_Operation *operation,
+ uint32_t *returnOrigin)
+{
+ struct TEEC_Session_imp *diSessionP = (struct TEEC_Session_imp *)&session->imp;
+ enum dxdi_sep_module sepRetOrigin;
+ uint32_t sepRetCode;
+ DxDI_RetCode_t diRc;
+ struct dxdi_sepapp_params sepAppParams;
+ struct dxdi_sepapp_params *sepAppParamsP;
+
+ if (session == NULL) {
+ *returnOrigin = TEEC_ORIGIN_API;
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+
+ if (operation == NULL) {
+ sepAppParamsP = NULL;
+ } else {
+ sepAppParamsP = &sepAppParams;
+ if (TeecOperationToSepAppParams(diSessionP->contextP,
+ operation, &sepAppParams) != 0) {
+ *returnOrigin = TEEC_ORIGIN_API;
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+ }
+
+ diRc = DxDI_SepAppCommandInvoke(diSessionP->contextP, diSessionP->sessionId,
+ commandID, sepAppParamsP,
+ &sepRetOrigin, &sepRetCode);
+
+ if (diRc == DXDI_RET_OK) {
+ CopyBackValParams(operation, sepAppParamsP);
+ }
+ *returnOrigin = sepModuleToTeecOrigin(sepRetOrigin);
+
+ return diRetCodeToTeecResult(diRc, *returnOrigin, sepRetCode);
+}
+
+/* 4.5.10 - not supported in this implementation */
+void TEEC_RequestCancellation(
+ TEEC_Operation *operation)
+{
+ /* Since this is function returns "void" we just ignore the request */
+}
+
+