OP-TEE运行sha256函数——基于QEMUv8

一、参考资料

本例子参考了网上的开源代码,进行修改后得到本例子
https://github.com/shuaifengyun/basicAlg_use/tree/master

该源码中主要涉及了OP-TEE中的一些密码学函数

我自己例程的目标:通过在OP-TEE中添加自定义的CA和TA,完成运算sha256的功能。

如何自定义CA与TA不在本文的范围内,本文主要说明如何调用sha256函数并计算对应的值。

二、自定义CA

根据optee_example_hello_world的模板修改得到对应的模板。重点关注传参的部分,本例程使用tmpref传参。分别传了输入的数据和长度,输出的数据和长度。

#include <err.h>
#include <stdio.h>
#include <string.h>

/* OP-TEE TEE client API (built by optee_client) */
#include <tee_client_api.h>

/* For the UUID (found in the TA's h-file(s)) */
#include <hash_ta.h>

int main(void)
{
	TEEC_Result res;
	TEEC_Context ctx;
	TEEC_Session sess;
	TEEC_Operation op;
	TEEC_UUID uuid = TA_HASH_UUID;
	uint32_t err_origin;

	//initializa sha256 param
	uint32_t len = 10;
	char pData[] = {'1','2','3','4','5','6','7','8','9','0'};
	uint32_t outLen = 256;
	char output[256] = {0};

	res = TEEC_InitializeContext(NULL, &ctx);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InitializeContext failed with code 0x%x", res);

	
	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);

	memset(&op, 0, sizeof(op));

	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.size = len;
	op.params[0].tmpref.buffer = pData;
	op.params[1].tmpref.size = outLen;
	op.params[1].tmpref.buffer = output;

	res = TEEC_InvokeCommand(&sess, TA_HASH_CMD_SHA256_VALUE, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);

	TEEC_CloseSession(&sess);

	TEEC_FinalizeContext(&ctx);

	return 0;
}

三、自定义TA

首先在TA_InvokeCommandEntryPoint函数中增加判断函数,将新增的运行sha256的CMD写入其中一种case,之后会执行对应的sha256函数。

#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>
#include <hash_ta.h>

/*
 * Called when the instance of the TA is created. This is the first call in
 * the TA.
 */
TEE_Result TA_CreateEntryPoint(void)
{
	DMSG("has been called");

	return TEE_SUCCESS;
}

/*
 * Called when the instance of the TA is destroyed if the TA has not
 * crashed or panicked. This is the last call in the TA.
 */
void TA_DestroyEntryPoint(void)
{
	DMSG("has been called");
}

/*
 * Called when a new session is opened to the TA. *sess_ctx can be updated
 * with a value to be able to identify this session in subsequent calls to the
 * TA. In this function you will normally do the global initialization for the
 * TA.
 */
TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
		TEE_Param __maybe_unused params[4],
		void __maybe_unused **sess_ctx)
{
	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE);

	DMSG("open session has been called");

	if (param_types != exp_param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	/* Unused parameters */
	(void)&params;
	(void)&sess_ctx;

	/*
	 * The DMSG() macro is non-standard, TEE Internal API doesn't
	 * specify any means to logging from a TA.
	 */
	IMSG("Hash !\n");

	/* If return value != TEE_SUCCESS the session will not be created. */
	return TEE_SUCCESS;
}

/*
 * Called when a session is closed, sess_ctx hold the value that was
 * assigned by TA_OpenSessionEntryPoint().
 */
void TA_CloseSessionEntryPoint(void __maybe_unused *sess_ctx)
{
	(void)&sess_ctx; /* Unused parameter */
	IMSG("close session Goodbye!\n");
}

static TEE_Result inc_value(uint32_t param_types,
	TEE_Param params[4])
{
	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE);

	DMSG("inc has been called");

	if (param_types != exp_param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	IMSG("Got value: %u from NW", params[0].value.a);
	params[0].value.a+=5;
	IMSG("Increase value to: %u", params[0].value.a);

	return TEE_SUCCESS;
}

