嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > TF-A 与 TEE OS

TF-A 与 TEE OS

1、背景

大量的嵌入式设备使用 ARM 为核心的芯片,为了保证安全 ARM 推出了 Arm Trusted Firmware 的可信固件,简称 TF-A。它是一个开源的软件,最早是用在 Armv8-A。它的作用是隔离硬件,为硬件提供一个安全环境并且提供安全服务。

智能手机里面保存了我们的指纹、Face ID(3D 人脸信息)、虹膜、银行卡密码等重要信息。因此智能设备的安全问题就成了半导体行业的重要问题,ARM 为此提供了 TrustZone 解决方案,TrustZone 将 CPU 的工作状态分为了 Secure World 和 Normal World,涉及到安全相关的内容运行在安全世界,比如指纹、密码等,其他的操作都在非安全世界运行,比如应用程序。TrustZone 是一种硬件解决方案。

我们并不会直接去官方网站下载 TF-A 的源码,这样的开发难度太大,半导体厂商都会从 TF-A 官网下载源码,然后修改适配自己的芯片,把自家的芯片加进去。我们在实际项目开发中直接使用半导体原厂给提供的 TF-A 即可

TF-A 是有自己的 Makefile 文件的,而且真正编译的时候也是要用 TF-A 自己的 Makefile。

TF-A 主要保护的就是设备启动过程,通过各种鉴权,保证设备启动的过程中每个阶段的固件都是安全的,防止被不法分子替换某些启动固件导致安全信息泄露。

对于传统的 ARM 处理器而言 , Linux 系统的启动流程是:内部 BootROM -> Uboot -> kernel -> rootfs,整个启动过程是一个链式结构,启动过程其实是没有安全校验的。加入 TF-A 固件以后,TF-A 就可以对 uboot、kernel 进行校验,如果还要使用 TEE OS(Trusted Execution Environment,TEE),那么 TF-A 还要完成对 TEE OS 的校验。

Linux 启动是一个链式结构,因此安全启动的鉴权(校验)过程也是链式结构的。在系统启动的过程中,会先对下一个要加载运行的镜像进行鉴权,只有鉴权成功此镜像才能运行,并进入到下一阶段,只要其中有一环鉴权失败,那么整个系统就会启动失败。

2、获取 TF-A 源码

TF-A 是 ARM 官方提供的一个固件代码,它提供了统一的接口标准,方便不同的半导体厂商将自家的芯片添加到 TF-A 里面。

TF-A 官网地址为:https://www.trustedfirmware.org/,此网站不仅仅提供了 TF-A,还有针对 Cortex-M 单片机的 TF-M,以及 OP-TEE 等安全相关软件库。详情参考《Trusted Firmware-A(TF-A 用户手册).pdf》

TF-A 一共分为 5 部分:bl1、bl2、bl2u、bl31、bl32 和 bl33,打开 TF-A 源码目录,可以看到这 5 部分:

bl1、bl2 和 bl31 都属于 TF-A 固件,而 bl32 和 bl33 是 TF-A 要启动的其他第三方固件,比如 TEE OS 和 uboot。

bl1、bl2、bl31、bl32 和 bl33 是 TF-A 的不同启动阶段,TF-A 的启动过程是链式的,不同的阶段完整的功能不同, bl1、bl2、bl31、bl32 和 bl33 全名如下:

bl1:Boot loader stage 1 (BL1)
bl2:Boot loader stage 2 (BL2)
bl31:Boot loader stage 3-1 (BL31)
bl32:Boot loader stage 3-2 (BL32)
bl33:Boot loader stage 3-3 (BL33)

3、ARMv7 和 ARMv8 权限等级

TF-A 一开始是为 ARMv8 准备的,ARMv8 最突出的特点就是支持 64 位指令,但是为了兼容原来的 ARMv7,ARMv8 提供了两种指令集:AAarch64 和 AArch32,根据字面意思就是 64 位和 32 位,其中 AArch32 和 ARMv7 基本一样(会多一些其他操作指令)。

