NVIDIA Jetson OP-TEE 官方源码:从目录结构到 JetPack / Yocto 构建与运行的完整指南

2025博客之星年度评选已开启 10w+人浏览 957人参与


📺 B站视频讲解(Bilibili)https://www.bilibili.com/video/BV1k1C9BYEAB/

📘 《Yocto项目实战教程》京东购买链接Yocto项目实战教程


读懂 NVIDIA Jetson OP-TEE 官方源码:从目录结构到 JetPack / Yocto 构建与运行的完整指南

本文以 NVIDIA 官方 nvidia-jetson-optee-source/optee 源码为核心,从目录结构 → 构建流程 → 产物形态 → 系统集成 → 运行与验证五个维度,系统讲清楚 Jetson 平台上 OP-TEE 的完整工程链路。内容同时覆盖 JetPack(L4T/Ubuntu)Yocto(meta-tegra) 两种主流体系,帮助你在两套系统中都能正确编译、部署并运行 OP-TEE 相关组件。


一、整体架构速览:Jetson 上的 OP-TEE 是如何工作的

在 Jetson 平台,OP-TEE 并不是一个“单独的程序”,而是一整套**跨启动链、跨世界(Secure/Normal)**的工程体系,主要由以下部分组成:

  • OP-TEE OS(Secure World):运行在 TrustZone Secure World 的可信操作系统
  • TEE Client(Normal World):Linux 用户态与 Secure World 通信的标准接口库
  • TEE Supplicant(Normal World 守护进程):辅助 OP-TEE OS 完成存储、文件、RPMB 等操作
  • TA / PTA(Secure World 应用):在 Secure World 中执行的可信应用
  • CA(Normal World 客户端):Linux 用户态程序,通过 TEE Client API 调用 TA/PTA

在 Jetson 启动链中:

  1. BootROM / MB1 / MB2 完成早期启动
  2. OP-TEE OS(tos-optee.img)* 被加载到 Secure World
  3. Linux Kernel 启动(Normal World)
  4. Linux 用户空间启动 tee-supplicant
  5. 用户程序(CA)通过 /dev/tee* 与 OP-TEE 通信

二、源码目录总览(以 nvidia-jetson-optee-source/optee 为准)

你当前看到的目录结构如下:

optee/
├── atf_and_optee_README.txt
├── optee_client/
├── optee_os/
├── optee_test/
├── samples/
└── tegra234-optee.dts

这是 Jetson 官方 OP-TEE 源码的完整工程形态,下面逐一拆解。


三、optee_os:Secure World 的核心(最关键)

1. 目录定位

optee_os/
├── core/
├── ldelf/
├── lib/
├── ta/
├── mk/
├── scripts/
├── keys/
└── prebuilt/

optee_os 是运行在 Secure World 的 OP-TEE 操作系统本体,最终会被编译成:

  • tos-optee_t234.img(或同类名称)

并在启动时由 Bootloader 加载。


2. 关键子目录说明

(1)core/
  • OP-TEE 内核核心代码
  • 包含线程调度、内存管理、TEE syscall 实现
  • 与 Linux Kernel 类似的“内核态”部分
(2)ldelf/
  • TA Loader(ELF 装载器)
  • Secure World 中负责加载 .ta 文件
  • xtest / hwkey-agent 中大量日志都与 ldelf 有关
(3)ta/
  • Secure World 中 TA / PTA 的公共支持代码
  • PTA(Pseudo TA)通常以内建形式存在于 OP-TEE OS
(4)mk/
  • 构建系统核心(Makefile 片段)
  • ta_dev_kit.mk 就在这里
  • 所有 TA 的交叉编译都依赖这一套工具链定义
(5)keys/
  • 测试密钥 / 示例密钥
  • 量产中通常不会直接使用这里的 key

3. 构建 optee_os(生成 Secure OS 镜像)

JetPack(L4T)方式

在 NVIDIA 提供的 Driver Package 中:

cd Linux_for_Tegra/source/optee
make PLATFORM=tegra234

生成的核心产物包括:

  • out/arm-plat-tegra/core/tee.bin
  • 经过签名/封装后成为 tos-optee_t234.img

该镜像在刷机阶段写入 A_secure-os 分区。


Yocto(meta-tegra)方式

在 Yocto 中:

  • recipe:optee-os_%.bb
  • include:optee-l4t.inc

Yocto 会:

  1. 拉取 nvidia-jetson-optee-source
  2. 进入 optee_os/
  3. 使用交叉工具链构建
  4. 生成 tos-optee*.img
  5. 集成进最终刷机镜像

关键点:Yocto 构建的 OP-TEE OS 与 JetPack 使用的是同一套源码,只是构建系统不同。


