OP-TEE (开放式便携式可信执行环境)

OP-TEE 驱动程序处理基于 OP-TEE [1] 的 TEE。目前仅支持基于 ARM TrustZone 的 OP-TEE 解决方案。

与 OP-TEE 通信的最低层基于 ARM SMC 调用约定 (SMCCC) [2],这是驱动程序内部使用的 OP-TEE SMC 接口 [3] 的基础。在此之上是 OP-TEE 消息协议 [4]。

OP-TEE SMC 接口提供了 SMCCC 所需的基本功能以及一些 OP-TEE 特有的附加功能。最值得关注的功能是:

  • OPTEE_SMC_FUNCID_CALLS_UID (SMCCC 的一部分) 返回版本信息,该信息随后由 TEE_IOC_VERSION 返回。

  • OPTEE_SMC_CALL_GET_OS_UUID 返回特定的 OP-TEE 实现,例如,用于区分 TrustZone OP-TEE 和在单独安全协处理器上运行的 OP-TEE。

  • OPTEE_SMC_CALL_WITH_ARG 驱动 OP-TEE 消息协议。

  • OPTEE_SMC_GET_SHM_CONFIG 允许驱动程序和 OP-TEE 协商 Linux 和 OP-TEE 之间共享内存所使用的内存范围。

GlobalPlatform TEE 客户端 API [5] 是在通用 TEE API 之上实现的。

OP-TEE 架构中不同组件之间关系的图示

   User space                  Kernel                   Secure world
   ~~~~~~~~~~                  ~~~~~~                   ~~~~~~~~~~~~
+--------+                                             +-------------+
| Client |                                             | Trusted     |
+--------+                                             | Application |
   /\                                                  +-------------+
   || +----------+                                           /\
   || |tee-      |                                           ||
   || |supplicant|                                           \/
   || +----------+                                     +-------------+
   \/      /\                                          | TEE Internal|
+-------+  ||                                          | API         |
+ TEE   |  ||            +--------+--------+           +-------------+
| Client|  ||            | TEE    | OP-TEE |           | OP-TEE      |
| API   |  \/            | subsys | driver |           | Trusted OS  |
+-------+----------------+----+-------+----+-----------+-------------+
|      Generic TEE API        |       |     OP-TEE MSG               |
|      IOCTL (TEE_IOC_*)      |       |     SMCCC (OPTEE_SMC_CALL_*) |
+-----------------------------+       +------------------------------+

RPC (远程过程调用) 是从安全世界向内核驱动程序或 tee-supplicant 发出的请求。RPC 通过 OPTEE_SMC_CALL_WITH_ARG 返回的 SMCCC 返回值中的一个特殊范围来标识。用于内核的 RPC 消息由内核驱动程序处理。其他 RPC 消息将转发到 tee-supplicant,驱动程序不再进一步介入,除了切换共享内存缓冲区表示。

OP-TEE 设备枚举

OP-TEE 提供了一个伪可信应用程序:drivers/tee/optee/device.c,以支持设备枚举。换句话说,OP-TEE 驱动程序调用此应用程序来检索可在 TEE 总线上注册为设备的受信任应用程序列表。

OP-TEE 通知

安全世界可以使用两种通知方式来让普通世界知晓某些事件。

  1. 使用 OPTEE_RPC_NOTIFICATION_SEND 参数通过 OPTEE_RPC_CMD_NOTIFICATION 传递同步通知。

  2. 异步通知通过非安全边沿触发中断和非安全中断处理程序中的快速调用相结合的方式传递。

同步通知受限于依赖 RPC 进行传递,这仅在通过 OPTEE_SMC_CALL_WITH_ARG 进行可让出调用进入安全世界时才可用。这排除了此类通知来自安全世界中断处理程序。

异步通知通过非安全边沿触发中断传递到 OP-TEE 驱动程序中注册的中断处理程序。实际的通知值通过快速调用 OPTEE_SMC_GET_ASYNC_NOTIF_VALUE 获取。请注意,一个中断可以表示多个通知。

通知值 OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF 具有特殊含义。当接收到此值时,表示普通世界应该进行一个可让出调用 OPTEE_MSG_CMD_DO_BOTTOM_HALF。此调用由协助中断处理程序的线程执行。这是安全世界中 OP-TEE OS 实现设备驱动程序“上半部分和下半部分”风格的构建块。

OPTEE_INSECURE_LOAD_IMAGE Kconfig 选项

OPTEE_INSECURE_LOAD_IMAGE Kconfig 选项支持在内核启动后从内核加载 BL32 OP-TEE 镜像,而不是在内核启动前从固件加载。这还需要在 Trusted Firmware for Arm 中启用相应的选项。Trusted Firmware for Arm 文档 [6] 解释了启用此功能相关的安全威胁以及在固件和平台层面的缓解措施。

使用此选项时,还有一些针对内核的额外攻击向量/缓解措施需要解决。

  1. 启动链安全。

    • 攻击向量:替换 rootfs 中的 OP-TEE OS 镜像以获得系统控制权。

    • 缓解:必须有启动链安全机制来验证内核和 rootfs,否则攻击者可以通过修改 rootfs 中的 OP-TEE 二进制文件来修改已加载的 OP-TEE。

  2. 备用启动模式。

    • 攻击向量:使用备用启动模式(即恢复模式)时,OP-TEE 驱动程序未加载,导致 SMC 漏洞开放。

    • 缓解:如果存在启动设备的其他方法(例如恢复模式),应确保在该模式下应用相同的缓解措施。

  3. SMC 调用之前的攻击。

    • 攻击向量:在发出加载 OP-TEE 的 SMC 调用之前执行的代码可能被利用,从而加载备用 OS 镜像。

    • 缓解:OP-TEE 驱动程序必须在任何潜在攻击向量开放之前加载。这应包括挂载任何可修改的文件系统、开放网络端口或与外部设备(例如 USB)通信。

  4. 阻塞加载 OP-TEE 的 SMC 调用。

    • 攻击向量:阻止驱动程序探测,从而在需要时无法执行加载 OP-TEE 的 SMC 调用,使其可在稍后执行并加载修改后的 OS。

    • 缓解:建议将 OP-TEE 驱动程序构建为内置驱动程序而不是模块,以防止可能导致模块无法加载的漏洞利用。

参考资料

[1] https://github.com/OP-TEE/optee_os

[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html

[3] drivers/tee/optee/optee_smc.h

[4] drivers/tee/optee/optee_msg.h

[5] http://www.globalplatform.org/specificationsdevice.asp 查找

“TEE 客户端 API 规范 v1.0” 并点击下载。

[6] https://trustedfirmware-a.readthedocs.io/en/latest/threat_model/threat_model.html