安全不能仅仅依靠软件来实现,也是需要硬件支持的,比如 ARM 处理器就有不同的运行等级,运行在低等级(非安全模式)的应用就不能访问高等级(安全模式)的资源,以此来保证敏感资源的安全性。

ARMv7-A 工作模式

以前的 ARMv7 处理器有 7 中运行模型:User、FIQ、IRQ、Supervisor(SVC)、Abort、Undef 和 System。新的 ARMv7-A 架构加入了 TrustZone 安全扩展,所以就新加了一种运行模式:Monitor,新的处理器架构还支持虚拟化扩展,因此又加入了另一个运行模式:Hyp,所以 Cortex-A7 处理器有 9 种处理模式,如表所示:

不同的处理器模式下,CPU 对于硬件的访问权限不同,叫做 Privilege Level(特权等级),一共有两个特权级别:Privilege(特权级)和 non-privilege(非特权级)。其中只有 User 模式处于 non-privilege,也就是非特权级,剩下的 8 个模式都是 privilege(特权级)。

系统启动以后应用软件都是运行在 User 模式,也就是非特权级,这个时候处理器对于敏感资源的访问是受限的,如果要访问这些敏感资源就需要切换到对应的工作模式下。

ARMv7-A 对 Privilege Level 进行了命名:PL0 和 PL1,后来也出现了 PL2,用于虚拟扩展。ARMv7-A 新增的 Monitor 模式就是针对安全扩展的,为了支持 TEE 而引入的。

ARMv8 工作模式

ARMv8 没有 Privilege level 的概念,取而代之的是 Exception level(异常级别)简称为 EL,用于描述特权级别,一共有 4 个级别:EL0、EL1、EL2 和 EL3,数字越大,级别越高,权限越大!这四个 EL 级别对应的应用场合如下:

EL0:一般的应用程序
EL1:操作系统,比如 Linux
EL2:虚拟化(Hypervisor),虚拟机管理器
EL3:最底层的安全固件,如 ARM Trusted Firmware(ATF/TF-A)

ARMv8 提供了两种安全状态:Secure 和 Non-secure,也就是安全和非安全,Non-secure 也就是正常世界(Normal World)。我们可以在 Non-secure 运行通用操作系统,比如 Linux,在 Secure 运行可信操作系统,比如 OP-TEE,这两个操作系统可以同时运行,这个需要处理器支持 ARM 的 TrustZone 功能。在 Normal world 和 Secure world 下,ARMv8 个 EL 等级对应的内容如图所示:

在 ARMv8 的 AArch32 模式下,处理器模式如图所示:

在 AArch32 模式下,EL0~LE3 对应 ARMv7 的不同工作模式:

EL0:对应 ARMv7 的 User 工作模式
EL1:对应 ARMv7 的 SVC、ABT、IRQ、IRQ、UND 和 SYS 这 6 中工作模式
EL2:对应 ARMv7 的 Hyp 工作模式
EL3:对应 ARMv7 的 Mon 工作模式

可以看出,只有 EL3 是用于安全监视器的,所以 TF-A 主要工作在 EL3 下,在看 TF-A 源码的时候会看到大量的“EL3”字样的文件或代码。

4、TF-A 不同启动阶段

FSBL:First stage boot loader,第一阶段启动文件
SSBL:Second stage boot loader,第二阶段启动文件

TF-A 分为不同的启动阶段,按照链式结构依次启动,ATF 代码启动流程如图所示:

当芯片复位以后首先运行 bl1 代码,bl1 一般是芯片内部的 ROM 代码,bl1 主要工作就是将外置 Flash 中的 bl2 固件加载到指定的 RAM 中,然后跳转到 bl2 部分。

bl2 为安全启动固件,bl2 会将剩余的三个启动阶段 bl31、bl32 和 bl33 对应的镜像文件加载到指定的内存中。比bl32 中的安全操作系统(OP-TEE),bl31 中的 EL3 运行时固件(Runtime Firware),bl33 中的 uboot。bl2 将这些固件加载完成以后就会启动相应的固件,也就是进入到第三启动阶段。