四、optee_client:Normal World 的通信桥梁

1. 目录定位

optee_client/
├── libteec/
├── tee-supplicant/
├── Makefile
└── README.md

optee_client 提供了 GlobalPlatform 标准定义的 TEE Client API。


2. 核心组件

libteec
  • libteec.so

  • CA(Normal World 程序)必须链接的库

  • 提供:

    • TEEC_InitializeContext
    • TEEC_OpenSession
    • TEEC_InvokeCommand
tee-supplicant
  • Linux 用户态守护进程

  • OP-TEE OS 在 Secure World 中无法直接访问 Linux 文件系统

  • 通过 RPC 请求,由 tee-supplicant 代为完成:

    • 文件访问
    • RPMB
    • 安全存储

3. 构建与部署

JetPack
  • NVIDIA 已预编译
  • 默认安装在:
/usr/lib/libteec.so
/usr/sbin/tee-supplicant
Yocto
  • recipe:optee-client_%.bb
  • 构建后自动进入 rootfs

五、optee_test:验证 OP-TEE 是否正常工作的标准套件

1. 目录结构

optee_test/
├── host/
├── ta/
└── README.md

2. xtest 的意义

  • xtest 是 OP-TEE 官方的回归测试程序

  • 能系统性验证:

    • Secure World 是否在跑
    • TA 是否能加载
    • 基本加密算法是否可用

你之前成功运行 xtest,已经证明:

OP-TEE OS + optee_client + tee-supplicant 整条链路是通的


六、samples:官方给你的“工程级示例”

1. 目录结构

samples/
├── hwkey-agent/
├── luks-srv/
├── ftpm-helper/
├── cpubl-payload-dec/
└── pkcs11-sample/

这些不是玩具示例,而是真实业务模型的参考实现


2. hwkey-agent(与你当前工作最相关)

samples/hwkey-agent/
├── ta/      # Secure World TA
├── host/    # Normal World CA
└── README
  • TA:运行在 Secure World
  • CA:Linux 用户态程序(你已经在 Yocto 中构建并运行)

nvhwkey-app 就来自这里。


3. 构建方式(以 Yocto 为例)

Yocto 中:

  • recipe:optee-nvsamples
  • 构建产物路径示例:
