2 背景
2.2 SGX Software Design Space
为了把传统应用放到SGX中,Graphene-SGX等Shielding Framework面临的一个问题是把多少功能给塞进Enclave中。为了确保性能开销小,两个重要的考量指标是:
- 由于Enclave切换环境开销大,应尽量减少进出Enclave。
- 由于Enclave物理内存(EPC)有限,应避免过度使用内存导致EPC出现Swap,从而影响性能。
具体实施起来应该考虑的点如下:
Shielding复杂性 应用放到Enclave后,有时候必须要一些内核功能,对此需要开放接口使用不可信的内核并检查返回值(Shield)。此时接口开放得越少,接口的逻辑复杂性越低,实现所需代码越少,防范Iago Attack越轻松。
应用代码复杂性 传统应用代码逻辑复杂度不尽相同,移植到Enclave的做法也不尽相同。
- 移植到Enclave中的应用的逻辑尽可能简单纯粹,避免涉及Runtime,避免频繁跨越Enclave边界。
- 有些移植到Enclave的应用还是需要一些Enclave内无法实现的功能,对此需要开放一些Enclave接口,OCALL到Enclave外实现某些功能并检查返回值。
- 在Encalve内塞全功能的LibOS/Shim,如此能很好地兼容传统应用,还支持系统调用等。
应用拆分 待移植的应用可以将功能拆分,分别放入不同Enclave实例中,这能提升安全。为此Shielding Framework应该能够支持较小的代码如Library,并确保Enclave间能共享状态。
3 设计
3.1 威胁模型
我们可以相信CPU、Enclave代码以及AESMD(Intel签名的Architectural Enclave)。(注:如果能找到AE的漏洞,那感觉影响挺大)
我们会用到SGX驱动,但并不相信它,但我们可以通过CPU硬件指令验证SGX驱动没干坏事。
我们不相信其它任何东西。
3.2 用户策略配置
扩展了Enclave Manifest文件(如这里),需要开发者先验地指明配置。
- 要求开发者在Manifest中事先声明好要用的系统资源(如fs、network),保护Host避免Enclave滥用资源;
- 在Manifest中指定Enclave信任的外部文件的hash,确保该文件未被修改(完整性保护);
- 在Manifest中指定Enclave会往外写的文件,但无法确保机密不外泄(无机密性保护)。
3.3 多进程应用
实现了用户态Enclave Fork(如何实现的?),每个进程的Enclave内的LibOS实例间通过消息传递来复制父Enclave内容并同步状态,存在如父子等协作关系的Enclaves同属于Enclave Group。
4 保护Linux抽象(以防不可信Host OS)
4.1 保护动态加载
PAL让SGX驱动初始化Enclave,从Shield开始动态加载、运行时链接,形成图3的架构。
内存权限 ELF加载、链接时需要动态地改变Page的权限。但是SGXv1 Enclave内存权限在初始化时就确定了,因此需要事先将所有Page权限标记为RWX,虽然存在安全风险及功能不兼容的情况。
位置相关可执行文件 往往从0x400000地址起始,为了包含0x400000地址并满足SGX要求( E n c l a v e S i z e = 2 x EnclaveSize=2^x EnclaveSize=2x,起址对齐到EnclaveSize,即 E L R A N G E = n ⋅ 2 x ∼ ( n + 1 ) ⋅ 2 x ELRANGE=n\cdot2^x\sim(n+1)\cdot2^x ELRANGE=n⋅2x∼(n+1)⋅2x),ELRANGE 势必包含0地址。ELRANGE包含0地址并将其Unmap,能避免不可信OS操控0地址破坏Enclave完整性。
4.2 保护单进程抽象
LibOS基于PicoProcess及PAL。PAL实现了36个函数。Enclave接口缩减至28个以向外调用不可信OS。(细节尚需看一下源码)
文件认证 通过构建Merkel Tree与Manifest中的Hash比对验证。
内存映射 Manifest事先声明预留多少堆内存,确保能缓存文件等。(感觉还方便有足够空间进行自定义的内存布局)
线程模型 未来基于支持动态创建线程的SGXv2,可以实现m:n的线程模型,方便异步调用提升性能(多个网络请求的场景)
异常处理 SGX硬件AEX返回后,利用SSA传递信号让LibOS模拟异常。(能够变相地在SGX内提供本不支持的硬件指令,如cpuid和rdtsc)
4.3 保护多进程抽象
Enclave间不能共享内存,Graphene-SGX通过消息传递而非共享内存实现多进程支持、Signal、System V IPC。
Enclave fork 流程如图4,父进程基于加密信道传递上下文快照给子进程以初始化。
Enclave execve 由于实现时的安全性考虑,只能执行Manifest中指定的可信程序。
Enclave IPC 通过Enclave间RPC消息传递实现。
5 评估
测量应用移植到Graphene-SGX上的吞吐量或延迟。
5.1 服务器应用
应用 | 开销要因 |
---|---|
Aphene | IPC密集型遇到加密RPC导致表现变差 |
NGINX | 主要因为事件驱动单线程型遇到Graphene-SGX只支持同步IO导致表现变差 |
其他原因包括SGX固有开销 |
5.2 命令行应用
应用 | 开销要因 |
---|---|
R | 内存分配和垃圾回收会造成明显性能开销。因为现有实现假设内存很大,布局稀疏,而SGX1要求Enclave内存创建时映射。 |
GCC | Enclave初始化 |
CURL | I/O延迟 |
5.3 性能开销分析
操作 | 开销要因 |
---|---|
打开文件 | 第一次打开文件时预加载文件内容构建Merkel Tree并计算Root Hash和Manifest比对 |
读文件 | 验证读取的文件块 |
fork | 创建新Enclave、本地认证、上下文复制时无法批量IPC(Graphene-SGX不支持m:n线程模型及异步调用) |