TF-A 启动流程就是:bl1 -> bl2 -> (bl31/bl32/bl33)。注意,bl31、bl32 和 bl33 对应的镜像不需要全部都有,但是 bl33 一般是必须的,因为 bl33 一般是 uboot,这个是很重要的!

bl 1

bl 1 是 TF-A 的第一个启动阶段,芯片复位以后就会运行 bl1 镜像,TF-A 提供了 bl1 源码。但是,实际上 bl1 一般是半导体厂商自己编写的内部 Boot ROM 代码,并没有使用 TF-A 提供的 bl1 镜像。因此 bl1 部分的实现就千差万别,不同的半导体厂商有不同的实现方法。

一般 bl1 要做的就是初始化 CPU,如果芯片支持不同的启动设备,那么还需要初始化不同的启动设置,比如 NAND、EMMC、SD、USB 或串口等。然后根据 BOOT 引脚的高低电平来 判断当前所选择的启动设备,从对应的启动设备中加载 bl2 镜像,并放到对应的内存中,最后跳转到 bl2 镜像并运行。

bl 2

bl 2 会进一步的初始化芯片,比如初始化 DDR、MMU、串口等。bl2 会将剩下三个阶段 (bl31、bl32 和 bl33)对应的镜像加载到指定的内存中,最后根据实际情况来启动剩下三个阶段的镜像。

bl 31

在 AArch64 中,bl31 主要是 EL3 的 Runtime 固件。

bl 32

bl32 一般为安全系统(TEE OS)固件,比如 OP-TEE。TF-A 为 AArch32 提供了 EL3 的 Runtime 软件,这个 Runtime 软件就是 bl32 固件,sp_min 就是这个 Runtime 软件。大家可以打开 TF-A 的 bl32 源码文件夹,其下就有一个名为“sp_min”的子文件夹,这个就是 bl32 的 sp_min 源码,如图所示:

bl32 提供运行时安全服务,在 TF-A 中默认使用 sp_min。sp_min 是一个最小的 AArch32 安全负载(Secure Payload),整合了 PSCI 库以及 AArch32 的 EL3 运行时软件sp_min 可以替代可信系统(TEE OS)或者可信执行环境(TEE),比如 OP-TEE。用户可以自行选择 bl32 使用哪个软件包。

bl32 充当安全监控(secure monitor),因此它向非安全系统(non-secure os,比如 linux)提供了一些安全服务。非安全的应用软件可以通过安全监控调用(secure monitor calls)来使用这些安全服务,这些代码支持标准的服务调用,比如 PSCI。

bl 33

bl33 就是 Normal World 下的镜像文件,比如 uboot。

至此,我们对 TF-A 的基本启动流程有了一个大概的了解,我们知道了 TF-A 分为多个阶 段,不同的阶段其工作内容不同。但是,在实际的开发中并不一定会用到 TF-A 中所有启动阶段。

TF-A 是用于完成安全启动的,OP-TEE 是 TEE OS,如果使用 OP-TEE 的话它会和 linux 内核同时运行,OP-TEE 负责可信应用,linux 就是普通的应用程序。

TF-A 分为了不同阶段:bl1、bl2、bl31、bl32 和 bl33,这个主要是面向 AArch64 的,对于 AArch32 而言只有 4 个阶段:

bl1:第 1 个阶段,一般为芯片内部 ROM 代码
bl2:第 2 个阶段,可信启动固件
bl32:EL3 运行时(Runtime)软件
bl33:非安全固件,比如 uboot

其中 bl1、bl2 和 bl32 都属于 TF-A 的一部分(如果你使用 TF-A 提供的 bl1 的话)。

5、TF-A 移植

