rust-libteec
介绍
基于 GlobalPlatform TEE Client API 规范的 TEE (Trusted Execution Environment) 客户端库的 Rust 实现。该库提供与可信执行环境中的可信应用 (TA) 通信的接口,支持通过机密通信通道(TLS + VSOCK)进行安全数据传输。
主要特性
- 完整的 TEEC API 实现: 支持上下文管理、会话管理、命令调用等所有标准 API
- 机密通信: 基于 SM2 ECDH 密钥协商 + TLS 动态 PSK 的加密通信通道(SM4-GCM),CA 与 TA 之间的所有数据都通过此通道传输,每次连接使用独立密钥,具备前向安全性
- 纯 Rust 国密栈: 密码学原语基于
tee_cryptocrate(RustCrypto 生态纯 Rust 实现),在xtee-psk子 crate 中提供纯 Rust 封装的 SM2 ECDH / HKDF-SM3 / SM2 签名验签接口;TLS 加密通道则直接使用mbedtls-smx国密库 - 共享内存管理: 管理 MEMREF 类型参数的本地缓冲区(数据通过网络序列化传输)
- CA 认证: 自动验证客户端应用的签名和证书链,为 TA 提供 ACL 访问控制信息
- 多参数类型支持: VALUE、MEMREF(INPUT/OUTPUT/INOUT)、PARTIAL MEMREF 等
- 线程安全: 使用 DashMap 实现并发安全的缓存和上下文管理
机密通信流程
网络架构上,CA 和 TA 之间通过 VSOCK(虚拟机套接字)通信,数据经由 TLS(SM4-GCM)加密传输。
CA (Client) TA (Server)
| |
| ─── VSOCK 连接 ─────────────────────→ |
| |
| ─── ECDH 公钥交换 ─────────────────→ | SM2P256R1 密钥协商
| ←── ECDH 公钥交换 + 签名 ──────────── | 长期密钥签名
| |
| HKDF-SM3(shared_secret) | 派生 32 字节动态 PSK
| |
| ─── TLS PSK 握手 ─────────────────→ | ECDHE-PSK-SM4-GCM-SM3
| ←── TLS PSK 握手 ────────────────── |
| |
| ─── 加密通信(SM4-GCM)────────────→ | 机密数据传输
| ←── 加密通信(SM4-GCM)───────────── |
每次连接流程:
- VSOCK 连接 — CA 通过 VSOCK 与 TA(由 vsock-manager 代理)建立 TCP-like 连接
- ECDH 密钥协商 — 双方生成临时 SM2P256R1 密钥对,交换公钥,服务端使用长期密钥签名,客户端通过 TOFU 模式校验服务端身份
- 动态 PSK 派生 — 双方各自使用 HKDF-SM3 从共享秘密派生出相同的 32 字节 PSK(共享秘密离开作用域时自动清零)
- TLS PSK 握手 — 使用 ECDHE-PSK-SM4-GCM-SM3 密码套件完成 TLS 握手
- 加密通信 — 后续所有数据通过 SM4-GCM 加密传输
每次连接独立生成临时密钥对,即使某次 PSK 泄露也不影响历史通信(前向安全性)。
主要常量
所有密码学常量集中定义在 xtee-psk/src/constants.rs,保持单一数据源:
| 常量 | 值 | 说明 |
|---|---|---|
SM2_COORDINATE_LEN |
32 | SM2 坐标分量长度(字节) |
SM2_PUBLIC_KEY_LEN |
64 | SM2 公钥长度(x||y) |
SM2_POINT_LEN |
65 | 未压缩 EC 点长度(0x04||x||y) |
PSK_LEN |
32 | PSK 密钥长度 |
MAX_SIG_LEN |
256 | 签名最大长度 |
常量间存在派生关系:SM2_PUBLIC_KEY_LEN = SM2_COORDINATE_LEN * 2,PSK_LEN = SM2_COORDINATE_LEN。
软件架构
rust-libteec/
├── src/
│ ├── cc_client/ # 机密通信客户端模块
│ │ ├── client.rs # TLS + VSOCK 客户端实现
│ │ ├── tofu.rs # 服务端身份 TOFU 校验
│ │ └── vsock_define.rs # VSOCK 配置
│ ├── teec/ # TEEC API 实现模块
│ │ ├── c_api.rs # C API FFI 薄包装层(TEEC_* 函数入口)
│ │ ├── ca_auth.rs # CA 认证和缓存管理
│ │ ├── context.rs # TEE 上下文生命周期管理
│ │ ├── mod.rs # 模块声明与重导出
│ │ ├── operation.rs # 操作参数处理
│ │ ├── safe_ptr.rs # 安全指针操作封装
│ │ ├── session.rs # 会话管理(含机密通信通道)
│ │ └── shared_memory.rs# 共享内存管理
│ ├── error.rs # 错误类型定义
│ ├── lib.rs # 库入口
│ └── teec_trace.rs # 日志跟踪
├── xtee-psk/ # PSK 协商密码学原语(子 crate)
│ └── src/
│ ├── lib.rs # 模块声明 + 公共 API 重导出
│ ├── constants.rs # 协议常量(SM2 点长度、PSK 长度等)
│ ├── error.rs # PskError 错误类型 + PskResult 别名
│ ├── keygen.rs # 随机数生成器 + ECDH/DSA 密钥对生成
│ ├── ec_point.rs # SEC1 未压缩格式与 PublicKeyComponents 互转
│ ├── ecdh.rs # ECDH 共享秘密 + HKDF-SM3 PSK 派生
│ ├── sign.rs # SM2 DSA 签名/验签(防 MITM)
│ ├── protocol.rs # 协议帧构建/解析(EcdhResponse)
│ ├── negotiate.rs # PskTransport trait + 协商主流程 + ServerPskContext
│ └── virga_transport.rs # virga VSOCK 传输层 PskTransport 实现
├── teec-api-types/ # TEE API 类型定义(子 crate)
├── teec-protocol/ # 通信协议定义(子 crate)
├── examples/ # Rust 示例程序
├── c-examples/ # C 语言示例程序
└── tests/ # 集成测试
xtee-psk crate
密码学原语库,基于 tee_crypto crate 封装国密接口,通过 PskTransport trait
将网络 I/O(send/recv)与密码学协商逻辑解耦,供客户端和服务端各自实现传输层并调用
统一的 server_ecdh_negotiate / client_ecdh_negotiate 协商函数。
各功能分散在独立子模块中,lib.rs 仅负责模块声明和公共 API 重导出:
| 模块 | 职责 |
|---|---|
constants |
协议常量(点长度、签名字段大小、PSK 长度等) |
error |
PskError 错误类型和 PskResult 别名 |
keygen |
随机数生成器创建、ECDH/DSA 密钥对生成 |
ec_point |
SEC1 未压缩格式与 PublicKeyComponents 互转 |
ecdh |
ECDH 共享秘密计算 + HKDF-SM3 PSK 派生 |
sign |
SM2 DSA 签名/验签(防 MITM) |
protocol |
协议帧构建/解析(EcdhResponse) |
negotiate |
PskTransport trait + 协商主流程 + ServerPskContext |
virga_transport |
virga VSOCK 传输层的 PskTransport 实现 |
核心功能列表:
- 命名常量:
SM2_COORDINATE_LEN、SM2_PUBLIC_KEY_LEN、SM2_POINT_LEN、PSK_LEN、MAX_SIG_LEN - SM2 密钥对生成:
generate_ecdh_keypair(ECDH 密钥交换)、generate_dsa_keypair(数字签名) - ECDH 共享秘密:
ecdh_compute_shared(返回Zeroizing,离开作用域自动清零) - HKDF-SM3 密钥派生:
derive_psk(从 ECDH 共享秘密派生 32 字节 PSK) - SM2 签名/验签:
sign_ecdh_exchange/verify_ecdh_signature(服务端身份认证) - 协议消息:
build_ecdh_response/parse_ecdh_response(ECDH 协商消息序列化) - 服务端上下文:
ServerPskContext(封装长期 DSA 密钥及协商入口negotiate,跨连接复用) - 随机数生成器:
CryptoRng(StdRng aliased)
客户端 tofu.rs
基于 TOFU(Trust On First Use,首次使用时信任)模型的服务端身份校验: 首次连接信任并缓存服务端长期公钥,后续连接校验一致性。若公钥变化则拒绝连接, 可防御持续性 MITM 攻击(首次连接发生在受控环境中,后续即使网络环境变化, 服务端身份也不会被替换)。
verify_server_identity— TOFU 身份校验入口
安装教程
系统要求
- Rust 1.85 或更高版本(edition 2024)
- Linux 操作系统(支持 VSOCK)
- GCC(用于编译 C 示例)
- clang
- CMake 3.16 或更高版本(Android 交叉编译建议 3.22+)
CMake 版本说明:rust-mbedtls 依赖的 mbedtls-sys 通过 CMake 构建 MbedTLS 库。低版本 CMake 会导致编译失败:
- CMake < 3.13:Rust
cmakecrate 的-B构建目录参数不可用- CMake < 3.16:Android 交叉编译时
CMAKE_TOOLCHAIN_FILE与 NDK 工具链文件配合不完善- CMake < 3.22:NDK r25+ 的
android.toolchain.cmake可能无法正常工作可通过
cmake --version检查当前版本,如需升级请参考 CMake 官方下载页。
Linux 构建
# 构建发布版本
# 或使用 Makefile
Android 16 交叉编译
使用 NDK r29 和 cargo-ndk 交叉编译 aarch64 目标:
-
下载 Android NDK r29:
# 从 Android 官方下载或通过 Android Studio 的 SDK Manager 安装,NDK 位于
~/Android/Sdk/ndk/29.x.x/。 -
安装 cargo-ndk:
-
设置 NDK 环境变量:
-
编译:
--platform 35:对应 Android 16 (API level 35)--target arm64-v8a:aarch64 目标架构- 编译产物位于
target/aarch64-linux-android/release/libcc_teec.so
-
AOSP 预编译部署:
将
libcc_teec.so复制到 AOSP 源码树的预编译目录下,并编写对应的Android.bp:cc_prebuilt_library_shared { name: "libcc_teec", srcs: ["libcc_teec.so"], compile_multilib: "64", shared_libs: ["libc", "libdl"], vendor: true, }然后在产品的
device.mk中添加:PRODUCT_PACKAGES +=编译 AOSP 后
libcc_teec.so安装到设备/vendor/lib64/。 -
编译 C 示例(Android):
编译
libcc_teec.so后,可以直接编译并签名 C 示例:或单独操作:
# 仅编译 C 示例(不签名) # 编译 + 签名签名后的 C 示例二进制部署到 AOSP 时,编写对应的
Android.bp:cc_prebuilt_binary { name: "cc-teec", srcs: ["cc-teec"], vendor: true, strip: { none: true, }, shared_libs: ["libcc_teec", "libc", "libdl"], }strip: { none: true }用于保留.ta_signatureELF 段,AOSP 默认 strip 会移除该段。然后在产品的
device.mk中添加:PRODUCT_PACKAGES +=
安装到系统(Linux,可选)
使用说明
Rust 项目中使用
在 Cargo.toml 中添加依赖:
[]
= "0.5"
基本使用示例请参考 examples/cc-teec.rs,对应的 TA 示例位于 xtee-rust-sdk-fuxi/examples/param(UUID: 9b28392f-39d2-497d-91af-b6600e3d6a3e)。
运行示例
# 运行 Rust 示例
# 编译并运行 C 示例
运行测试
# 运行单元测试
# 运行覆盖率测试
特性标志
ca-sign-verify: 启用 CA 认证功能(默认启用)debug_level_0~debug_level_4: 控制日志详细程度(默认 level_2)
参与贡献
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
许可证
本项目采用 Apache License 2.0 许可证 - 详见 LICENSE 文件