2. TEE与OP-TEE基础

在移动终端、支付终端、车载控制器和物联网网关中,系统往往同时承载两类截然不同的任务:一类是界面、网络、多媒体等开放业务,另一类是密钥运算、生物特征比对、DRM 解密、安全启动校验等敏感操作。若把两者放在同一个执行环境中,任何一处应用漏洞都可能直接威胁密钥与身份凭证。TEE(Trusted Execution Environment,可信执行环境)正是为解决这一矛盾而提出的硬件级隔离方案:它与普通操作系统并存,却拥有独立的执行空间、内存与中断资源,只向普通世界暴露受控的调用接口。

一、TEE 的核心概念与安全目标

TEE 可以理解为处理器内部的一块“安全飞地”。它具备三个基本特征:隔离性——安全世界的代码与数据无法被普通世界直接读写;完整性——安全镜像在加载前需通过签名校验,运行中受硬件访问控制保护;可验证性——普通世界只能通过预先定义的命令入口请求服务,参数需经过检查。TEE 并不追求替代操作系统,而是把“必须可信”的最小功能收敛到安全侧,例如密钥管理、加解密、安全存储、可信 UI 和远程证明。

与之相对,REE(Rich Execution Environment,普通执行环境)运行 Linux、Android 等通用操作系统,负责业务逻辑与用户交互。REE 可以发起对 TEE 的请求,但不能读取 TEE 的内部状态。这种“普通世界请求、安全世界执行、结果受控返回”的模式,构成了后续所有 OP-TEE 通信工程的基础。

二、ARM TrustZone 架构:隔离如何落地

ARM TrustZone 是 TEE 在 ARM 平台上的典型硬件支撑。它并非两套物理 CPU,而是通过 安全状态位(NS bit) 将同一颗处理器的运行状态划分为 Secure World 与 Normal World。CPU 在任意时刻处于其中一种状态,配合总线侧的安全控制器,把内存、外设和中断也划分为安全与非安全属性。

关键机制包括:

  • 安全监控模式(Monitor Mode):位于两种世界之间的切换枢纽,通过 SMC(Secure Monitor Call)指令进入,负责保存和恢复上下文。
  • 地址空间控制器(TZASC):把 DRAM 划分为安全区与非安全区,阻止普通世界访问安全内存。
  • 中断控制器(GIC)与 TZPC:区分安全中断与非安全中断,保护安全外设不被普通世界直接操作。
  • MMU 与页表隔离:安全世界拥有独立页表,普通世界的地址映射无法覆盖安全区域。

因此,TrustZone 提供的是“硬件强制”的边界,而不是依赖软件自觉。OP-TEE 正是运行在 Secure World 中的可信操作系统,REE 侧的 Linux 内核与用户态程序则位于 Normal World。

ARM TrustZone 双世界隔离与 OP-TEE 组成 Normal World(普通世界 / REE) CA 客户端应用 调用 GlobalPlatform TEE Client API TEE Client Library(libteec) TEEC_InitializeContext / OpenSession / InvokeCommand Linux 内核 TEE 驱动 /dev/tee0、/dev/teepriv0 字符设备 SMC 调用入口 smc #0 触发世界切换 非安全内存 / 非安全外设 Secure World(安全世界 / TEE) TA 可信应用 实现具体安全业务,如密钥、加解密 TEE Internal Core API TA 侧标准接口,由 OP-TEE 提供 OP-TEE OS 内核 调度、内存管理、系统调用、TA 加载 安全监控与 SMC 处理 接收普通世界请求并分发 安全内存 / 安全外设 / 安全中断 Monitor Mode 世界切换 SMC 请求 结果返回 不可信执行环境:业务逻辑、网络、UI 可信执行环境:密钥、证明、安全存储

三、OP-TEE 的组成与运行位置

OP-TEE 是开源的可信执行环境实现,通常由三部分协同工作:

组件 运行位置 主要职责
OP-TEE OS Secure World 安全内核,负责 TA 加载、调度、内存与系统调用
OP-TEE Client(libteec) Normal World 用户态 提供 GP TEE Client API,封装会话与命令调用
OP-TEE Linux 驱动 Normal World 内核态 字符设备接口,完成 SMC 参数编组与共享内存映射
TA(Trusted Application) Secure World 具体安全业务逻辑,按 UUID 被加载与调用

一次典型调用链为:CA 调用 TEEC_OpenSession 打开会话,再通过 TEEC_InvokeCommand 发起命令;libteec 将请求交给 Linux 驱动,驱动通过 SMC 陷入 Monitor Mode,最终由 OP-TEE OS 调度对应 TA 执行,结果沿原路返回。整个过程对 CA 而言像一次普通函数调用,但实际跨越了硬件隔离边界。

四、GlobalPlatform API 与安全世界/普通世界划分

GlobalPlatform 定义了两套互补接口:普通世界侧使用 TEE Client API,安全世界侧使用 TEE Internal Core API。前者负责上下文初始化、会话建立、命令调用与共享内存注册;后者为 TA 提供密码学、安全存储、时间、属性查询等能力。二者通过 UUID 和命令 ID 对齐,形成标准化的跨世界契约。

TEEC_Context ctx;
TEEC_Session sess;
TEEC_UUID uuid = TA_HELLO_WORLD_UUID;
uint32_t err;

err = TEEC_InitializeContext(NULL, &ctx);
err = TEEC_OpenSession(&ctx, &sess, &uuid,
                       TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);

TEEC_Operation op = {0};
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
                                 TEEC_NONE, TEEC_NONE, TEEC_NONE);
op.params[0].value.a = 0x1234;
err = TEEC_InvokeCommand(&sess, CMD_INC_VALUE, &op, NULL);

TEEC_CloseSession(&sess);
TEEC_FinalizeContext(&ctx);

世界划分要点:普通世界负责“发起与展示”,安全世界负责“决策与密钥”。CA 不应假设自己能看到 TA 的内部数据;TA 也不应信任 CA 传入的指针,必须通过共享内存与参数类型做严格校验。

五、典型场景与常见误区

以安全支付为例:支付应用作为 CA 运行在 Android 用户态,它把交易金额、随机数和终端信息通过 TEEC_InvokeCommand 发给支付 TA;TA 在安全世界内完成密钥派生、交易签名,并只返回签名结果。即使 Android 被 root,攻击者也无法直接读取 TA 内存中的主密钥。

常见误区一:把 TEE 当成“更安全的 Linux”。TEE 资源有限,不适合运行复杂业务,TA 应保持小而专。
常见误区二:认为只要用了 OP-TEE 就自动安全。若 CA 与 TA 之间缺少参数校验、共享内存未正确注册,仍可能出现越权或数据泄露。
常见误区三:忽略世界切换开销。频繁 SMC 会带来明显延迟,批量命令与共享内存复用是常见优化手段。

复盘建议:排查 OP-TEE 通信问题时,先确认 /dev/tee0 是否存在、TA 是否已签名并放入 /lib/optee_armtz,再检查 UUID 与命令 ID 是否匹配,最后用 xtest 验证基础环境。多数“调用失败”并非密码学问题,而是会话未建立或参数类型不匹配。

理解 TEE 概念、TrustZone 隔离机制、OP-TEE 三组件分工以及 GlobalPlatform 双 API 契约,是后续编写 CA/TA、设计安全通信协议和进行安全调试的前提。只有先看清安全世界与普通世界的边界在哪里,才能正确决定哪些数据必须留在安全侧、哪些交互必须经过受控接口。