当我们实际做产品的时候我们的硬件平台肯定会和芯片原厂的有区别,比如 DDR 容量会改变,自己的硬件没有使用到官方开发板所使用的 PMIC 芯片等等。因此这里就涉及到将半导体原厂提供的 TF-A 移植到我们的硬件上

所谓的移植就是让半导体官方提供的软件在自己的硬件平台上运行起来,准确的说应该是将自己的硬件添加到官方软件包。TF-A 是 ARM 官方出品的一个软件包,半导体厂商会从 ARM官方下载这个最正宗的 TF-A 软件包,然后将自己公司的 SOC 芯片添加进去,最终打包好提供给 SOC 用户,这个就是所谓的 SDK 包。

TF-A 的移植全部是修改设备树。可以参考芯片原厂 demo 板的设备树,创建我们自己硬件的设备树,一般主要修改串口、电源、TF 卡、EMMC、USB 等节点信息。

以 STM32MP157 为例,移植成功后的 TF-A 的启动 log 如下,TEE OS 用的 sp_min:

参考《【正点原子】STM32MP1嵌入式Linux驱动开发指南》

6、TEE OS

TEE:Trusted Execution Environment,可信执行环境

REE:Rich Execution Environment,移动设备通用环境,运行通用的 OS,如 Android,I0S 系统

TEE OS 发展历程

TEE 的前身:Open Mobile Terminal Platform 于 2006 年提出一种双系统解决方案:在一智能终端下,除了多媒体操作系统外再提供一个隔离的安全操作系统,这一运行在隔离的硬件之上的隔离安全操作系统用来专门处理敏感信息以保证信息的安全。

TEE 标准正式提出:OMTP 于 2009 年提出了 TEE 标准,说明了 TEE 同时包含了硬件和软件,目标是为应用程序提供必要的支持。定义了两个安全级别,第一个级别是可以应对软件方面的攻击,第二个级别是可以同时应对软件和硬件攻击。

TEE 的实现:基于 OMTP 的方案,ARM 公司提出了一种硬件虚拟化技术 TrustZone 及其相关硬件实现方案。TrustZone 即是支持 TEE 技术的产品。TrustZone 在概念上将 Soc 的硬件和软件资源划分为安全(Secure World)和非安全(Normal World)两个世界,所有需要保密的操作在安全世界执行(如指纹识别、密码处理、数据加解密、安全认证等),其余操作在非安全世界执行(如用户操作系统、各种应用程序等)

TEE 当前的标准:Global Platform(智能卡多应用管理规范的组织,简称为 GP),从 2011 年起开始起草制定相关的 TEE 规范标准,并联合一些公司共同开发基于 GP TEE 标准的可信操作系统。如今大多数基于 TEE 技术的 Trust OS 都遵循了 GP 的标准规范。

Android 6 引入 TEE OS 机制 (2015-2016)

TEE OS 厂家

OP-TEE:完全开源的方案,官方网址:https://www.op-tee.org/,厂商需要自行移植适配

高通 QSEE:全称是 Qualcomm Security Execution Environment,高通完全自主研发的 TEE OS。用高通芯片的厂商无需外购方案。

Trustonic:英国厂商,ARM 背景。采用 MTK 平台的厂商大都用这家 TEE 方案,售价较高。

豆荚科技:被大部分中小手机厂商采用,OPPO、VIVO 早年也用过,小米目前在使用。

瓶钵:位于上海,上海交大背景。跟豆英是直接竞争对手,市场份额不如豆荚。

华为:华为麒麟系列芯片,全部采用自研 TEE 安全解决方案。

三星 Knox:My Knox,三星自研的 TEE 安全解决方案。

Google : 推出 Trusty TEE 操作系统,但并不强制客户必须使用 Trusty。

其他名词:

TA: Trusted Application,运行在 TEE 环境下的应用

CA: Client Application,运行在 REE 环境下的应用

TrustZone:基于 ARM 架构的移动平台芯片,理论上都支持 TrustZone。TrustZone 是独立的一个安全的世界,基于 TrustZone 可实现 TEE。