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算法。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ACIPHER代码在OP-TEE examples中是一个对称加密算法的例子,它展示了如何使用OP-TEE来实现加密和解密数据。 ACIPHER实现了AES加密算法,并在TA(Trusted Application)中运行,以保证加密数据的安全性。代码中包含了加密和解密数据的函数,以及如何与OP-TEE安全模块进行通信的详细说明。通过阅读ACIPHER代码,您可以了解如何在OP-TEE环境中实现对称加密算法,以及如何使用TA来保护敏感数据的安全。 ### 回答2: 在OP-TEE examples中,acipher代码是指实现了在安全环境中进行加密和解密操作的示例代码。 首先,acipher代码涉及到的主要功能是使用Open Portable TEEOP-TEE)提供的加密功能来保护敏感数据。它提供了一种安全的方式来执行加密和解密操作,以免被恶意软件或攻击者窃取或篡改。具体而言,acipher代码为应用程序提供了一种方式来调用OP-TEE中的加密APIs,以进行对称密码和非对称密码的加密和解密操作。 其次,acipher代码中包含了一些示例函数,这些函数展示了如何使用OP-TEE的加密功能。例如,可以使用acipher_init()函数来初始化加密库,acipher_aes_encrypt()函数执行AES加密操作,acipher_rsa_encrypt()函数执行RSA加密操作,acipher_aes_decrypt()函数执行AES解密操作等等。这些函数使用OP-TEE提供的API,将敏感数据以安全的方式进行加密和解密。 最后,acipher代码还提供了示例数据和详细的代码注释,以帮助开发人员理解和使用加密功能。开发人员可以根据自己的需求自定义这些代码,以满足特定的加密需求。同时,acipher代码还提供了错误处理机制,以确保加密操作的安全性和稳定性。 总之,在OP-TEE examples中,acipher代码所展示的是如何在安全环境中使用OP-TEE提供的加密功能来保护敏感数据。通过理解和使用这些示例代码,开发人员可以更好地应用加密算法,提高数据的安全性和完整性。 ### 回答3: acipher是OP-TEE examples中的一个代码示例,用于演示在安全环境执行加密操作的方法。在理解acipher代码之前,首先需要了解OP-TEE的基本概念。 OP-TEEOpen Portable Trusted Execution Environment)是一个开放的可移植的可信执行环境,它提供了一个安全执行环境,可以独立于操作系统运行。acipher代码则是OP-TEE examples中的一个示例,用于展示如何在OP-TEE环境中使用加密算法。 acipher代码的主要功能是执行一些常见的加密操作,如对称加密、非对称加密、哈希等。它通过调用OP-TEE提供的安全接口函数,来完成这些加密操作。 在acipher代码中,首先会初始化OP-TEE环境,并创建一个与之关联的会话。然后,根据用户的选择,选择执行不同的加密操作。例如,可以选择对一段明文进行对称加密,使用AES算法和密钥进行加密,并将密文存储在OP-TEE安全缓冲区中。还可以选择执行非对称加密,使用RSA算法进行公钥加密或私钥解密。 代码还提供了其他一些功能,如生成随机数、计算哈希值等。通过这些功能,acipher代码可以满足一些基本的加密需求。 总的来说,acipher代码主要是为了向开发者展示如何在OP-TEE环境中使用加密算法。通过对代码的理解和学习,开发者可以了解到如何在安全环境执行加密操作,并将其应用到实际场景中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值