在一些原生的SoC中,crypto engine(或HSE)没有得到良好的支持,例如某种加密算法不支持,或者key的存储空间不够,可考虑采用ARM原生的Trustzone/OPTEE-OS的方案来解决此问题。
ARM TrustZone是基于硬件的安全功能,它通过对原有硬件架构进行修改,在处理器层次引入了两个不同权限的保护域——安全世界和普通世界,任何时刻处理器仅在其中的一个环境内运行。同时这两个世界完全是硬件隔离的,并具有不同的权限,正常世界中运行的应用程序或操作系统访问安全世界的资源受到严格的限制,反过来安全世界中运行的程序可以正常访问正常世界中的资源。这种两个世界之间的硬件隔离和不同权限等属性为保护应用程序的代码和数据提供了有效的机制:通常正常世界用于运行商品操作系统(例如Android、iOS等),该操作系统提供了正常执行环境(Rich Execution Environment,REE);安全世界则始终使用安全的小内核(TEE-kernel)提供可信执行环境(Trusted Execution Environment,TEE),机密数据可以在TEE中被存储和访问。这样一来即使正常世界中的操作系统被破坏或入侵(例如iOS已被越狱或Android已被ROOT),黑客依旧无法获取存储在TEE中的机密数据。
TrustZone通过硬件隔离安全世界和非安全世界,在软件上,如果使用Trustzone则需要TEE内核系统与TEE服务系统。OPTEE-OS实现一套基本的OS功能,以管理多个TEE实例,每个实例托管一个特定的应用程序。TEE内核实现的功能有:管理安全世界的内存、对每个TEE实施内存保护、处理TEE与OS之间的通信以及为TEE应用程序提供API。
void cipher_buffer(struct test_ctx *ctx, char *in, char *out, size_t sz)
{
TEEC_Operation op;
uint32_t origin;
TEEC_Result res;
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.buffer = in;
op.params[0].tmpref.size = sz;
op.params[1].tmpref.buffer = out;
op.params[1].tmpref.size = sz;
res = TEEC_InvokeCommand(&ctx->sess, TA_AES_CMD_CIPHER,
&op, &origin);
if (res != TEEC_SUCCESS)
errx(1, "TEEC_InvokeCommand(CIPHER) failed 0x%x origin 0x%x",
res, origin);
}
static TEE_Result cipher_buffer(void *session, uint32_t param_types,
TEE_Param params[4])
{
const uint32_t exp_param_types =
TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_OUTPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
struct aes_cipher *sess;
/* Get ciphering context from session ID */
DMSG("Session %p: cipher buffer", session);
sess = (struct aes_cipher *)session;
/* Safely get the invocation parameters */
if (param_types != exp_param_types)
return TEE_ERROR_BAD_PARAMETERS;
if (params[1].memref.size < params[0].memref.size) {
EMSG("Bad sizes: in %d, out %d", params[0].memref.size,
params[1].memref.size);
return TEE_ERROR_BAD_PARAMETERS;
}
if (sess->op_handle == TEE_HANDLE_NULL)
return TEE_ERROR_BAD_STATE;
/*
* Process ciphering operation on provided buffers
*/
return TEE_CipherUpdate(sess->op_handle,
params[0].memref.buffer, params[0].memref.size,
params[1].memref.buffer, ¶ms[1].memref.size);
}
以s32g274板子为环境,板子需要启动tfa和optee-os,并且编译了tee-supplicant应用程序。运营REE侧的应用,可以看到TEE的log,完成AES的加密。