Esempio n. 1
0
/******************************************************************************
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;
}
Esempio n. 4
0
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);
 }
Esempio n. 6
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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");
}
Esempio n. 10
0
/*
 * 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 );
	}	
}
Esempio n. 11
0
/* 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);
}
Esempio n. 17
0
/******************************************************************************
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);
}
Esempio n. 22
0
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);
		}
	}

}
Esempio n. 23
0
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;
}
Esempio n. 24
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);
}
Esempio n. 25
0
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;
}
Esempio n. 27
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;
}
Esempio n. 29
0
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, &param->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 *)&param->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 *)&param->
						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, &param->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 *)&param->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 *)
							&param->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;
}