RISC-V机密计算实战:从Smepmp硬件隔离到Keystone远程证明的完整流程
一、机密计算与 Keystone 架构
1.1 威胁模型
传统虚拟化场景下,Hypervisor 被视为可信方;机密计算引入更严格假设——Hypervisor 与 OS 均不可信。攻击者即使控制宿主机,也无法观察或篡改飞地内明文数据与执行流。达成此目标需三方面支撑:内存隔离(飞地区域对宿主不可见)、执行隔离(飞地上下文切换需硬件配合)、可验证性(远程方可校验飞地身份与完整性)。
1.2 Keystone 三层组件
Keystone 是 RISC-V 上较成熟的开源机密计算框架,由三层组件构成:
- Security Monitor(SM):运行于 M-mode,承担飞地创建、上下文切换、PMP 切换、远程证明等职责,是可信计算基(TCB)的核心。
- Runtime:运行于 U/S-mode 的宿主侧库,负责 eapp(飞地程序)加载、参数编组与系统调用代理。
- Eapp:飞地内运行的目标程序,运行于独立的 PMP 区域中。
三者关系:Runtime 装载并启动 Eapp,SM 在背后配置 PMP、切换寄存器上下文、生成证明报告。
1.3 与其他架构对比
| 维度 | RISC-V(Keystone) | Intel SGX | Arm CCA |
|---|---|---|---|
| 隔离底座 | Smepmp + PMP | EPC + MEE | RMM + Realm |
| TCB 体积 | 中(SM 全开源) | 小(微码闭源) | 中(RMM 开源) |
| 远程证明 | 自定义 report + 厂商签名 | EPID/DCAP | 厂商证书链 |
| 硬件依赖 | Smepmp + M-mode | SGX 指令集扩展 | RME 扩展 |
| 开源程度 | 完全开源 | 部分 | 部分 |
RISC-V 方案的优势在于 TCB 完全可审计与定制——SM 与 Runtime 均为开源代码,便于嵌入式与定制化场景下的安全评估。
二、飞地生命周期
2.1 创建与加载
飞地创建由 Security Monitor 完成,核心动作是为 eapp 分配独占物理页并配置 PMP 条目。eapp 镜像需经 SM 验签后方可装载,加载完成后 SM 切换至飞地入口点。
2.2 进入与退出(ecall / eret)
飞地上下文切换的关键是 SM 借助 Smepmp 的 mseccfg.MMWP 与 PMP 条目 MODE 字段在飞地模式与宿主模式间切换:
- 进入飞地(ecall):SM 保存宿主上下文,将目标飞地的 PMP 条目切换为
Locked-M-only模式,使 M-mode 才能配置、U/S-mode 无法访问,最后执行mret进入飞地入口。 - 退出飞地(eret):飞地通过
ecall触发陷入;SM 恢复宿主 PMP 配置,从保留栈恢复寄存器,跳转回宿主调用点。
切换的核心约束:飞地区域的 PMP 条目必须配置为 Locked,否则宿主可在切换间隙修改 PMP 配置破坏隔离。
2.3 销毁
销毁流程反向:SM 回收物理页、清除 PMP 条目、释放元数据。销毁后的飞地 ID 不可重用,避免重放攻击。
2.4 飞地内存加密(MEE)
Keystone 依赖外部内存加密引擎(MEE)对飞地物理页加密,使 DIMM 抓取与冷启动攻击均无法获取明文。RISC-V 上 MEE 由 SoC 厂商实现,Keystone 通过 SBI 调用与 MEE 交互;QEMU 默认不启用 MEE,实战中需通过 -bios 指定支持 MEE 的固件。
三、远程证明
3.1 报告结构
远程证明(Remote Attestation)使远程验证方确认飞地身份、完整性、运行环境。Keystone 的报告由 SM 签发,典型字段如下:
struct keystone_report {
uint8_t hash[64]; /* eapp 二进制度量 */
uint8_t public_key[32]; /* 飞地公钥 */
uint64_t nonce; /* 防重放随机数 */
uint8_t signature[64]; /* SM 私钥签名(Ed25519) */
};
3.2 验证流程
验证方使用 SM 公钥校验签名,并核对度量值与公钥是否符合目标飞地规格:
int verify_report(const struct keystone_report *rep,
const uint8_t *expected_hash,
const uint8_t *sm_public_key,
uint64_t expected_nonce) {
if (rep->nonce != expected_nonce) return -1; /* 防重放 */
if (memcmp(rep->hash, expected_hash, 64) != 0) /* 度量校验 */
return -2;
return ed25519_verify(sm_public_key, rep, /* 签名校验 */
sizeof(*rep) - 64, rep->signature);
}
3.3 工程要点
- nonce 由验证方提供,每次会话唯一,避免旧报告重放。
- SM 公钥需预先烧录至 OTP 或硬件证书,与启动信任根打通——这也是远程证明与上一篇文章"安全启动"主题的衔接点。
- 度量值在 eapp 编译期固定,CI 流水线需将度量值登记到验证方数据库。
四、QEMU 实战路径
4.1 构建工具链
Keystone 在 QEMU 上的 smoke test 可通过以下步骤复现:
git clone https://github.com/keystone-enclave/keystone.git
cd keystone && git checkout v0.4.0
make -C sdk # 构建 host runtime
make -C sm # 构建 security monitor
make -C qemu # 编译含 Keystone 支持的 QEMU(默认上游已合入)
4.2 启动 smoke test
./build/qemu-riscv64/bin/qemu-system-riscv64 \
-M virt -cpu rv64 -m 512M -nographic \
-bios build/sm/firmware/fw_jump.elf \
-kernel build/sdk/examples/hello.ke
# 预期输出:
# [SM] Booting Keystone Security Monitor v0.4.0
# [Runtime] Loading enclave...
# [Eapp] Hello from RISC-V Enclave!
# [SM] Attestation report generated, signature: 9f3a...b21c
4.3 验证 attestation
# 提取 report 并在宿主机使用 SM 公钥验证
./build/sdk/tests/verify_report tests/report.bin \
--sm-pub-key build/sm/sm_public_key.pem \
--expected-hash $(sha256sum build/sdk/examples/hello.ke)
# 预期输出:Verification succeeded
QEMU 不模拟 MEE 时,步骤 4.2 中飞地内容以明文存于内存——这仅用于流程验证,不反映生产部署的真实隔离强度。
五、排错与系列闭环
5.1 高频问题
| 现象 | 可能原因 | 定位方法 |
|---|---|---|
| eapp 启动立即崩溃 | PMP 条目未配置为 Locked | 检查 sm/src/pmp.c 切换逻辑 |
| 远程证明签名验证失败 | SM 公钥未与验证方同步 | 核对 OTP 区与验证方数据库 |
| 飞地 ecall 后宿主崩溃 | 上下文切换未保存浮点寄存器 | 检查 sm/src/switch.S 的 CSR 保存范围 |
| MEE 异常导致启动卡住 | SoC MEE 固件版本不匹配 | 升级 SBI 与 MEE 固件版本对齐 |
5.2 与系列前作的衔接
- 安全篇:Smepmp 是 Keystone 的硬件底座;安全启动链条为远程证明的 SM 公钥提供信任传递。
- 启动篇:OpenSBI 在 Keystone 场景中扩展 SBI 调用以代理 MEE 操作。
- 虚拟化篇:飞地隔离与 VM 隔离属不同层级,机密 VM(Confidential VM)是两者结合的工程形态,后续可单独展开。
RISC-V 的机密计算生态仍在演进,Keystone 当前的工程资料与参考实现已足以支撑嵌入式场景的概念验证与方案评估。后续方向包括 Confidential VM 整合、形式化验证在 SM 上的应用、以及 MEE 的标准化进展。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)