2. TEE架构概览:GlobalPlatform TEE规范、TEE内部组件、TEE API分层

好,咱们进入正题。第二章,我打算带你从宏观上把TEE的骨架摸清楚。很多初学者一上来就钻代码,结果越看越迷糊——说白了,就是脑子里没有一张架构图。这一章,我们就来画这张图。

我会从GlobalPlatform规范讲起,然后拆开TEE内部看看都有哪些零件,最后理清API的分层关系。嗯,这部分内容偏概念,但非常重要。你想想看,如果连房子有几层、每层干什么用都不知道,你怎么去适配接口?

2.1 GlobalPlatform TEE规范:行业的标准答案

先聊规范。TEE不是某一家公司闭门造车搞出来的,它是GlobalPlatform这个国际标准组织定义的。GlobalPlatform最早做智能卡规范,后来延伸到TEE,现在几乎所有的商用TEE方案——无论高通、联发科、华为还是Trustonic——都遵循这套规范。

我个人习惯把GP TEE规范看作一本“菜谱”。它不规定你必须用什么锅、什么火,但它告诉你:菜要切成什么形状、调料放多少、出锅温度是多少。换句话说,它定义了接口和行为,不限制实现。

核心规范版本:目前主流是GPD_SPE_009(TEE Internal Core API)和GPD_TEE_010(TEE Client API),对应v1.2/v1.3。做适配时,先确认你的TEE支持哪个版本。

GP规范主要覆盖三个层面:

  • TEE Client API:运行在REE侧(普通世界),供CA(Client Application)调用。比如打开会话、传输数据、调用TA命令。
  • TEE Internal Core API:运行在TEE侧(安全世界),供TA(Trusted Application)使用。比如安全存储、密码运算、时间获取。
  • TEE System Architecture:描述TEE内部怎么组织,包括内存隔离、中断处理、上下文切换等底层机制。

我在项目中遇到过一种情况:芯片厂商说“我们支持GP 1.2”,结果调TA的TEE_OpenPersistentObject时发现返回值跟规范对不上。查了半天,原来是他们只实现了API子集,有些接口是stub。所以,不要只看文档说“兼容GP”,一定要跑一遍CTS(兼容性测试套件)。

2.2 TEE内部组件:拆开看看里面有什么

一个典型的TEE系统,内部可以拆成几个关键组件。我习惯把它们分成“内核层”和“服务层”来看。

2.2.1 TEE内核

TEE内核是安全世界的操作系统核心。它不像Linux那么庞大,通常是一个微内核或轻量级RTOS。它的职责很纯粹:

  • 内存隔离:通过硬件MMU或TZASC(TrustZone Address Space Controller)把安全世界和普通世界的内存彻底隔开。
  • 上下文管理:管理TA的加载、运行、销毁,以及REE侧与TEE侧的切换。
  • 中断处理:安全中断(S-EL1 FIQ)由TEE内核处理,普通中断直接透传给REE。

我记得第一次看OP-TEE的内核代码时,发现它的核心只有几万行C代码,跟Linux动辄上千万行比,简直是小而美的典范。但别小看它——每一行都经过严格的安全审计。

2.2.2 TEE安全存储

安全存储是TEE最常用的功能之一。TA需要保存密钥、证书、敏感配置,这些不能放在REE的文件系统里,因为那里对攻击者来说几乎是透明的。

GP规范定义了两种安全存储对象:

类型 存储位置 特点
持久对象 安全世界专用存储区(如RPMB分区或安全Flash) 掉电不丢失,支持加密和完整性校验
临时对象 TEE内核内存 会话结束后自动销毁,适合存放临时密钥

避坑指南:我曾经在适配RPMB(Replay Protected Memory Block)时踩过坑。RPMB的写次数有限,如果TA频繁写入小数据,很快就会耗尽寿命。后来我加了一层缓存,批量写入,问题才解决。所以,安全存储不是随便用的,要考虑磨损均衡。

2.2.3 TEE通信代理

通信代理是REE和TEE之间的桥梁。它负责:

  • 会话管理:CA发起TEEC_OpenSession,通信代理负责在TEE侧创建对应的TA实例。
  • 消息传递:CA通过TEEC_InvokeCommand发送命令和数据,通信代理把这些参数打包,通过SMC(Secure Monitor Call)指令传递给TEE内核。
  • 共享内存管理:CA和TA之间需要共享数据时,通信代理负责分配和映射共享内存,并确保REE侧不能篡改。

说白了,通信代理就是一个“翻译官”。REE侧说“我要调用TA的加密功能”,通信代理就把这句话翻译成TEE内核能理解的SMC调用,再把结果翻译回来。

2.3 TEE API分层:从应用到底层

API分层是理解TEE编程模型的关键。我画了一张图,你可以对照着看。

TEE API分层架构 REE侧(普通世界) CA(Client Application) 调用 TEE Client API(TEEC_* 函数) 通信代理 / TEE Driver SMC调用 / 共享内存管理 TEE侧(安全世界) TA(Trusted Application) 调用 TEE Internal Core API(TEE_* 函数) TEE内核(安全OS) 内存隔离 / 上下文管理 / 中断处理 硬件安全扩展(TrustZone / TEE硬件) API分层说明 CA只能调用Client API TA只能调用Internal API 通信代理是唯一桥梁

从这张图可以清楚看到:

  • CA只跟Client API打交道,它不知道TEE内部怎么实现的。
  • TA只跟Internal Core API打交道,它不关心底层硬件细节。
  • 通信代理是唯一的桥梁,负责跨世界的数据传递。
  • TEE内核和硬件层提供底层的安全保证。

这种分层设计的好处是:上层应用不需要关心底层实现。你写CA的时候,只需要调用TEEC_OpenSession、TEEC_InvokeCommand这些标准接口,至于底层是用SMC还是用Hypervisor调用,那是TEE厂商的事。

注意:虽然API是标准的,但不同TEE方案的实现细节有差异。比如OP-TEE的共享内存分配方式和Trustonic的就不完全一样。做适配时,一定要以目标平台的TEE SDK文档为准,不能只看GP规范。

2.4 小结:这张图要刻在脑子里

这一章的内容偏理论,但它是后续所有实战的基础。我个人建议你把上面那张SVG图多看几遍,最好能自己画一遍。搞清楚CA、TA、通信代理、TEE内核、硬件层这五层的关系,后面讲接口适配的时候你才不会晕。

嗯,我记得刚接触TEE那会儿,花了整整一周才把GP规范里的API分类理清楚。后来发现,只要把分层逻辑搞明白,剩下的就是查文档、调参数的事了。所以,别急,先把骨架搭好。