提要
本期推送是对ICDE 2021 中发表的论文《TWINE:An Embedded Trusted Runtime for WebAssembly》的解读。WebAssembly是一种越来越流行的轻量级二进制指令格式。这篇论文描述了TWINE,这是一个WebAssembly trusted runtime,它能够支持编译为wasm的应用运行。TWINE提供了一个安全的软件runtime(沙箱),它嵌入在TEE中;并且提供WASI interface,通过WASI来抽象底层环境。TWINE会动态地将WASI操作翻译为等价的OS calls和SGX中的安全的库。特别地,作者使用TWINE实现了一个安全、可信的SQLite版本,这是一个众所周知的成熟的可嵌入数据库。作者认为这样一个受信任的数据库将是构建许多大型应用程序服务的合理组件。评估表明,SQLite可以通过WebAssembly和现有的系统接口在SGX enclave内完全执行,平均性能开销类似。额外的安全保证及其与标准WebAssembly的完全兼容性在很大程度上弥补了性能上的损失。
研究背景
可信代码执行目前是分布式系统的主要挑战之一。无论是云中的大型数据中心,还是瘦客户机和物联网设备上的网络边缘,其中存储了许多的数据资产。这些数据是许多公司的关键资产。例如像Intel SGX、ARM TrustZone等等这些TEE环境(Trusted execution environment,可信执行环境)就可以通过特殊的硬件结构为代码安全执行提供硬件支持,从而可以从外界环境中被保护出来,或者说隔离出来,这些外界环境包括操作系统和特权用户。
然而,尽管涌现出了许多framework和runtime environment,为TEE编写应用程序仍然是一项复杂的任务。开发人员通常必须使用定制的工具和api,而且仅支持少数的编程语言。所以,作者提出了支持对unmodified applications执行的trusted runtime,这个runtime作为一个virtual machine运行在TEE中,只需将application编译为WebAssembly,因为Wasm是不限制语言的。因为Wasm自身的一些优点,这个trusted runtime具有执行速度快、通用性好(支持多种语言开发的application)、安全(沙箱环境)等优势。
图1:研究背景示意图
系统设计
作者设计的Trusted runtime是运行在TEE中的。Intel SGX 是在现代英特尔处理器中的一组处理器指令,程序员可以通过使用 SGX 创建内存的加密区域,称为enclaves。通过enclave内部的指令对其中内存内容进行读写操作时会自动加密和解密。Enclave加密密钥保存在处理器内部,没有任何指令可以访问这些密钥,即使当运行高级硬件特权级别时,操作系统、虚拟机管理员也无法获取。Enclave内的内存受到保护,不接受任何未经授权的访问,甚至不接受具有物理访问权限的机器管理员的访问。
图2:SGX工作示意图
对enclave中的内存访问通过一个大块的缓存来加速,这个cache memory被称为enclave page cache(EPC)。EPC的大小是受限的,在最新的CPU中支持最大为256MB的EPC。处理器在 EPC 中保存所有 enclave page 的未加密副本,并且当 EPC 满的时候采用分页。并且硬件还为EPC中的所有enclave page维护加密hash表。enclave内部的指令可以访问enclave外部的数据,但是调用enclave外部的指令需要一个特殊的out call指令(OCALL)。当调用OCALL时,CPU退出受保护的enclave,在外部执行代码。相反,有一个enclave call(ECALL)指令来调用enclave内的代码。OCALL和ECALL指令会比较慢,因为在enclave内部和外部之间切换上下文的代价很高(在最新的服务器级处理器中,高达13’100个CPU周期)。已有的工作已经证明,在enclave中的应用程序应该尽量避免这样的调用,以减少性能损失。
作者提出了TWINE (Trusted Wasm in enclave),这是一个运行在TEE中的轻量级可嵌入Wasm虚拟机。图3中描述了TWINE的workflow。它充当应用程序与底层TEE、OS和硬件之间的适配层。TWINE提供了嵌套在TEE中的安全软件运行时(沙箱),支持WASI接口,并从应用程序中抽象出底层环境。
图3:TWINE workflow
TWINE是一个适用于在TEE中运行Wasm应用程序的执行环境。它主要由两个主要模块构成: Wasm runtime 和 WASI接口。Wasm runtime 完全运行在TEE内部,作者使用的TEE是Intel SGX。作者通过利用TEE的保护来为运行Wasm application提供一个可信环境。WASI充当受信任和不受信任环境之间的桥梁,抽象出专用于与底层操作系统通信的机制。因此,WASI相当于由OCALLs组成的传统SGX适配层。WASI能够通过沙箱实现安全性。常规应用程序通常通过标准接口(例如POSIX)调用操作系统。WASI在Wasm操作系统调用和实际的操作系统接口之间增加了一层(薄薄的)控制层。因此,runtime环境可以自己限制各个Wasm程序所能做的事情,从而阻止Wasm代码使用运行进程的用户的全部权限。(例如,WASI实现可以将应用程序限制在文件系统的子树中,这与chroot提供的功能类似。)在enclave中的代码和数据被认为是可信的,在此之外的进程部分、操作系统和(任何hypervisor)都可能是敌对的、恶意的。enclave内部的内存只能从外部以加密的形式读取。从外部写入enclave会导致enclave终止。
图4:TWINE 架构
通过WASI,能够实现三重抽象:
(1)开发人员可以自由选择编程语言,并通过compiler将它编译为Wasm binaries。
这解除了SGX强加的限制,之前通常因为这个限制强制应用程序必须用C/C++编写。
(2)将TEE从应用程序中抽象出来,只要TEE能够解释或执行Wasm (带有WASI支持),应用程序就可以安全执行。
这为其他TEE技术打开了大门。
(3)WASI是与系统无关的,只要操作系统能够提供WASI所需的等效API。
由于WASI模拟POSIX系统的系统调用,许多Unix变体都可以实现它。
图5:WASI的三层抽象
作者选择了一个已有的Wasm runtime project-WAMR来作为runtime,并修改了它的WASI接口。WAMR支持解释器、JIT、AoT三种方式的Wasm binaries执行。但是考虑到速度的问题,native code执行起来比解释器快。并且,解释器环境相对runtime而言,占用内存更大,这对于边缘计算又是很重要的。因此,作者放弃了WAMR中interpreter的方式。又因为JIT方式是运行时即时编译,需要在一个enclave中嵌进来一个JIT compiler。所以就要在enclave中引入LLVM machinery,这需要移植代码库来编译SGX的限制。所以最终作者采用了AOT的方式。
WAMR中原生的对WASI的实现,严重依赖于POSIX调用。POSIX在SGX enclave中不可用,因此WAMR作者编写的WASI实现需要频繁地跨越enclave的可信边界,并使用OCALLs直接将大多数WASI函数路由到它们的POSIX等效函数。出于性能原因:大多数WASI调用将被简单地转换为OCALLs。其次,作者希望能够利用其可信实现,例如英特尔保护的文件系统(IPFS)。因此,作者重构了WAMR的WASI实现,以保持其沙箱实施。
实验评估
如图6所示,作者使用 PolyBench/C benchmarks 来作为实验的benchmark,展示了30个PolyBench/C (v4.2.1-beta)测试的结果。通过native执行时间来进行标准化,比较了WAMR for wasm和TWINE for wasm in TEE的执行时间,结果如图所示。Wasm应用程序通常比本机应用程序慢,由于
(1)寄存器压力增加
(2)更多的分支语句
(3)代码大小增加等等
但是WAMR和TWINE之间的差距较小。
图6:PolyBench/C benchmark的性能测试,标准化到native speed
SQLite是一个被广泛使用的成熟的嵌入式数据库。由于其便携性(portability)和紧凑的尺寸(compact size),它非常适合SGX。并且SQLite能够体现出性能密集型的操作和文件系统交互,所以作者也对它进行了评估。作者使用了SQLite自己的性能测试程序Speedtest1,运行了32个可用测试中的29个,覆盖了大量场景。每个Speedtest1实验都针对于数据库的一个方面,(例如,使用多个关节进行选择,更新索引记录,等等)。测试由任意数量的SQL查询组成,根据生成的负载可能会执行多次。图7中显示了测试的结果,以native execution为标准进行了标准化。(其中包括内存中配置的结果,以及使用WASI的持久化数据库的结果。)作者在所有测试中观察到,对于in-memory数据库和in-file数据库,WAMR相对于本地数据库平均慢4.1x和3.7×。
在in-memory和in-file数据库中,TWINE相对于WAMR的速度慢了1.7x和1.9x。
图7:在SQLite Speedtest1 benchmark上的相对性能
为了更好地理解所观察到的性能损失的来源,作者为常见的数据库查询设计了一套测试,包括插入、顺序读取和随机读取。根据对这三类操作的执行时间分析,得出以下结果:
(1)图8a显示了关于插入记录的结果。
由于额外的文件加密,使用TWINE的持久数据库的操作成本线性增加。
(SGX-LKL在插入顺序元素方面有更优的方法,并遵循了TWINE的内存性能趋势。)
(2)图8b显示了顺序读取所有记录的执行时间。
作者在SGX内存访问中发现了造成这种性能损失的根本原因。
(3)图8c描述了随机读取的执行时间。
随机读取更加经常地触发enclave分页机制,文件内随机读取的例子突出了TWINE的优点,它提供了比SGX-LKL更快的性能,EPC(enclave page cache)限制之前为1.031×,之后为1.074×。在EPC限制以上的内存内插入也会有类似的性能提升,增益为1.035×。
图8:对SQLite的插入和读取进行性能评估
结论
这篇论文设计并实现了TWINE以支持编译为wasm的应用运行。TWINE提供了一个安全的软件runtime(沙箱),它嵌入在TEE中;并且提供WASI interface,通过WASI来抽象底层环境。评估表明,SQLite可以通过WebAssembly和现有的系统接口在SGX enclave内完全执行,并且平均性能开销类似。
原文标题:思辨|WebAssembly的嵌入式可信运行时
文章出处:【微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。
全部0条评论
快来发表一下你的评论吧 !