TEE
伴随着日益增多的智能终端设备,为了确保终端设备的数据安全,我们最好还要在系统中构建一个相对来说更为可信的运行环境,以确保即便在系统被攻破后,入侵者也无法获取用户的关键信息,这样的一个可信赖安全的运行环境被称为可信执行环境(Trusted Execution Environment,TEE) 。
如果将整个运行环境按照可信与不可信分为安全世界(secure world)和正常世界(Normal world),那么一套完整的TEE解决方案就需要包含正常世界的客户端应用(Client Application,CA)、安全世界的可信应用(Trust Application,TA)、可信硬件驱动、以及安全世界的可信操作系统(TEE OS)以及可信的硬件。
ARM自ARMv6结构开始,就引入了TrustZone技术。支持TrustZone技术的ARM核将运行状态分为安全世界和正常世界两种状态,并通过安全监控模式调用指令(secure monitor call,smc)实现安全世界和正常世界状态的转换。在安全世界状态,系统只能访问安全世界的资源,同理,在正常世界只能访问正常世界的资源。通常也将安全世界称为TEE侧,正常世界称为REE侧。REE即Rich Execution Environment。
目前国内外不同的厂商有不同的TEE解决方案,但是一般都会遵循GP(Global Platform)规范,提供相同的API供开发者开发CA和TA。
OP-TEE
OP-TEE是一套按照GP规范开发,支持通用ARMv7和ARMv6平台的开源TEE解决方案。开发者可以轻松的从github上获取optee源码。
整个optee的源码主要有四个project,分别是:
optee_os: https://github.com/OP-TEE/optee_os.git
optee_client: https://github.com/OP-TEE/optee_client.git
optee_test: https://github.com/OP-TEE/optee_test.git
optee_linuxdriver: https://github.com/OP-TEE/optee_linuxdriver.git
{
ps:在本文档中,我copy了官方linux内核中driver/tee目录中的driver做分析
也可以直接去我的github上讲四个project下载下来:
https://github.com/4LogCoder/optee.git
}
你可以选择单独下载这四个project,同时也可以使用repo工具,统一管理,repo仓库的地址是:https://github.com/OP-TEE/manifest.git
OP-TEE源码框架
整个optee的源码主要有四个部分,分别是:
optee_os:一个小型的安全操作系统内核
optee_clien:主要分为两个部分,一是tee_supplicant源码,编译后作为一个正常世界的可执行文件,系统启动后一直在后台运行,辅助响应optee_os对正常世界的资源访问和操作;二是libteec库的源码,供运行在正常世界用户空间的CA调用。
optee_linuxdriver:linux系统的driver,是正常世界和安全世界的交流途径。
Optee_test:optee提供的测试demo,可供用户参考。
OP-TEE框架
再详细分析源码之前,我们先以一个完整的demo介绍下optee的工作流程。
Demo功能:利用SHA算法计算一段明文的摘要,并返回结果。
在详细介绍之前,我们先看一下整个框架图:
- 首先运行在Normal World User空间的CA调用libteec库相关接口,申请一块共享内存(share memory),将待计算的明文存放在这块内存中,并申请初始化一个session。
- 在linteec库中,由系统调用进而陷入Normal World的kernel空间,也就是到达tee_linuxdriver,在driver中,调用smc指令,进行Normal world和secure world的转换
- 转换至secure world状态后由optee_os对命令解析,在这里的命令为初始化一个session,首先需要去动态load相应的TA文件,由于我们编译后的TA文件一般存放在REE侧的文件系统中,所以在这里,optee_os会发起RPC请求,也就是重新调用smc指令,转换至Normal world后,通过optee_linuxdriver到达tee_supplicat,tee_supplicat解析这一请求,去指定的文件夹寻找指定的TA文件,并load进内存。
- 在经过初始化session后,相应的TA文件已经load,此时我们再在CA中发起SHA计算请求,并将共享内存地址作为参数传入
- 此时系统再次陷入Normal world的kernel空间,并通过smc调用,将请求发送至optee_os
- optee_os接收请求后,调用相应的TA执行,TA执行计算完成之后,将计算结果放在共享内存中,并返回,按照相同的路径传回至CA中,至此计算完成。