build/ca/hwkey-agent/nvhwkey-app
build/ta/hwkey-agent/*.ta

这些文件在 rootfs 中的放置规则:

文件位置
CA/usr/bin/
TA/lib/optee_armtz/

七、关键文件最终都放到哪里?(非常重要)

类型文件位置
Secure OStos-optee_t234.imgA_secure-os 分区
EKBeks_t234.imgA_eks 分区
TA*.ta/lib/optee_armtz/
CA可执行文件/usr/bin/
libteeclibteec.so/usr/lib/
supplicanttee-supplicant/usr/sbin/

八、JetPack 与 Yocto 的差异总结

维度JetPackYocto
构建方式NVIDIA 预编译 + 手动bitbake 自动
灵活性
适合阶段验证 / Demo产品化
OP-TEE 修改麻烦非常自然

你现在走 Yocto 路线,是做安全产品的正确选择。


九、如何基于这套源码继续你的 HelloWorld 安全工程

在你已经完成的阶段基础上:

  1. gen_ekb.py → 把 hello_seed 放进 EKB
  2. OP-TEE OS 启动 → Secure World 解析 EKB
  3. PTA → 从 EKB 读取 seed
  4. CA → 请求“加密/解密服务”,但永远拿不到 key

你现在理解的这套 目录结构 + 构建方式,正是你后续每一步安全设计的“地图”。


九、EKB(Encrypted Key Blob):Jetson OP-TEE 的密钥构建与运行时使用核心

在前面的章节中,我们已经完整走通了 OP-TEE 的源码结构、构建方式以及在 JetPack / Yocto 中的运行形态。但如果要真正把 OP-TEE 用于业务级安全,就绕不开一个核心机制:EKB(Encrypted Key Blob)

这一节将把 EKB 的构建逻辑、生成流程、启动时解析路径以及运行时使用方式系统性地补齐,使整篇文章形成一个从“源码 → 构建 → 启动 → 业务”的完整闭环。


在这里插入图片描述

9.1 为什么需要 EKB?

在 Jetson 的安全设计中,有一个非常明确的目标:

业务密钥不能明文存在于 Linux 文件系统中,也不能在运行时被 Linux 直接读取。

但与此同时:

  • OP-TEE 需要在启动后稳定地拿到这些密钥
  • 密钥需要支持 OTA 更新
  • 不同安全业务(磁盘加密、UEFI、应用加密)需要不同 key

EKB 正是为了解决这一组矛盾而设计的:

  • EKB 是一个加密后的二进制密钥容器
  • 存放在 EKS 分区
  • 只能被 Secure World(OP-TEE) 解密和解析
  • Linux 永远只能看到密文

9.2 EKB 在启动链中的位置

在 Jetson 平台,EKB 的使用路径是固定的:

Flash / OTA
   ↓
EKS 分区(eks_t234.img)
   ↓
MB2
   ↓
OP-TEE OS 启动
   ↓
jetson-user-key PTA 解析 EKB
   ↓
密钥进入 Secure World 内存

几个关键点:

  • EKB 不在 rootfs 中
  • EKB 不在 Linux 视角可读的分区中
  • 只有 OP-TEE 在启动早期才能拿到它

9.3 EKB 的核心构建流程(工程视角)

9.3.1 构建输入材料

一个最小但完整的 EKB,至少包含:

输入作用
OEM_K1Root of Trust,烧录到 Fuse
FV随机向量,用于派生 EKB_RK
用户密钥(如 hello_seed)业务真正使用的 seed

这些输入不会直接以明文形式出现在设备上。


9.3.2 gen_ekb.py 的角色

nvidia-jetson-optee-source 中,EKB 是通过官方工具生成的:

optee/samples/hwkey-agent/host/tool/gen_ekb/gen_ekb.py

这个脚本本质上做了 5 件事:

  1. 使用 OEM_K1 + FV 派生 EKB_RK

  2. 基于 NIST-SP-800-108 KDF 派生:

    • EKB_EK(加密)
    • EKB_AK(认证)
  3. 将用户密钥(如 hello_seed)按 tag 编码进 EKB 内容

  4. 使用 EKB_EK 对内容加密

  5. 使用 EKB_AK 生成 MAC

最终输出:

eks_t234.img

9.4 一个最小业务 EKB 的示例(HelloWorld 场景)

以最简单的业务为例:

我希望 Secure World 中持有一个 hello_seed,用它派生 AES key,对 Linux 文件进行加解密。

构建步骤概览:
  1. 生成 hello_seed(32 字节随机数)
  2. 修改 gen_ekb.py,增加 -in_hello_seed
  3. 将 hello_seed 作为一个新的 key_tag 写入 EKB
  4. 生成 eks_t234.img
  5. 刷写到 A_eks 分区

在这个过程中:

  • hello_seed 只在 生成阶段短暂存在
  • 上板后设备中不再存在明文 seed

9.5 OP-TEE 启动时如何解析 EKB

在 OP-TEE OS 启动过程中:

  1. Secure Engine 从 Fuse 中加载 OEM_K1
  2. OP-TEE 计算 EKB_RK
  3. 验证 EKB 的 MAC
  4. 解密 EKB 内容
  5. 将 key_tag → key 的映射保存到 PTA 内部结构

这一逻辑主要位于:

optee_os/core/pta/jetson-user-key/

这也是为什么:

  • Linux 永远无法直接访问这些 key
  • CA 只能“请求服务”,而不能“请求密钥”

9.6 EKB 与 PTA / CA 的职责边界

组件能看到什么
Linux CA看不到任何明文 key
tee-supplicant看不到 key
PTA(Secure World)能看到并使用 key
OP-TEE Core负责生命周期与隔离

一个典型业务调用是:

Linux CA → PTA:请帮我加密这个 buffer
PTA:使用 EKB 中的 hello_seed 派生 key
PTA:完成加密,返回密文

Linux 全程:

  • 不知道 key
  • 不知道派生方式
  • 只能看到结果

9.7 为什么 EKB 是“一次构建,多次使用”的机制

EKB 有几个重要特性:

  • 不能在运行时修改
  • 只能通过 OTA / 刷机更新
  • 启动后,key 常驻 Secure World 内存

这意味着:

  • 构建 EKB 是安全工程的“源头设计”
  • 后续所有安全业务,都是围绕这个源头展开

十、结语:从源码理解,到安全能力落地

通过补齐 EKB 这一章,可以看到:

  • OP-TEE 并不是一个“黑盒安全模块”
  • EKB 不是魔法,而是可推导、可验证、可工程化的机制

当你理解了:

  • OP-TEE 源码结构
  • JetPack / Yocto 构建路径
  • EKB 的构建与解析

你实际上已经具备了:

在 Jetson 平台上设计、实现并交付安全业务的能力

无论是文件保护、模型加密,还是 OTA / 设备身份,这套链路都已经在你手中。


📺 B站视频讲解(Bilibili)https://www.bilibili.com/video/BV1k1C9BYEAB/

📘 《Yocto项目实战教程》京东购买链接Yocto项目实战教程


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值