static TEE_Result dec_value(uint32_t param_types,
	TEE_Param params[4])
{
	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE,
						   TEE_PARAM_TYPE_NONE);

	DMSG("dec has been called");

	if (param_types != exp_param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	IMSG("Got value: %u from NW", params[0].value.a);
	params[0].value.a-=10;
	IMSG("Decrease value to: %u", params[0].value.a);

	return TEE_SUCCESS;
}

void TA_Print(char* buf,uint32_t len)
{
	uint32_t index = 0u;
	for(index = 0u;index < len;index++){
		TF("0x%02x",(buf[index] & 0xFFU));
	}
	TF("\n\n");
}

static TEE_Result sha256(uint32_t param_types,
	TEE_Param params[4])
{

	DMSG("sha256 called!");
	char* inputData = NULL;
	char* output = NULL;
	uint32_t inputLen = 0u;
	uint32_t outputLen = 0u;
	
	inputData = params[0].memref.buffer;
	inputLen = params[0].memref.size;
	output = params[1].memref.buffer;
	outputLen = params[1].memref.size;
	
	TEE_Result ret;
	TEE_OperationHandle oh;
	uint32_t alId = TEE_ALG_SHA256;
	
	//1
	ret = TEE_AllocateOperation(&oh,alId,TEE_MODE_DIGEST,0);
	if(ret != TEE_SUCCESS)
	{
		TF("sha256 handle failed!\n");	
	}
	//2
	TEE_DigestUpdate(oh,inputData,inputLen);
	//3
	ret = TEE_DigestDoFinal(oh,NULL,0,output,&outputLen);
	TA_Print(output,outputLen);
	if(ret != TEE_SUCCESS){
		TF("Do the final sha fail\n");
	}
	return TEE_SUCCESS;
}

/*
 * Called when a TA is invoked. sess_ctx hold that value that was
 * assigned by TA_OpenSessionEntryPoint(). The rest of the paramters
 * comes from normal world.
 */
TEE_Result TA_InvokeCommandEntryPoint(void __maybe_unused *sess_ctx,
			uint32_t cmd_id,
			uint32_t param_types, TEE_Param params[4])
{
	(void)&sess_ctx; /* Unused parameter */
	
	switch (cmd_id) {
	case TA_HASH_CMD_INC_VALUE:
		return inc_value(param_types, params);
	case TA_HASH_CMD_DEC_VALUE:
		return dec_value(param_types, params);
	case TA_HASH_CMD_SHA256_VALUE:
		return sha256(param_types, params);
	default:
		return TEE_ERROR_BAD_PARAMETERS;
	}
}

在自定义的sha256函数中,我们分别执行TEE_AllocateOperationTEE_DigestUpdateTEE_DigestDoFinal函数后,就可以得到inputdata进行sha256后得到的结果。

四、在头文件中自定义命令ID

我们可以在该头文件中(hash_ta.h),自定义sha256操作需要的CMD id,即TA_HASH_CMD_SHA256_VALUE。上面还有两个CMD id是之前Helloworld用的,在本例程中没有用到。也定义了对应的打印宏,即TF

#ifndef TA_HASH_H
#define TA_HASH_H

#define TA_HASH_UUID \
	{ 0x6aaaf200, 0x2450, 0x11e4, \
		{ 0xab, 0xe2, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }

/* The function IDs implemented in this TA */
#define TA_HASH_CMD_INC_VALUE		0
#define TA_HASH_CMD_DEC_VALUE		1
#define TA_HASH_CMD_SHA256_VALUE       2

#define TF MSG_RAW

#endif /*TA_HASH_H*/

五、编译运行

当修改完文件并自定义好CA与TA后,我们需要重新进行编译,再运行,才能得到刚刚的结果。

重新编译源工程

make -f qemu_v8.mk all -j8

运行

make -f qemu_v8.mk run-only

之后再在Normal World的对话框中输入该模块对应的名字,即可成功运行sha256算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值