/****************************************************************************** Function: load_done Description: 全部镜像发送完毕开始校验 Input: cmd_id - 传送给安全OS的cmd_id Output: none Return: 0: OK 其他: ERROR码 ******************************************************************************/ static s32 load_done(TEEC_Session *session, SECBOOT_CMD_ID cmd_id) { TEEC_Result result; TEEC_Operation operation; u32 origin; mutex_lock(&trans_lock); operation.started = 1; operation.cancel_flag = 0; operation.paramTypes = TEEC_PARAM_TYPES( TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); result = TEEK_InvokeCommand( session, cmd_id, &operation, &origin); if (result != TEEC_SUCCESS) { sec_print_err("invoke failed!\n"); result = SEC_ERROR; } mutex_unlock(&trans_lock); return result; }
SST_ERROR SST_EXPORT_API SSTCloseHandle(SST_HANDLE hFile) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; if (hFile == S_HANDLE_NULL) { return SST_SUCCESS; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = hFile; nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_CLOSE_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); return static_SSTConvertErrorCode(nError); }
/****************************************************************************** Function: TEEK_cmd_session Description: 传入命令到安全OS Input: cmd_id - 传送给安全OS的cmd_id func_cmd - 调用函数命令字 param - 函数入参 Output: none Return: 0: OK 其他: ERROR码 ******************************************************************************/ static int TEEK_cmd_session(TEEC_Session *session, SECBOOT_CMD_ID cmd_id, FUNC_CMD_ID func_cmd, const unsigned int param) { TEEC_Result result; TEEC_Operation operation; unsigned int origin; operation.started = 1; operation.cancel_flag = 0; operation.paramTypes = TEEC_PARAM_TYPES( TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].value.a = (unsigned int)func_cmd; operation.params[0].value.b = param; result = TEEK_InvokeCommand( session, cmd_id, &operation, &origin); if (result != TEEC_SUCCESS) { sec_print_err("invoke failed!result = 0x%x!\n",result); result = BSP_ERROR; } return BSP_OK; }
static TEEC_Result run_test_with_args(enum storage_benchmark_cmd cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t *out0, uint32_t *out1) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; TEEC_Result res; TEEC_Session sess; uint32_t orig; res = xtest_teec_open_session(&sess, &storage_benchmark_ta_uuid, NULL, &orig); if (res != TEEC_SUCCESS) return res; op.params[0].value.a = arg0; op.params[0].value.b = arg1; op.params[1].value.a = arg2; op.params[1].value.b = arg3; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT, TEEC_NONE); res = TEEC_InvokeCommand(&sess, cmd, &op, &orig); if (out0) *out0 = op.params[2].value.a; if (out1) *out1 = op.params[2].value.b; TEEC_CloseSession(&sess); return res; }
SST_ERROR SST_EXPORT_API SSTEnumerationGetNext(SST_HANDLE hFileEnumeration, SST_FILE_INFO** ppFileInfo) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; SST_FILE_INFO* pInfo = NULL; char sFilename[SST_MAX_FILENAME]; if (ppFileInfo==NULL) { return SST_ERROR_BAD_PARAMETERS; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = hFileEnumeration; sOperation.params[1].tmpref.buffer = sFilename; sOperation.params[1].tmpref.size = SST_MAX_FILENAME; nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_ENUM_GETNEXT_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); if (nError == TEEC_SUCCESS) { if (sOperation.params[1].tmpref.size <= SST_MAX_FILENAME) { pInfo = (SST_FILE_INFO*)malloc(sizeof(SST_FILE_INFO)); if (pInfo == NULL) { return SST_ERROR_OUT_OF_MEMORY; } pInfo->pName = (char*)malloc(sOperation.params[1].tmpref.size+1); if (pInfo->pName == NULL) { free(pInfo); return SST_ERROR_OUT_OF_MEMORY; } memcpy(pInfo->pName, sFilename, sOperation.params[1].tmpref.size); /* Add zero terminator */ pInfo->pName[sOperation.params[1].tmpref.size] = 0; pInfo->nSize = sOperation.params[0].value.b; } } *ppFileInfo = pInfo; return static_SSTConvertErrorCode(nError); }
static void _release_tee_cmd(struct tee_session *sess, struct tee_cmd *cmd) { int idx; struct tee_context *ctx; BUG_ON(!cmd); BUG_ON(!sess); BUG_ON(!sess->ctx); BUG_ON(!sess->ctx->tee); ctx = sess->ctx; dev_dbg(_DEV_TEE, "%s: > free the temporary objects...\n", __func__); tee_shm_free(cmd->uuid); if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) goto out; for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); struct tee_shm *shm; switch (type) { case TEEC_NONE: case TEEC_VALUE_INPUT: case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT: break; case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: case TEEC_MEMREF_WHOLE: case TEEC_MEMREF_PARTIAL_INPUT: case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT: if (IS_ERR_OR_NULL(cmd->param.params[idx].shm)) break; shm = cmd->param.params[idx].shm; if (is_mapped_temp(shm->flags)) tee_shm_free(shm); else tee_shm_put(ctx, shm); break; default: BUG_ON(1); } } out: memset(cmd, 0, sizeof(struct tee_cmd)); dev_dbg(_DEV_TEE, "%s: <\n", __func__); }
SST_ERROR SST_EXPORT_API SSTEnumerationStart(const char* pFilenamePattern, uint32_t nReserved1, uint32_t nReserved2, SST_HANDLE* phFileEnumeration) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; if (nReserved1!=0 || nReserved2!=0) { return SST_ERROR_BAD_PARAMETERS; } if (phFileEnumeration==NULL) { return SST_ERROR_BAD_PARAMETERS; } *phFileEnumeration = SST_HANDLE_INVALID; nError = static_SSTCheckPattern(pFilenamePattern); if (nError != SST_SUCCESS) { return nError; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = 1; /* Private storage */ sOperation.params[1].tmpref.buffer = (void*)pFilenamePattern; if (pFilenamePattern != NULL) { sOperation.params[1].tmpref.size = strlen(pFilenamePattern); } else { sOperation.params[1].tmpref.size = 0; } nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_ENUM_START_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); *phFileEnumeration = (SST_HANDLE)sOperation.params[0].value.a; return static_SSTConvertErrorCode(nError); }
static TEEC_Result invoke_command(TEEC_Session *session, TEEC_SharedMemory *inout_mem, uint32_t command_type) { TEEC_Operation operation = {0}; TEEC_Result ret; /* Set the parameter types */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].memref.parent = inout_mem; /* Invoke command */ ret = TEEC_InvokeCommand(session, command_type, &operation, NULL); return ret; }
static void prepare_op() { TEEC_Result res; uint32_t ret_origin; TEEC_Operation op; memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); op.params[0].value.a = algo; res = TEEC_InvokeCommand(&sess, TA_SHA_PERF_CMD_PREPARE_OP, &op, &ret_origin); check_res(res, "TEEC_InvokeCommand"); }
/* * Function to send answer to the TEE */ void send_answer(TEEC_Session sess,char *answer,uint32_t err_origin){ TEEC_Operation op; TEEC_Result res; memset(&op, 0 , sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,TEEC_MEMREF_TEMP_INPUT,TEEC_VALUE_OUTPUT,TEEC_NONE); op.params[1].tmpref.buffer = answer; op.params[1].tmpref.size = strlen(answer); res = TEEC_InvokeCommand(&sess, TA_QUIZ_CMD_CHECK_ANSWER, &op,&err_origin); if (res != TEEC_SUCCESS) errx(1, "TEEC_Send_Answer failed with code 0x%x origin 0x%x",res, err_origin); if(op.params[0].value.a == 1){ printf("\n----------------------- \nScore = %d %% \n----------------------- \n",op.params[2].value.a ); } }
/* Hash test: buffer of size byte. Run test n times. */ static void run_test(size_t size, unsigned int n, unsigned int l) { uint64_t t; struct statistics stats; TEEC_Operation op; int n0 = n; alloc_shm(size, algo); if (!random_in) memset((uint8_t *)in_shm.buffer + offset, 0, size); memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_VALUE_INPUT, TEEC_NONE); op.params[0].memref.parent = &in_shm; op.params[0].memref.offset = 0; op.params[0].memref.size = size + offset; op.params[1].memref.parent = &out_shm; op.params[1].memref.offset = 0; op.params[1].memref.size = hash_size(algo); op.params[2].value.a = l; op.params[2].value.b = offset; verbose("Starting test: %s, size=%zu bytes, ", algo_str(algo), size); verbose("random=%s, ", yesno(random_in)); verbose("unaligned=%s, ", yesno(offset)); verbose("inner loops=%u, loops=%u, warm-up=%u s\n", l, n, warmup); if (warmup) do_warmup(); memset(&stats, 0, sizeof(stats)); while (n-- > 0) { t = run_test_once((uint8_t *)in_shm.buffer + offset, size, &op, l); update_stats(&stats, t); if (n % (n0/10) == 0) vverbose("#"); } vverbose("\n"); printf("min=%gμs max=%gμs mean=%gμs stddev=%gμs (%gMiB/s)\n", stats.min/1000, stats.max/1000, stats.m/1000, stddev(&stats)/1000, mb_per_sec(size, stats.m)); free_shm(); }
SST_ERROR SST_EXPORT_API SSTOpen(const char* pFilename, uint32_t nFlags, uint32_t nReserved, SST_HANDLE* phFile) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; SST_ERROR nErrorCode = SST_SUCCESS; if (phFile == NULL || nReserved != 0) { return SST_ERROR_BAD_PARAMETERS; } *phFile = SST_HANDLE_INVALID; nErrorCode = static_SSTCheckFileName(pFilename); if (nErrorCode != SST_SUCCESS) { return nErrorCode; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = 1; /* Private storage */ sOperation.params[0].value.b = nFlags; /* Access flags */ sOperation.params[1].tmpref.buffer = (void*)pFilename; sOperation.params[1].tmpref.size = strlen(pFilename); nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_OPEN_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); if (nError == TEEC_SUCCESS) { *phFile = (SST_HANDLE)sOperation.params[0].value.a; } return static_SSTConvertErrorCode(nError); }
/*Do the SecureOs locally for modem only*/ static s32 TEEK_start_modem() { s32 ret_os = SEC_ERROR; TEEC_Session session; TEEC_Context context; u32 origin; TEEC_Operation operation; TEEC_Result result; /*TEEK_init do prepare for start SecureOs*/ ret_os = TEEK_init(&session, &context); if(SEC_ERROR == ret_os) { printk(KERN_ERR "%s:TEEK_InitializeContext failed!\n",__FUNCTION__); return ret_os; } memset(&operation, 0, sizeof(TEEC_Operation)); operation.started = 1; operation.cancel_flag = 0; /*Configure the local checking parameters*/ operation.paramTypes = TEEC_PARAM_TYPES( TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].value.a = MODEM; operation.params[1].value.a = NULL; operation.params[2].value.a = NULL; /*TEEK_InvokeCommand do the local checking for modem*/ result = TEEK_InvokeCommand( &session, SECBOOT_CMD_ID_VERIFY_DATA_TYPE_LOCAL, &operation, &origin); /*When finish TEEK_CloseSession try to close the tee session*/ TEEK_CloseSession(&session); /*When finish TEEK_FinalizeContext try to close the tee context*/ TEEK_FinalizeContext(&context); return result; }
/****************************************************************************** Function: TEEK_init Description: TEEK初始化 Input: session context Output: none Return: 0: OK 其他: ERROR码 ******************************************************************************/ static int TEEK_init(TEEC_Session *session, TEEC_Context *context) { TEEC_Result result; TEEC_UUID svc_uuid = TEE_SERVICE_SECBOOT; TEEC_Operation operation = {0}; u8 package_name[] = "sec_boot"; u32 root_id = 0; result = TEEK_InitializeContext(NULL, context); if(result != TEEC_SUCCESS) { sec_print_err("TEEK_InitializeContext failed,result = 0x%x!\n",result); return BSP_ERROR; } operation.started = 1; operation.cancel_flag = 0; operation.paramTypes = TEEC_PARAM_TYPES( TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); operation.params[2].tmpref.buffer = (void *)(&root_id); operation.params[2].tmpref.size = sizeof(root_id); operation.params[3].tmpref.buffer = (void *)(package_name); operation.params[3].tmpref.size = strlen(package_name) + 1; result = TEEK_OpenSession( context, session, &svc_uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, NULL); if (result != TEEC_SUCCESS) { sec_print_err("TEEK_OpenSession failed,result = 0x%x!\n",result); TEEK_FinalizeContext(context); return BSP_ERROR; } return BSP_OK; }
SST_ERROR SST_EXPORT_API SSTRead(SST_HANDLE hFile, uint8_t* pBuffer, uint32_t nSize, uint32_t* pnCount) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; if ((pBuffer == NULL) || (pnCount == NULL)) { return SST_ERROR_BAD_PARAMETERS; } *pnCount = 0; pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } if (nSize == 0) { return SST_SUCCESS; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = hFile; sOperation.params[1].tmpref.buffer = pBuffer; sOperation.params[1].tmpref.size = nSize; nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_READ_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); *pnCount = sOperation.params[1].tmpref.size; /* The returned buffer size */ return static_SSTConvertErrorCode(nError); }
SST_ERROR SST_EXPORT_API SSTGetSize(const char* pFilename, uint32_t* pnSize) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; if ((pFilename == NULL) || (pnSize == NULL)) { return SST_ERROR_BAD_PARAMETERS; } nError = static_SSTCheckFileName(pFilename); if (nError != SST_SUCCESS) { return nError; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = 1; /* private storage */ sOperation.params[0].value.b = 0; sOperation.params[1].tmpref.buffer = (void*)pFilename; sOperation.params[1].tmpref.size = strlen(pFilename); nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_GET_SIZE_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); *pnSize = sOperation.params[0].value.a; return static_SSTConvertErrorCode(nError); }
/****************************************************************************** Function: bsp_trans_to_os Description: 从指定偏移开始传送指定大小的镜像 Input: cmd_id - 传送给安全OS的cmd_id *buf - 输入参数,存放要传送到安全os中的值 size - 输入参数,要写入的镜像的bytes大小 offset - 镜像需要写入的偏移地址 Output: none Return: 0: OK 其他: ERROR码 ******************************************************************************/ static s32 bsp_trans_to_os(TEEC_Session *session, SECBOOT_CMD_ID cmd_id, void * buf, const unsigned int offset, const unsigned int size) { TEEC_Result result; TEEC_Operation operation; u32 origin; mutex_lock(&trans_lock); operation.started = 1; operation.cancel_flag = 0; operation.paramTypes = TEEC_PARAM_TYPES( TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_VALUE_INPUT, TEEC_NONE); operation.params[0].value.a = trans_data.image_addr; operation.params[0].value.b = offset; operation.params[1].tmpref.buffer = (void *)g_vrl_P; operation.params[1].tmpref.size = SECBOOT_VRL_SIZE; operation.params[2].value.a = (u32)virt_to_phys(buf); operation.params[2].value.b = size; result = TEEK_InvokeCommand( session, cmd_id, &operation, &origin); if (result != TEEC_SUCCESS) { sec_print_err("invoke failed!\n"); result = SEC_ERROR; } mutex_unlock(&trans_lock); return result; }
static SST_ERROR SSTGetOffsetAndSize(SST_HANDLE hFile, uint32_t* pnOffset, uint32_t* pnSize) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } if (pnOffset == NULL) { return SST_ERROR_BAD_PARAMETERS; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = (uint32_t)hFile; nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_GET_OFFSET_AND_SIZE_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); if (pnOffset != NULL) { *pnOffset = sOperation.params[0].value.a; } if (pnSize != NULL) { *pnSize = sOperation.params[0].value.b; } return static_SSTConvertErrorCode(nError); }
SST_ERROR SST_EXPORT_API SSTSeek(SST_HANDLE hFile, int32_t nOffset, SST_WHENCE whence) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; switch(whence) { case SST_SEEK_SET: case SST_SEEK_CUR: case SST_SEEK_END: break; default: return SST_ERROR_BAD_PARAMETERS; } pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = hFile; sOperation.params[1].value.a = nOffset; sOperation.params[1].value.b = (uint32_t)whence; nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_SEEK_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); return static_SSTConvertErrorCode(nError); }
SST_ERROR SST_EXPORT_API SSTRename(SST_HANDLE hFile, const char* pNewFilename) { TEEC_Session* pSession; TEEC_Result nError; TEEC_Operation sOperation; uint32_t nReturnOrigin; pSession = static_SSTGetSession(); if (pSession == NULL) { return SST_ERROR_GENERIC; } if (pNewFilename == NULL) { return SST_ERROR_BAD_PARAMETERS; } nError = static_SSTCheckFileName(pNewFilename); if (nError != SST_SUCCESS) { return nError; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); sOperation.params[0].value.a = hFile; sOperation.params[1].tmpref.buffer = (void*)pNewFilename; sOperation.params[1].tmpref.size = strlen(pNewFilename); nError = TEEC_InvokeCommand(pSession, SERVICE_SYSTEM_SST_RENAME_COMMAND_ID, /* commandID */ &sOperation, /* IN OUT operation */ &nReturnOrigin /* OUT returnOrigin, optional */ ); return static_SSTConvertErrorCode(nError); }
SST_ERROR SST_EXPORT_API SSTInit(void) { TEEC_Result nTeeError = TEEC_SUCCESS; TEEC_Operation sOperation; uint8_t nParamType3 = TEEC_NONE; void* pSignatureFile = NULL; uint32_t nSignatureFileLen = 0; uint32_t nLoginType; stubMutexLock(); if (g_bSSTInitialized) { /* SST library already initialized */ nTeeError = TEEC_SUCCESS; goto end; } nTeeError = stubInitializeContext(); if (nTeeError != TEEC_SUCCESS) { goto end; } /* Check if there is a signature file. * If yes, send it in param3, otherwise use LOGIN_APPLICATION */ nTeeError = TEEC_ReadSignatureFile(&pSignatureFile, &nSignatureFileLen); if (nTeeError == TEEC_ERROR_ITEM_NOT_FOUND) { nLoginType = TEEC_LOGIN_USER_APPLICATION; } else { if (nTeeError != TEEC_SUCCESS) { goto end; } sOperation.params[3].tmpref.buffer = pSignatureFile; sOperation.params[3].tmpref.size = nSignatureFileLen; nParamType3 = TEEC_MEMREF_TEMP_INPUT; nLoginType = TEEC_LOGIN_AUTHENTICATION; } sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, nParamType3); nTeeError = TEEC_OpenSession(&g_sContext, &g_SSTSession, /* OUT session */ &SERVICE_UUID, /* destination UUID */ nLoginType, /* connectionMethod */ NULL, /* connectionData */ &sOperation, /* IN OUT operation */ NULL /* OUT returnOrigin, optional */ ); if (nTeeError != TEEC_SUCCESS) { goto end_finalize_context; } g_bSSTInitialized = true; stubMutexUnlock(); return SST_SUCCESS; end_finalize_context: stubFinalizeContext(); end: stubMutexUnlock(); return static_SSTConvertErrorCode(nTeeError); }
static void _update_client_tee_cmd(struct tee_session *sess, struct tee_cmd_io *cmd_io, struct tee_cmd *cmd) { int idx; struct tee_context *ctx; BUG_ON(!cmd_io); BUG_ON(!cmd_io->op); BUG_ON(!cmd_io->op->params); BUG_ON(!cmd); BUG_ON(!sess->ctx); ctx = sess->ctx; dev_dbg(_DEV_TEE, "%s: returned err=0x%08x (origin=%d)\n", __func__, cmd->err, cmd->origin); cmd_io->origin = cmd->origin; cmd_io->err = cmd->err; if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) return; for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); int offset = 0; size_t size; size_t size_new; TEEC_SharedMemory *parent; dev_dbg(_DEV_TEE, "%s: id %d type %d\n", __func__, idx, type); BUG_ON(!tee_session_is_supported_type(sess, type)); switch (type) { case TEEC_NONE: case TEEC_VALUE_INPUT: case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_PARTIAL_INPUT: break; case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT: dev_dbg(_DEV_TEE, "%s: a=%08x, b=%08x\n", __func__, cmd->param.params[idx].value.a, cmd->param.params[idx].value.b); if (tee_copy_to_user (ctx, &cmd_io->op->params[idx].value, &cmd->param.params[idx].value, sizeof(cmd_io->op->params[idx].value))) dev_err(_DEV_TEE, "%s:%d: can't update %d result to user\n", __func__, __LINE__, idx); break; case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: /* Returned updated size */ size_new = cmd->param.params[idx].shm->size_req; if (size_new != cmd_io->op->params[idx].tmpref.size) { dev_dbg(_DEV_TEE, "Size has been updated by the TA %zd != %zd\n", size_new, cmd_io->op->params[idx].tmpref.size); tee_put_user(ctx, size_new, &cmd_io->op->params[idx].tmpref.size); } dev_dbg(_DEV_TEE, "%s: tmpref %p\n", __func__, cmd->param.params[idx].shm->kaddr); /* ensure we do not exceed the shared buffer length */ if (size_new > cmd_io->op->params[idx].tmpref.size) dev_err(_DEV_TEE, " *** Wrong returned size from %d:%zd > %zd\n", idx, size_new, cmd_io->op->params[idx].tmpref.size); else if (tee_copy_to_user (ctx, cmd_io->op->params[idx].tmpref.buffer, cmd->param.params[idx].shm->kaddr, size_new)) dev_err(_DEV_TEE, "%s:%d: can't update %d result to user\n", __func__, __LINE__, idx); break; case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT: case TEEC_MEMREF_WHOLE: parent = &cmd->param.c_shm[idx]; if (type == TEEC_MEMREF_WHOLE) { offset = 0; size = parent->size; } else { offset = cmd_io->op->params[idx].memref.offset; size = cmd_io->op->params[idx].memref.size; } /* Returned updated size */ size_new = cmd->param.params[idx].shm->size_req; tee_put_user(ctx, size_new, &cmd_io->op->params[idx].memref.size); /* * If we allocated a tmpref buffer, * copy back data to the user buffer */ if (is_mapped_temp(cmd->param.params[idx].shm->flags)) { if (parent->buffer && offset + size_new <= parent->size) { if (tee_copy_to_user(ctx, parent->buffer + offset, cmd->param.params[idx].shm->kaddr, size_new)) dev_err(_DEV_TEE, "%s: can't update %d data to user\n", __func__, idx); } } break; default: BUG_ON(1); } } }
int main(void){ TEEC_Result res; TEEC_Context ctx; TEEC_Session sess; TEEC_Operation op,init_vals; TEEC_UUID uuid = TA_QUIZ_UUID; char question[DEF_QUES_SIZE] = {0}; uint32_t err_origin; //strt file read FILE *infile; infile = fopen("/bin/test.txt","r"); int num = 0; int i; ssize_t read; size_t len =0; char *line; line = (char *)malloc(sizeof(char) * 120); while((read = getline(&line,&len,infile)) != -1){ // printf("%s\n",line ); num++; } printf("%d\n",num); struct question ques[num/2]; fseek(infile,0,SEEK_SET); for(i =0 ; i < num;++i){ read = getline(&line,&len,infile); // printf("%s\n",line ); line[strlen(line)] = '\0'; if(i%2 == 0){ strcpy(ques[i/2].q,line); }else{ strcpy(ques[i/2].answer,line); } } free(line); num = num/2; /* FILE *infile; infile = fopen("/bin/test.txt","r"); int num = 0; struct question temp; int i; while(fread(&temp,sizeof(struct question),1,infile) != 0){ // printf("%s \n %s \n",temp.q,temp.answer); num++; } fseek(infile,0,SEEK_SET); struct question ques[num]; for(i =0 ; i < num;++i){ fread(&ques[i],sizeof(struct question),1,infile); } */ //end of read from file memset(&init_vals,0,sizeof(init_vals)); init_vals.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,TEEC_MEMREF_TEMP_INPUT,TEEC_NONE,TEEC_NONE); init_vals.params[0].value.a = num; init_vals.params[1].tmpref.buffer = ques; init_vals.params[1].tmpref.size = sizeof(ques[0])*num; res = TEEC_InitializeContext(NULL, &ctx); // This basically checks if a TEE is present in the system if (res != TEEC_SUCCESS) errx(1, "TEEC_InitializeContext failed with code 0x%x", res); /* * Open a session to the TA */ res = TEEC_OpenSession(&ctx, &sess, &uuid,TEEC_LOGIN_PUBLIC, NULL, &init_vals, &err_origin); if (res != TEEC_SUCCESS) errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",res, err_origin); /* * Prepare the argument. Pass a value in the first parameter, * the remaining three parameters are unused. */ memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); op.params[1].tmpref.buffer = question; op.params[1].tmpref.size = sizeof(question); printf("********************** QUIZ **************************\n"); while(1){ res = TEEC_InvokeCommand(&sess, TA_QUIZ_CMD_START_QUIZ, &op,&err_origin); if (res != TEEC_SUCCESS) errx(1, "TEEC_Get_Question failed with code 0x%x origin 0x%x",res, err_origin); if(op.params[0].value.a == 0){ break; }else{ printf("\n----------------------- \n Question:\n %s \n",question ); printf(" Enter your anwer:\n"); char answer[DEF_QUES_SIZE]; fgets(answer,DEF_QUES_SIZE,stdin); if ((strlen(answer)>0) && (answer[strlen (answer) - 1] == '\n')) answer[strlen (answer) - 1] = '\0'; send_answer(sess,answer,err_origin); } } printf("Quiz ended\n"); /* * Close the session */ TEEC_CloseSession(&sess); TEEC_FinalizeContext(&ctx); return 0; }
int main() { TEEC_Context context; TEEC_Session session; TEEC_Result ret; TEEC_Operation operation = {0}; uint32_t connection_method = TEEC_LOGIN_PUBLIC; printf("START: services test app\n"); /* Initialize context */ printf("Initializing context: "); ret = TEEC_InitializeContext(NULL, &context); if (ret != TEEC_SUCCESS) { printf("TEEC_InitializeContext failed: 0x%x\n", ret); goto end_1; } else { printf("initialized\n"); } operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); /* Open session */ printf("Opening session: "); ret = TEEC_OpenSession(&context, &session, &uuid, connection_method, NULL, &operation, NULL); if (ret != TEEC_SUCCESS) { printf("TEEC_OpenSession failed: 0x%x\n", ret); goto end_2; } else { printf("opened\n"); } printf("Initialization complete\n"); /* Invoke commands */ printf("----- Counter tests begin -----\n"); ret = do_counter_tests(&session, &context); if (ret != TEEC_SUCCESS) { printf("Counter test failed: 0x%x\n", ret); goto end_3; } else { printf("Counter test ok\n"); } printf("----- Counter tests end -----\n"); /* Cleanup */ end_3: printf("Closing session: "); TEEC_CloseSession(&session); printf("closed\n"); end_2: printf("Finalizing context: "); TEEC_FinalizeContext(&context); printf("finalized\n"); end_1: printf("END: services test app\n"); exit(ret); }
static void _update_client_tee_cmd(struct tee_session *sess, struct tee_cmd_io *cmd_io, struct tee_cmd *cmd) { int idx; struct tee_context *ctx; BUG_ON(!cmd_io); BUG_ON(!cmd_io->op); BUG_ON(!cmd_io->op->params); BUG_ON(!cmd); BUG_ON(!sess->ctx); ctx = sess->ctx; dev_dbg(_DEV_TEE, "%s: returned err=0x%08x (origin=%d)\n", __func__, cmd->err, cmd->origin); cmd_io->origin = cmd->origin; cmd_io->err = cmd->err; if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) return; for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); dev_dbg(_DEV_TEE, "%s: id %d type %d\n", __func__, idx, type); BUG_ON(!tee_session_is_supported_type(sess, type)); switch (type) { case TEEC_NONE: case TEEC_VALUE_INPUT: case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_PARTIAL_INPUT: break; case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT:{ dev_dbg(_DEV_TEE, "%s: a=%08x, b=%08x\n", __func__, cmd->param.params[idx].value.a, cmd->param.params[idx].value.b); if (tee_copy_to_user (ctx, &cmd_io->op->params[idx].value, &cmd->param.params[idx].value, sizeof(cmd_io->op->params[idx].value))) dev_err(_DEV_TEE, "%s:%d: can't update %d result to user\n", __func__, __LINE__, idx); break; } case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT:{ /* Returned updated size */ size_t size = cmd->param.params[idx].shm->size_req; if (size != cmd_io->op->params[idx].tmpref.size) { dev_dbg(_DEV_TEE, "Size has been updated by the TA %zu != %zu\n", size, cmd_io->op->params[idx].tmpref. size); tee_put_user(ctx, size, &cmd_io->op->params[idx]. tmpref.size); } BUG_ON(!cmd->param.params[idx].shm); BUG_ON(! (cmd->param.params[idx].shm-> flags & TEE_SHM_TEMP)); dev_dbg(_DEV_TEE, "%s: tmpref %p\n", __func__, cmd->param.params[idx].shm->kaddr); /* ensure we do not exceed * the shared buffer length */ if (size > cmd_io->op->params[idx].tmpref.size) dev_err(_DEV_TEE, " *** Wrong returned size from %d:%zu > %zu\n", idx, size, cmd_io->op->params[idx].tmpref. size); else if (tee_copy_to_user (ctx, cmd_io->op->params[idx].tmpref.buffer, cmd->param.params[idx].shm->kaddr, size)) dev_err(_DEV_TEE, "%s:%d: can't update %d result to user\n", __func__, __LINE__, idx); break; } case TEEC_MEMREF_WHOLE:{ /* Returned updated size */ size_t size = cmd->param.params[idx].shm->size_req; if (size != cmd_io->op->params[idx].memref.size) { dev_dbg(_DEV_TEE, "Size has been updated by the TA %zu != %zu\n", size, cmd_io->op->params[idx].memref. size); tee_put_user(ctx, size, &cmd_io->op->params[idx]. memref.size); } /* ensure we do not exceed * the shared buffer length */ if (size > cmd->param.c_shm[idx].size) dev_err(_DEV_TEE, " *** Wrong returned size from %d:%zu > %zu\n", idx, size, cmd->param.c_shm[idx].size); else if ((cmd->param.params[idx].shm->flags & (TEE_SHM_MAPPED | TEE_SHM_TEMP)) == (TEE_SHM_MAPPED | TEE_SHM_TEMP)) { BUG_ON(!cmd->param.c_shm[idx].buffer); BUG_ON(!cmd->param.c_shm[idx].size > 0); dev_dbg(_DEV_TEE, "%s: whole %p\n", __func__, cmd->param.params[idx].shm-> kaddr); if (tee_copy_to_user (ctx, cmd->param.c_shm[idx].buffer, cmd->param.params[idx].shm->kaddr, size)) dev_err(_DEV_TEE, "%s: can't update %d result to user\n", __func__, idx); } break; } case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT:{ int offset = cmd_io->op->params[idx].memref.offset; /* Returned updated size */ size_t size = cmd->param.params[idx].shm->size_req; if (size != cmd_io->op->params[idx].memref.size) { dev_dbg(_DEV_TEE, "Size has been updated by the TA %zu != %zu\n", size, cmd_io->op->params[idx].memref. size); tee_put_user(ctx, size, &cmd_io->op->params[idx]. memref.size); } /* ensure we do not exceed * the shared buffer length */ if ((offset + size) > cmd->param.c_shm[idx].size) dev_err(_DEV_TEE, " *** Wrong returned size from %d:%d +%zu > %zu\n", idx, offset, size, cmd->param.c_shm[idx].size); /* If we allocated a tmpref buffer, * copy back data to the user buffer */ else if ((cmd->param.params[idx].shm->flags & (TEE_SHM_MAPPED | TEE_SHM_TEMP)) == (TEE_SHM_MAPPED | TEE_SHM_TEMP)) { BUG_ON(!cmd->param.c_shm[idx].buffer); BUG_ON(!cmd->param.c_shm[idx].size > 0); if (tee_copy_to_user (ctx, cmd->param.c_shm[idx].buffer + offset, cmd->param.params[idx].shm->kaddr, size)) dev_err(_DEV_TEE, "%s: can't update %d result to user\n", __func__, idx); } break; } default: BUG_ON(1); } } }
int main(int argc, char *argv[]) { TEEC_Result res; TEEC_Context ctx; TEEC_Session sess; TEEC_Operation op; TEEC_UUID uuid = TA_HELLO_WORLD_UUID; uint32_t err_origin; /* Initialize a context connecting us to the TEE */ res = TEEC_InitializeContext(NULL, &ctx); if (res != TEEC_SUCCESS) errx(1, "TEEC_InitializeContext failed with code 0x%x", res); /* * Open a session to the "hello world" TA, the TA will print "hello * world!" in the log when the session is created. */ res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin); if (res != TEEC_SUCCESS) errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x", res, err_origin); /* * Execute a function in the TA by invoking it, in this case * we're incrementing a number. * * The value of command ID part and how the parameters are * interpreted is part of the interface provided by the TA. */ /* * Prepare the argument. Pass a value in the first parameter, * the remaining three parameters are unused. */ memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); op.params[0].value.a = 42; printf("Invoking TA to increment %d\n", op.params[0].value.a); res = TEEC_InvokeCommand(&sess, TA_HELLO_WORLD_CMD_INC_VALUE, &op, &err_origin); if (res != TEEC_SUCCESS) errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", res, err_origin); printf("TA incremented value to %d\n", op.params[0].value.a); /* * We're done with the TA, close the session and * destroy the context. * * The TA will print "Goodbye!" in the log when the * session is closed. */ TEEC_CloseSession(&sess); TEEC_FinalizeContext(&ctx); return 0; }
int main() { TEEC_Context context; TEEC_Session session; TEEC_Operation operation; TEEC_SharedMemory in_mem; TEEC_SharedMemory out_mem; TEEC_Result ret; uint32_t return_origin; uint32_t connection_method = TEEC_LOGIN_PUBLIC; char data[DATA_SIZE]; uint8_t sha1[SHA1_SIZE]; int i; printf("START: example SHA1 calc app\n"); memset((void *)&in_mem, 0, sizeof(in_mem)); memset((void *)&out_mem, 0, sizeof(out_mem)); memset((void *)&operation, 0, sizeof(operation)); memset(data, 'y', DATA_SIZE); memset(sha1, 0, SHA1_SIZE); /* Initialize context */ printf("Initializing context: "); ret = TEEC_InitializeContext(NULL, &context); if (ret != TEEC_SUCCESS) { printf("TEEC_InitializeContext failed: 0x%x\n", ret); goto end_1; } else { printf("initiliazed\n"); } /* Open session is expecting HASH algorithm */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].value.a = HASH_SHA1; /* Open session */ printf("Openning session: "); ret = TEEC_OpenSession(&context, &session, &uuid, connection_method, NULL, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_OpenSession failed: 0x%x\n", ret); goto end_2; } else { printf("opened\n"); } /* Register shared memory for initial hash */ /* Data */ in_mem.buffer = data; in_mem.size = DATA_SIZE; in_mem.flags = TEEC_MEM_INPUT; ret = TEEC_RegisterSharedMemory(&context, &in_mem); if (ret != TEE_SUCCESS) { printf("Failed to register DATA shared memory\n"); goto end_3; } printf("Registered in mem..\n"); /* Fill operation parameters */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].memref.parent = &in_mem; /* Invoke command */ printf("Invoking command: Update sha1: "); ret = TEEC_InvokeCommand(&session, HASH_UPDATE, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_InvokeCommand failed: 0x%x\n", ret); goto end_3; } else { printf("done\n"); } /* register a shared memory region to hold the output of the sha1 operation */ out_mem.buffer = sha1; out_mem.size = SHA1_SIZE; out_mem.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; ret = TEEC_RegisterSharedMemory(&context, &out_mem); if (ret != TEE_SUCCESS) { printf("Failed to allocate SHA1 shared memory\n"); goto end_3; } printf("Registered out mem..\n"); /* * Send some more data to calculate the hash over, this will be added to the origional hash * . This is not strictly needed it is a test for passing 2 memref params in a single * operation */ memset(data, 'Z', DATA_SIZE); /* Fill operation parameters */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE); /* * reuse the origional input shared memory, because we have just updated the contents * of the buffer */ operation.params[0].memref.parent = &in_mem; operation.params[1].memref.parent = &out_mem; /* Invoke command */ printf("Invoking command: Do final sha1: "); ret = TEEC_InvokeCommand(&session, HASH_DO_FINAL, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_InvokeCommand failed: 0x%x\n", ret); goto end_4; } else { printf("done\n"); } /* Printf sha1 buf */ printf("Calculated sha1: "); for (i = 0; i < SHA1_SIZE; i++) printf("%02x", sha1[i]); printf("\n"); /* Cleanup used connection/resources */ end_4: printf("Releasing shared out memory..\n"); TEEC_ReleaseSharedMemory(&out_mem); end_3: printf("Releasing shared in memory..\n"); TEEC_ReleaseSharedMemory(&in_mem); printf("Closing session..\n"); TEEC_CloseSession(&session); end_2: printf("Finalizing ctx..\n"); TEEC_FinalizeContext(&context); end_1: printf("END: example SHA1 calc app\n"); exit(ret); }
static int __init product_detect(void) { int err; int origin_err; struct tee_operation operation = {0}; struct tee_context context; struct tee_session session; /* Selects trustzone application needed for the job. */ struct tee_uuid static_uuid = { STATIC_TEE_TA_START_LOW, STATIC_TEE_TA_START_MID, STATIC_TEE_TA_START_HIGH, STATIC_TEE_TA_START_CLOCKSEQ, }; err = teec_initialize_context(NULL, &context); if (err) { pr_err("ux500-product: unable to initialize tee context," " err = %d\n", err); err = -EINVAL; goto error0; } err = teec_open_session(&context, &session, &static_uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, &origin_err); if (err) { pr_err("ux500-product: unable to open tee session," " tee error = %d, origin error = %d\n", err, origin_err); err = -EINVAL; goto error1; } memset(&operation, 0, sizeof(struct tee_operation)); if (cpu_is_u8500_family()) { operation.shm[0].buffer = &product_config; operation.shm[0].size = sizeof(product_config); operation.shm[0].flags = TEEC_MEM_OUTPUT; operation.flags = TEEC_MEMREF_0_USED; } else if (cpu_is_ux540_family()) { operation.param[0].tmpref.buffer = &product_config; operation.param[0].tmpref.size = sizeof(product_config); operation.types = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); } else { pr_err("ux500-product: incorrect memref\n"); err = -EINVAL; goto error1; } err = teec_invoke_command(&session, TEE_STA_GET_PRODUCT_CONFIG, &operation, &origin_err); if (err) { pr_err("ux500-product: fetching product settings failed, err=%d", err); err = -EINVAL; goto error1; } switch (product_config.product_id) { case TEE_PRODUCT_ID_8400: pr_info("ux500-product: u8400 detected\n"); break; case TEE_PRODUCT_ID_8500B: pr_info("ux500-product: u8500B detected\n"); break; case TEE_PRODUCT_ID_9500: pr_info("ux500-product: a9500 detected\n"); break; case TEE_PRODUCT_ID_7400: pr_info("ux500-product: u7400 detected\n"); break; case TEE_PRODUCT_ID_8500C: pr_info("ux500-product: u8500C detected\n"); break; case TEE_PRODUCT_ID_8500A: pr_info("ux500-product: u8500A detected\n"); break; case TEE_PRODUCT_ID_8500E: pr_info("ux500-product: u8500E detected\n"); break; case TEE_PRODUCT_ID_8520F: pr_info("ux500-product: u8520F detected\n"); break; case TEE_PRODUCT_ID_8520H: pr_info("ux500-product: u8520H detected\n"); break; case TEE_PRODUCT_ID_9540: pr_info("ux500-product: u9540 detected\n"); break; case TEE_PRODUCT_ID_9500C: pr_info("ux500-product: a9500C detected\n"); break; case TEE_PRODUCT_ID_8500F: pr_info("ux500-product: u8500F detected\n"); break; case TEE_PRODUCT_ID_8540APE: pr_info("ux500-product: u8540APE detected\n"); break; case TEE_PRODUCT_ID_8540XMIP: pr_info("ux500-product: u8540XMIP detected\n"); break; case TEE_PRODUCT_ID_8520E: pr_info("ux500-product: u8520E detected\n"); break; case TEE_PRODUCT_ID_8520J: pr_info("ux500-product: u8520J detected\n"); break; case TEE_PRODUCT_ID_UNKNOWN: default: pr_info("ux500-product: UNKNOWN! (0x%x) detected\n", product_config.product_id); break; } pr_info("ux500-product: JTAG is %s\n", ux500_jtag_enabled() ? "enabled" : "disabled"); error1: (void) teec_finalize_context(&context); error0: return err; }
static int _copy_op(struct tee_session *sess, struct tee_cmd_io *cmd_io, struct tee_cmd *cmd) { int res = -EINVAL; int idx; TEEC_Operation op; struct tee_data *param = &cmd->param; struct tee *tee; struct tee_context *ctx; BUG_ON(!sess->ctx); BUG_ON(!sess->ctx->tee); ctx = sess->ctx; tee = sess->ctx->tee; dev_dbg(_DEV(tee), "%s: > sessid=%08x\n", __func__, sess->sessid); if (tee_context_copy_from_client (sess->ctx, &op, cmd_io->op, sizeof(TEEC_Operation))) goto out; cmd->param.type_original = op.paramTypes; if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) { param->type = cmd->param.type_original; res = 0; goto out; } for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(op.paramTypes, idx); switch (type) { case TEEC_NONE: break; case TEEC_VALUE_INPUT: case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT: param->params[idx].value = op.params[idx].value; dev_dbg(_DEV_TEE, "%s: param[%d]:type=%d,a=%08x,b=%08x (VALUE)\n", __func__, idx, type, param->params[idx].value.a, param->params[idx].value.b); break; case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p,s=%zu (TMPREF)\n", idx, type, op.params[idx].tmpref.buffer, op.params[idx].tmpref.size); param->params[idx].shm = tee_context_create_tmpref_buffer(sess->ctx, op.params[idx]. tmpref.size, op.params[idx]. tmpref.buffer, type); if (IS_ERR_OR_NULL(param->params[idx].shm)) return -ENOMEM; dev_dbg(_DEV_TEE, "< %d %p:%zu (TMPREF)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); break; case TEEC_MEMREF_WHOLE: if (sess->ctx->usr_client) { if (tee_copy_from_user(ctx, ¶m->c_shm[idx], op.params[idx].memref. parent, sizeof (TEEC_SharedMemory))) { res = TEEC_ERROR_BAD_PARAMETERS; goto out; } } else param->c_shm[idx] = *op.params[idx].memref.parent; BUG_ON(!param->c_shm[idx].buffer); BUG_ON(!param->c_shm[idx].size); if (param->c_shm[idx].flags == TEEC_MEM_INPUT) type = TEEC_MEMREF_TEMP_INPUT; else if (param->c_shm[idx].flags == TEEC_MEM_OUTPUT) type = TEEC_MEMREF_TEMP_OUTPUT; else if (param->c_shm[idx].flags == (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) type = TEEC_MEMREF_TEMP_INOUT; if (check_shm (tee, (struct tee_shm_io *)¶m->c_shm[idx])) { dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p, s=%zu (WHOLE)\n", idx, type, op.params[idx].tmpref.buffer, param->c_shm[idx].size); param->params[idx].shm = tee_context_create_tmpref_buffer(sess->ctx, param->c_shm[idx].size, param->c_shm[idx].buffer, type); if (IS_ERR_OR_NULL(param->params[idx].shm)) return -ENOMEM; dev_dbg(_DEV_TEE, "< %d %p:%zu (WHOLE)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); } else { struct tee_shm *shm; /* The buffer is already allocated by the tee * get a reference on it */ shm = tee_shm_get(sess->ctx, (struct tee_shm_io *)¶m-> c_shm[idx]); if (!shm) /* not allocated by us, * is it a use case ? */ BUG_ON(1); param->params[idx].shm = devm_kzalloc(tee->dev, sizeof(struct tee_shm), GFP_KERNEL); if (!param->params[idx].shm) return -ENOMEM; param->params[idx].shm->parent = shm; param->params[idx].shm->ctx = sess->ctx; param->params[idx].shm->tee = tee; param->params[idx].shm->dev = tee->dev; param->params[idx].shm->size_req = param->c_shm[idx].size; param->params[idx].shm->size_alloc = 0; param->params[idx].shm->kaddr = shm->kaddr; param->params[idx].shm->paddr = shm->paddr; param->params[idx].shm->flags = shm->flags | TEE_SHM_PARENT; } break; case TEEC_MEMREF_PARTIAL_INPUT: case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT:{ uint32_t offset = op.params[idx].memref.offset; uint32_t size = op.params[idx].memref.size; if (sess->ctx->usr_client) { if (tee_copy_from_user (ctx, ¶m->c_shm[idx], op.params[idx].memref.parent, sizeof(TEEC_SharedMemory))) { res = TEEC_ERROR_BAD_PARAMETERS; goto out; } } else param->c_shm[idx] = *op.params[idx].memref.parent; dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p, offset=%x s=%d (PARTIAL)\n", idx, type, param->c_shm[idx].buffer, offset, size); if (type == TEEC_MEMREF_PARTIAL_INPUT) type = TEEC_MEMREF_TEMP_INPUT; else if (type == TEEC_MEMREF_PARTIAL_OUTPUT) type = TEEC_MEMREF_TEMP_OUTPUT; else if (type == TEEC_MEMREF_PARTIAL_INOUT) type = TEEC_MEMREF_TEMP_INOUT; if (check_shm (tee, (struct tee_shm_io *)¶m->c_shm[idx])) { param->params[idx].shm = tee_context_create_tmpref_buffer (sess->ctx, size, param->c_shm[idx].buffer + offset, type); if (IS_ERR_OR_NULL( param->params[idx].shm)) return -ENOMEM; } else { struct tee_shm *shm; /* The buffer is already allocated by * the tee * get a reference on it */ shm = tee_shm_get(sess->ctx, (struct tee_shm_io *) ¶m->c_shm[idx]); if (!shm) /* not allocated by us, * is it a use case ? */ BUG_ON(1); param->params[idx].shm = devm_kzalloc(tee->dev, sizeof(struct tee_shm), GFP_KERNEL); if (!param->params[idx].shm) return -ENOMEM; param->params[idx].shm->parent = shm; param->params[idx].shm->ctx = sess->ctx; param->params[idx].shm->tee = tee; param->params[idx].shm->dev = tee->dev; param->params[idx].shm->size_req = size; param->params[idx].shm->size_alloc = 0; param->params[idx].shm->kaddr = shm->kaddr + offset; param->params[idx].shm->paddr = shm->paddr + offset; param->params[idx].shm->flags = shm->flags | TEE_SHM_PARENT; } dev_dbg(_DEV_TEE, "< %d %p:%zu (PARTIAL)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); break; } default: BUG_ON(1); } param->type |= (type << (idx * 4)); } res = 0; out: dev_dbg(_DEV(tee), "%s: < fd=%d\n", __func__, res); return res; }