Linux5.10内核TEE驱动架构深度解析

📅 2026/6/16 14:47:54
Linux5.10内核TEE驱动架构深度解析
Linux 5.10 内核 TEE 驱动详解本文基于Linux 5.10 LTS 内核Android 12~Android 14 官方标配 GKI 通用内核版本完整梳理 TEE 驱动架构、工作流程、libteec 服务对接、ATF 世界切换与数据交互全链路。所有 SMC 通信逻辑均集成在 optee/core.c 与 optee/optee_smc.h 中.一、整体分层架构与源码结构Linux 5.10 TEE 子系统采用「通用框架抽象 厂商驱动实现 架构通信封装」三层松耦合设计向上提供统一接口向下对接 OP-TEE 等安全操作系统是正常世界REE与安全世界TEE交互的唯一内核桥梁。1. 三层架构职责划分架构层级核心源码路径核心职责TEE 核心框架层drivers/tee/tee_core.ctee_shm.ctee_bus.c与具体 TEE 实现无关的通用抽象字符设备模型、共享内存池、TEE 总线、上下文与会话管理OP-TEE 驱动实现层drivers/tee/optee/core.ccall.cshm.cOP-TEE 专属适配固件探测、消息协议封装、中断处理、RPC 分发架构通信层drivers/tee/optee/optee_smc.harch/arm64/kernel/smccc-call.S遵循 ARM SMCCC 标准封装 SMC 指令触发、寄存器参数打包与返回值解析2. 5.10 内核完整目录结构drivers/tee/ ├── tee_core.c # 核心框架字符设备注册、上下文管理、ioctl 分发 ├── tee_shm.c # 通用共享内存分配、映射、缓存一致性 ├── tee_bus.c # TEE 总线TA 设备枚举与内核态驱动匹配 ├── tee_private.h # 核心层私有数据结构与宏定义 └── optee/ # OP-TEE 驱动主体Android 生态唯一主流实现 ├── core.c # 驱动入口、probe 初始化、SMC 调用封装 ├── call.c # 消息协议解析、会话/命令调用核心逻辑 ├── shm.c # OP-TEE 专属共享内存与 DMA 适配 ├── optee_smc.h # 所有 SMC 功能号、SMCCC 调用宏定义 └── optee_private.h # 驱动私有结构体、函数声明3. 双字符设备节点设计TEE 子系统对外暴露两类设备节点严格权限隔离对应不同使用场景设备节点访问主体权限等级核心用途/dev/tee0第三方应用 CA、普通用户态进程普通权限常规业务调用加密、签名、安全存储等/dev/teepriv0tee-supplicant 守护进程特权权限处理安全世界反向 RPC 请求TA 加载、文件系统代理、RPMB 代理二、核心数据结构5.10 内核通过一组层级化结构体管理全链路资源从属关系为tee_device → tee_context → tee_session共享内存 tee_shm 挂靠在上下文下。1. struct tee_device —— TEE 设备根实例每个物理 TEE 硬件对应两个实例普通设备 特权设备是驱动的根对象存储设备描述符、操作函数集、共享内存池根节点绑定字符设备 cdev、设备号、内核设备模型维护引用计数保证多进程并发访问安全2. struct tee_context —— 进程级上下文用户态进程每打开一次 /dev/tee0内核创建一个独立上下文与文件描述符生命周期绑定维护当前进程的所有会话链表、共享内存链表实现进程间资源隔离区分普通客户端上下文与 supplicant 特权上下文权限分级管控随 close() 系统调用自动销毁强制清理残留会话与内存3. struct tee_session —— TA 会话实例对应一次与指定 UUID TA 的连接由 TEEC_OpenSession 创建包含会话 ID、TA UUID、会话状态一个上下文可同时存在多个 TA 会话所有命令调用必须基于会话执行会话 ID 由安全世界分配内核仅做透传与映射4. struct tee_shm —— 共享内存块管理 REE 与 TEE 均可访问的非安全共享内存记录物理地址、内核虚拟地址、大小、所属上下文支持两种模式内核分配、用户态内存注册维护引用计数支持多会话共享同一块内存5. struct tee_param —— 调用参数统一描述 4 个操作参数完全对齐 GlobalPlatform 标准支持值类型value、内存引用类型memref两种格式内核层负责用户态参数合法性校验、虚拟地址到物理地址转换三、驱动初始化与设备注册流程OP-TEE 驱动通过设备树节点匹配硬件入口为 optee_probe() 函数定义于 drivers/tee/optee/core.c完整执行流程如下1. 硬件信息解析解析设备树 firmware/optee 节点获取安全中断号、共享内存预留区域等硬件参数调用 get_invoke_func() 根据 CPU 架构匹配 SMC 调用函数指针返回 optee_smccc_smc 作为统一调用入口2. 安全固件探测与能力协商通过一系列 SMC 快速调用与安全世界握手验证 TEE 有效性并约定交互规则发送 OPTEE_SMC_FUNCID_CALLS_UID 调用读取 TEE 标准 UID确认是 OP-TEE 兼容固件调用 OPTEE_SMC_CALL_GET_OS_UUID 与版本查询接口获取 OP-TEE OS 版本、支持的 API 能力集调用 OPTEE_SMC_GET_SHM_CONFIG与安全世界约定共享内存的物理地址范围、页大小与属性以上所有 SMC 调用均通过 optee_smccc_smc() 函数触发功能号定义于 optee_smc.h3. 核心资源初始化共享内存池创建基于协商好的内存范围调用 tee_shm_pool_alloc_res_mem() 创建全局共享内存池划分管理块与数据块中断注册注册安全世界通知中断通常为 FIQ绑定中断处理函数用于异步事件与 RPC 回调分发4. 设备注册上线调用 tee_device_alloc() 分配两个 tee_device 实例分别对应普通业务设备与特权 RPC 设备填充设备描述符与操作函数集绑定共享内存池调用 tee_device_register() 完成注册内核自动创建 /dev/tee0 与 /dev/teepriv0 字符设备节点枚举可用 TA 设备注册到 TEE 总线等待内核态客户端驱动匹配挂载四、面向 libteec 的核心业务工作流程用户态 libteec 库所有 GlobalPlatform 标准 API最终均通过 ioctl 系统调用下沉到内核 TEE 驱动执行。1. ioctl 命令与 libteec API 对应关系libteec 标准 API内核 ioctl 命令执行核心逻辑TEEC_InitializeContextopen(/dev/tee0)创建进程级上下文绑定文件描述符TEEC_OpenSessionTEE_IOC_OPEN_SESSION与指定 UUID 的 TA 建立会话TEEC_InvokeCommandTEE_IOC_INVOKE向 TA 发送业务命令并传递参数TEEC_AllocateSharedMemoryTEE_IOC_ALLOC_SHM内核分配共享内存并映射到用户态TEEC_RegisterSharedMemoryTEE_IOC_REGISTER_SHM将用户态已有内存注册为共享内存TEEC_CloseSessionTEE_IOC_CLOSE_SESSION销毁 TA 会话释放安全世界资源2. 核心调用TEEC_InvokeCommand 全链路这是最核心的业务交互流程完整路径分为 4 个阶段阶段1用户态参数准备CA 填充命令 ID、4 个操作参数value/memref调用 libteec 的 TEEC_InvokeCommandlibteec 将参数封装为 tee_ioctl_invoke_arg 结构体发起 TEE_IOC_INVOKE ioctl 系统调用阶段2内核参数处理与消息封装内核从文件私有数据取出 tee_context校验会话 ID 有效性遍历所有参数对内存引用类型做地址合法性校验普通用户内存临时映射到共享内存池已注册共享内存直接转换物理地址optee/call.c 中按照 OP-TEE 消息协议将命令 ID、参数、会话 ID 封装为 optee_msg_arg 结构体写入共享内存缓冲区对共享内存执行 flush_cache_range 缓存刷写确保数据写入物理内存安全世界可读取到最新内容阶段3SMC 触发与安全世界执行调用 optee_smccc_smc()将共享内存物理地址、消息大小等参数按 SMCCC 规范写入通用寄存器底层执行 SMC #0 指令CPU 提升异常级别至 EL3进入 ATF 固件ATF 校验 SMC 功能号路由到 OP-TEE SPD切换安全状态跳转到 OP-TEE OS 入口OP-TEE OS 解析共享内存消息找到对应会话与 TA执行指定命令将结果写回共享内存安全世界执行 SMC 返回指令回到 EL3ATF 恢复非安全上下文返回 Linux 内核阶段4结果回传内核返回后对共享内存执行 invalidate_cache_range 缓存失效确保读取到安全世界写入的最新数据解析 optee_msg_arg 中的返回状态与输出参数更新内核态参数结构将输出数据拷贝到用户态缓冲区释放临时映射的内存资源向用户态返回执行结果与错误码3. RPC 反向调用流程安全世界无法直接访问正常世界资源需通过 RPC 反向请求协助典型场景为动态 TA 加载、安全存储后端代理安全世界执行中需要 REE 服务构造 RPC 请求写入共享内存执行 SMC 返回Linux 内核从 SMC 返回值识别 RPC 请求解析命令类型内核可直接处理的请求如内存分配直接处理后再次 SMC 返回结果需要用户态处理的请求转发到 /dev/teepriv0唤醒 tee-supplicant 进程tee-supplicant 执行对应操作如读取 TA 镜像文件将结果写回共享内存通过 ioctl 通知内核内核再次触发 SMC 调用将结果传回安全世界安全世界恢复执行五、SMC 调用与 ATF 世界切换全链路5.10 内核中 SMC 调用采用「驱动封装 → 架构通用实现 → 硬件触发 → ATF 分发」的四层链路是 TrustZone 隔离的唯一合法入口。1. 内核 SMC 封装实现5.10 专属定义位置drivers/tee/optee/core.cstatic void optee_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7, struct arm_smccc_res *res) { arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res); }该函数是 OP-TEE 驱动的 SMC 统一出口直接封装内核通用 arm_smccc_smc() 接口所有 SMC 功能号宏定义于 drivers/tee/optee/optee_smc.h遵循 ARM SMCCC 1.1 规范底层最终由 arch/arm64/kernel/smccc-call.S 中的汇编代码执行 SMC #0 指令2. 硬件触发与异常级别提升Linux 内核运行在非安全 EL1 特权级执行 SMC #0 指令时CPU 硬件自动完成保存当前程序状态寄存器 PSTATE 到 SPSR_EL3保存返回地址到 ELR_EL3异常级别提升至 EL3CPU 进入安全监控模式跳转到 VBAR_EL3 指向的异常向量表即 ATF 预先注册的异常入口硬件强制保证非安全世界无法直接跳转到安全世界代码所有切换必须经过 EL3 的 ATF 校验分发这是 TrustZone 隔离的硬件根基。3. ATF 异常捕获与 SMC 分发ATF BL31 运行在 EL3runtime_exceptions.S 定义完整异常向量表SMC 异常进入 smc_handler64 处理函数1.保存非安全上下文将非安全世界的通用寄存器、系统寄存器保存到 ATF 内部上下文栈2.解析 SMC 功能号从 x0 读取 Function ID按 SMCCC 规范判断调用类型标准快速调用PSCI 电源管理等ATF 内置服务直接处理可信操作系统调用功能号属于 TEE 服务范围转发给对应 SPD3.OP-TEE SPD 路由Android 平台注册 opteed 作为 OP-TEE 分发器负责 TEE 请求转发与生命周期管理4. 安全世界进入与返回opteed_smc_handler 执行世界切换的核心步骤校验请求合法性检查功能号范围、参数边界修改 SCR_EL3.NS 位为 0安全态配置 SPSR_EL3 目标异常级别为 S-EL1从 ATF 上下文栈中恢复安全世界的寄存器状态设置 ELR_EL3 为 OP-TEE OS 的 SMC 处理入口执行 eret 退出 EL3进入 S-EL1 的 OP-TEE 内核安全世界处理完成后反向执行 SMC 指令触发返回ATF 恢复非安全上下文切换回非安全态最终回到 Linux 内核的 SMC 调用处继续执行。六、从 ATF / 安全世界读取数据的机制根据数据量与服务类型分为三类数据读取模式所有交互均符合 SMCCC 规范。1. 寄存器级短数据读取适用于状态码、版本号、小尺寸参数等少量数据直接通过通用寄存器传递调用时x0 存放功能号x1~x7 存放输入参数返回时x0 存放返回状态码x1~x3 存放返回数据典型场景OP-TEE 固件版本查询、会话创建返回码、ATF 原生服务状态限制单轮 SMC 最多返回 4 个寄存器数据仅适合控制信令2. 共享内存大数据读取业务级数据加密结果、证书、密钥密文等均通过非安全共享内存传输完整读取流程内核 TEE 驱动从共享内存池分配缓冲区获得物理地址将物理地址、长度通过寄存器参数传递给 ATF转发给 OP-TEE OSOP-TEE 校验内存地址属于合法非安全区域后将处理结果写入物理内存SMC 返回后内核执行缓存失效操作将数据拷贝到用户态缓冲区安全设计共享内存仅配置为非安全属性不会泄露安全内存数据OP-TEE 内部会做地址范围校验防止攻击者构造安全内存地址窃取数据。3. ATF 原生服务数据读取若数据由 ATF 固件直接提供无需经过 OP-TEE由 EL3 代码直接处理返回典型服务SOC 版本读取、芯片唯一 ID、安全 EFUSE 状态、电源管理状态调用方式内核直接发送对应功能号的 SMC 调用ATF 读取硬件寄存器后通过寄存器返回结果特点链路最短不经过安全世界仅用于芯片级底层信息查询4. 异步数据通知机制耗时较长的安全操作采用「SMC 发起请求 中断通知结果」的异步模式内核发送 SMC 提交异步任务后立即返回不阻塞等待安全世界处理完成后触发 FIQ 中断经 ATF 路由到非安全世界Linux TEE 驱动中断处理函数被触发从共享内存读取处理结果通过回调通知上层七、安全设计要点资源隔离每个进程拥有独立上下文会话、共享内存按上下文隔离进程间无法互相访问 TEE 资源参数强校验内核层对所有用户态传入的地址、长度、参数类型做严格校验防止非法参数触发内存漏洞单向不可逆切换SMC 切换由硬件与 ATF 双重管控非安全世界无法直接访问安全内存特权分级普通设备与特权设备分离普通应用无法访问 RPC 特权接口内存边界防护安全世界侧二次校验共享内存地址范围防止越权访问安全内存