rust-libteec 0.6.0

Rust implementation of TEE Client API for secure communication with Trusted Applications.
Documentation

rust-libteec

Crates.io License

介绍

基于 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_crypto crate(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)─────────────  |

每次连接流程:

  1. VSOCK 连接 — CA 通过 VSOCK 与 TA(由 vsock-manager 代理)建立 TCP-like 连接
  2. ECDH 密钥协商 — 双方生成临时 SM2P256R1 密钥对,交换公钥,服务端使用长期密钥签名,客户端通过 TOFU 模式校验服务端身份
  3. 动态 PSK 派生 — 双方各自使用 HKDF-SM3 从共享秘密派生出相同的 32 字节 PSK(共享秘密离开作用域时自动清零)
  4. TLS PSK 握手 — 使用 ECDHE-PSK-SM4-GCM-SM3 密码套件完成 TLS 握手
  5. 加密通信 — 后续所有数据通过 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 * 2PSK_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_LENSM2_PUBLIC_KEY_LENSM2_POINT_LENPSK_LENMAX_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 cmake crate 的 -B 构建目录参数不可用
  • CMake < 3.16:Android 交叉编译时 CMAKE_TOOLCHAIN_FILE 与 NDK 工具链文件配合不完善
  • CMake < 3.22:NDK r25+ 的 android.toolchain.cmake 可能无法正常工作

可通过 cmake --version 检查当前版本,如需升级请参考 CMake 官方下载页

Linux 构建

# 构建发布版本
cargo build --release

# 或使用 Makefile
make build

Android 16 交叉编译

使用 NDK r29 和 cargo-ndk 交叉编译 aarch64 目标:

  1. 下载 Android NDK r29

    # 从 Android 官方下载
    wget https://dl.google.com/android/repository/android-ndk-r29-linux.zip
    unzip android-ndk-r29-linux.zip
    

    或通过 Android Studio 的 SDK Manager 安装,NDK 位于 ~/Android/Sdk/ndk/29.x.x/

  2. 安装 cargo-ndk

    cargo install cargo-ndk
    
  3. 设置 NDK 环境变量

    export ANDROID_NDK_HOME=/path/to/android-ndk-r29
    
  4. 编译

    cargo ndk --platform 35 build --release --target arm64-v8a
    
    • --platform 35:对应 Android 16 (API level 35)
    • --target arm64-v8a:aarch64 目标架构
    • 编译产物位于 target/aarch64-linux-android/release/libcc_teec.so
  5. 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 += libcc_teec
    

    编译 AOSP 后 libcc_teec.so 安装到设备 /vendor/lib64/

  6. 编译 C 示例(Android)

    编译 libcc_teec.so 后,可以直接编译并签名 C 示例:

    make android-c-examples
    

    或单独操作:

    # 仅编译 C 示例(不签名)
    make -C c-examples android
    
    # 编译 + 签名
    make -C c-examples android-sign
    

    签名后的 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_signature ELF 段,AOSP 默认 strip 会移除该段。

    然后在产品的 device.mk 中添加:

    PRODUCT_PACKAGES += cc-teec
    

安装到系统(Linux,可选)

sudo make install

使用说明

Rust 项目中使用

Cargo.toml 中添加依赖:

[dependencies]
rust-libteec = "0.5"

基本使用示例请参考 examples/cc-teec.rs,对应的 TA 示例位于 xtee-rust-sdk-fuxi/examples/param(UUID: 9b28392f-39d2-497d-91af-b6600e3d6a3e)。

运行示例

# 运行 Rust 示例
cargo run --release --example cc-teec

# 编译并运行 C 示例
make test-c-examples

运行测试

# 运行单元测试
make test

# 运行覆盖率测试
make coverage

特性标志

  • ca-sign-verify: 启用 CA 认证功能(默认启用)
  • debug_level_0 ~ debug_level_4: 控制日志详细程度(默认 level_2)

参与贡献

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

许可证

本项目采用 Apache License 2.0 许可证 - 详见 LICENSE 文件

联系方式