try ai
科普
编辑
分享
反馈
  • 安全飞地

安全飞地

SciencePedia玻尔百科
关键要点
  • 安全飞地从根本上改变了计算机安全,它将可信计算基 (TCB) 缩小到仅包含 CPU 硬件,并将操作系统视为对手。
  • 安全性通过硬件机制强制执行,例如用于保证机密性的内存加密,以及用于证明运行代码完整性的远程证明。
  • 封印机制允许飞地使用一个派生自硬件的、对该 CPU 和飞地身份唯一的密钥来加密数据,以实现持久化存储。
  • 安全飞地催生了各种新颖的应用,从防御恶意软件、保护物联网设备到充当区块链的可信预言机。

引言

在一个日益互联的数字世界中,我们敏感数据和计算的安全性往往依赖于庞大而复杂的软件层。传统的安全模型信任操作系统,但当这个基础层被攻破时会发生什么?这一漏洞迫切需要一种新的范式——信任不再锚定于易出错的软件,而是锚定于不可变的硬件。安全飞地作为一种强大的解决方案应运而生,它在处理器内部提供了一个硬件隔离的堡垒。本文将踏上揭开这项技术神秘面纱的旅程。首先,在“原理与机制”部分,我们将探讨使飞地得以运作的架构和密码学基础,从颠覆传统信任模型到证明和封印的机制。随后,在“应用与跨学科联系”部分,我们将发现这种信任上的根本性转变如何在网络安全、物联网和去中心化系统中催生革命性的应用,从根本上改变我们构建安全系统的方式。

原理与机制

要真正领会安全飞地的精妙之处,我们必须超越“安全盒子”的简单概念,探索赋予其生命的基础原则。这是一个颠覆数十年信任关系的故事,一个在硅片中铸造新规则的故事,一个将密码学不仅用作通信工具,更用作架构基石的故事。

机器中的堡垒:一种新的信任模型

在计算历史的大部分时间里,操作系统 (OS) 一直是最高统治者——数字王国的可信内核。它处于特权硬件状态(如“Ring 0”),监管所有应用程序,管理所有内存,并掌握着所有资源的钥匙。我们隐含地信任它。但如果我们不能信任它呢?如果操作系统本身被恶意软件攻破,或者我们根本不希望云服务提供商的操作系统访问我们的敏感计算,该怎么办?

这正是安全飞地最激进之处:它缩小了​​可信计算基 (TCB)​​——为保证安全而必须信任的所有硬件和软件组件的集合。在传统系统中,TCB 包含了庞大而复杂的操作系统。而在有安全飞地的系统中,TCB 被大幅缩减至仅处理器硬件本身。

这一哲学上的转变对操作系统的角色产生了深远影响,它如今被降级为一个强大但不受信任的仆人。从飞地的角度来看,操作系统是一个对手,其职责被置于深度怀疑的视角下审视:

  • ​​内存管理​​:操作系统仍然管理将虚拟地址映射到物理内存的页表。然而,CPU 硬件现在扮演着更高的权威角色。处理器会加密飞地的私有内存,并确保操作系统(或任何其他软件)访问飞地内存页的任何企图都会被硬件阻止,无论页表如何规定。操作系统在飞地内存保护中的角色完全是​​建议性的​​;它可以建议将内存放在哪里,但最终的访问控制由硬件强制执行。

  • ​​CPU 调度​​:操作系统仍然决定哪个线程在何时运行。但是,一个不受信任的操作系统可能会选择永不调度飞地的线程(一种拒绝服务攻击),或者以特定的模式调度它们,从而通过时间侧信道来了解它们的行为。因此,飞地不能依赖操作系统来保证活性或公平性。即使在对抗性调度下,其逻辑也必须是正确的。

  • ​​输入/输出 (I/O) 和命名​​:当飞地需要写入文件或发送网络数据包时,数据必须离开硬件保护的堡垒,并穿过操作系统。一旦数据到了外部,就进入了敌对区域。操作系统可以读取、修改或丢弃数据。它可以在文件名上撒谎,在请求良性文件时提供一个恶意文件。因此,操作系统提供的任何 I/O 抽象都仅仅是“方便的接口”,而非信任锚点。为了保护静态或传输中的数据,飞地必须使用自己的密码学,我们将在​​封印​​和安全通信中探讨这一概念。

跨越护城河:进入、退出和通信的机制

如果飞地是一个堡垒,那么如何进出呢?简单的函数调用是行不通的,因为它不会改变硬件的保护上下文。标准的系统调用则更糟,因为它会将控制权交给不受信任的操作系统——就像为敌人放下吊桥。

解决方案在于处理器​​指令集架构 (ISA)​​ 定义的特殊指令。最常见的范式涉及使用 ECALL(“飞地调用”)进入飞地,以及使用 OCALL(“外部调用”)退出。

ECALL 是一个严格控制的转换。处理器验证目标位置,保存当前上下文,并切换到“飞地模式”,激活硬件内存保护。然而,这种转换并非没有代价。它会因专门的指令、保存和恢复状态的需要,以及有时因刷新​​转换后备缓冲区 (TLB)​​等微架构结构或预热​​内存加密引擎​​而产生显著的性能开销。

跨越这个边界进行通信也是一门精巧的艺术。你不能简单地将一个指针传入飞地,因为操作系统无法访问它所指向的数据。相反,参数必须被小心地复制——这个过程称为​​编组​​——在进入时从未受信任的应用程序内存复制到飞地的受保护内存中,结果在退出时再被复制回来。

也许最关键的机制限制是无法从飞地内部进行直接的​​系统调用​​。由于飞地在非特权用户模式下运行,尝试执行 syscall 指令会被硬件拦截。CPU 不会将控制权转移给操作系统内核,而是触发一个故障或受控退出。这可以防止飞地天真地信任操作系统。要访问系统服务,飞地必须向不受信任的主机应用程序执行一个 OCALL,然后由该应用程序代表飞地进行所需的系统调用。这种复杂的舞蹈维持了隔离性,但也引入了延迟,特别是对于 I/O 密集型工作负载,数据必须被分割成更小的块,每一块都需要在边界内外进行一次完整的往返。

筑起高墙并证明其真实性

飞地的安全性建立在两大支柱之上:硬件构建坚不可摧的墙壁的能力,以及向外部世界证明这些墙壁是真实的能力。

主要的“墙壁”是​​加密内存​​。处理器包含一个专用的​​内存加密引擎 (MEE)​​,它会自动加密所有从飞地写入片外 DRAM 的数据,并在读回时进行解密。这确保了机密性;即使能够物理访问内存总线,攻击者也只能看到无法理解的密文。

但仅有机密性是不够的。攻击者可以记录有效的加密数据,并在稍后重放以欺骗飞地(重放攻击)。为了防止这种情况,硬件还保证了​​完整性​​和新鲜度。这通常通过​​Merkle 树​​等密码学结构来实现。在这个优美的方案中,飞地内存的每个缓存行都是一个巨大哈希树中的“叶子”。对缓存行的任何更改都会改变其哈希值,进而改变其父节点的哈希值,依此类推,直到一个安全存储在处理器内部的根哈希。在使用内存中的任何数据之前,硬件会验证其在树中的路径。如果任何一个字节被篡改或重放,最终计算出的根哈希将与可信的根哈希不匹配,硬件将引发异常。

有了这些墙壁,远程用户如何相信他们正在与一个真正的飞地通信,而不是一个运行在被攻破机器上的软件模仿品?这通过​​远程证明​​来完成。当一个飞地首次创建时,处理器的硬件会计算其初始代码和配置的密码学哈希——一个独特的指纹或度量 (H(code∣∣config)H(\text{code}||\text{config})H(code∣∣config))。该度量由一个受信任的硬件单元在加载过程中执行,通常与内存传输并发进行,以隐藏性能成本。然后,该度量被存储在一个特殊的 CPU 寄存器中。飞地随后可以请求 CPU 使用一个可追溯到 CPU 制造商的硬件绑定密钥对此度量进行密码学签名。远程用户可以验证这个签了名的“证明报告 (quote)”,并确信处理器内部运行的确切代码,完全绕过不受信任的操作系统所做的任何声明。

秘密金库:为未来封印数据

飞地的内存是易失的;断电后就会消失。为了持久地存储秘密,飞地必须将它们写入由不受信任的操作系统控制的磁盘。这就是​​封印​​发挥作用的地方。

飞地可以请求 CPU 派生一个唯一的密码学密钥。这个密钥不是随机的;它由几个因素派生而来,包括一个熔断到处理器中的秘密根密钥 ($K_{\mathrm{root}}$)、飞地作者的身份 ($mr_{\mathrm{signer}}$),以及至关重要的是,飞地的安全版本号 (svnsvnsvn)。

由此产生的封印密钥 $K_{s} = \mathrm{KDF}(K_{\mathrm{root}}, mr_{\mathrm{signer}}, svn, \text{``seal''}),对于在该特定 CPU 上的该飞地家族是唯一的。飞地可以使用 $K_{s}$ 来加密其数据,然后交给操作系统进行存储。只有在同一物理 CPU 上运行的、具有相同身份和版本号的飞地才能请求硬件重新派生出完全相同的密钥来解密数据。

该机制为​​撤销​​提供了一个强大的工具。如果在 $svn = s$ 的所有飞地中发现了一个漏洞,平台所有者可以分发一个签名的微码更新,告诉处理器增加一个硬件级撤销计数器。此后,CPU 将拒绝为请求版本号低于新阈值(例如 $s+1$)的飞地派生任何密钥。这一单一行为从密码学上使得所有先前由该易受攻击的飞地版本封印的数据永久无法访问,从而强制实施了稳健的安全更新。

架构多样性与挥之不去的幽灵

并非所有飞地的构建方式都相同。到目前为止描述的模型,即小型用户模式应用程序依赖于不受信任的操作系统,是​​基于进程的飞地​​(如 Intel SGX)的特征。这种设计优先考虑最小的 TCB。

另一种著名的架构是​​双世界模型​​,例如 ARM TrustZone。在这里,处理器被划分为一个“普通世界”(运行标准操作系统)和一个“安全世界”,后者可以运行自己独立的、受信任的操作系统。在这种模型中,在安全世界中发生的陷阱和异常由安全操作系统处理,从而在不退出到不受信任的普通世界的情况下保持隔离。这允许构建更复杂的安全组件,如可信设备驱动程序,但代价是 TCB 大得多。

最后,即使有这些令人难以置信的硬件保护,安全之战也永无止境。飞地和所有计算一样,会在处理器共享的微架构状态中留下微妙的痕迹。它们的执行模式会预热缓存、填充分支预测器并填充 TLB。一个恶意的操作系统,通过在飞地执行完毕后仔细观察这些“幽灵”,可以发起​​侧信道攻击​​来推断秘密信息。为了对抗这一点,现代安全处理器必须在每次飞地进入和退出时执行昂贵的​​擦洗​​操作,从缓存中使非飞地条目无效,并刷新预测器缓冲区。这场在硬件最深层次上进行的攻防猫鼠游戏,突显了构建一个真正安全的飞地所面临的巨大挑战——以及其中蕴含的深邃智慧。

应用与跨学科联系

我们花了时间凝视安全飞地的核心,理解了那些让我们能够在计算机内部建立一个小型信任堡垒的硬件和密码学的精巧机制。我们已经看到它如何封存秘密,保证即使是机器自身的操作系统——那个本应是房子的主人——也无法窥探内部。这是一个卓越的成就。但是,一个堡垒,无论多么坚固,其价值仅在于它所能成就的事物。现在,让我们走出堡垒,看看这个新的信任工具让我们能够构建怎样的世界。我们就像刚刚建造了一种新型望远镜的天文学家;我们将发现哪些新的星辰?

加固计算的根基

可信执行环境 (TEE) 最直接的用途是加固计算的根基,而这些根基几十年来一直出人意料地脆弱。我们的数字生活建立在层层软件之上,任何一层的裂缝都可能让整个大厦崩塌。

以恶意软件的祸害为例。例如,勒索软件通过获取你的宝贵数据并用一个密钥将其加密来运作。如果你支付赎金,攻击者就会给你密钥。但如果我们能扭转局势呢?一个试图击败某个勒索软件的分析师需要在恶意软件运行时,在计算机内存中找到那个密钥。一个编写巧妙的病毒可能会使用操作系统自身的密码学工具,但如果这些工具由 TEE 支持,就可以要求它们生成一个不可导出的密钥。这个密钥在飞地内部诞生,其整个生命周期都在其中度过,并被用来加密文件,但它的原始形式永远不会出现在主内存中。分析师在计算机内存中搜寻时,只会找到一个不透明的“句柄”——一个指向堡垒内部秘密的无意义数字。密钥保持安全,没有它,分析师的工作就变得不可能。在这里,TEE 就像一个黑匣子,它执行一个秘密动作而不泄露秘密本身。

这种“密码学预言机”的想法非常强大。它可以用来修复陈旧而顽固的漏洞。很长一段时间以来,攻击程序最常见的方法之一是“缓冲区溢出”。程序为某些数据留出一个小盒子(缓冲区),攻击者巧妙地提供了过多的数据,这些数据溢出并覆盖了一些重要的东西,比如函数的返回地址,从而劫持了程序的流程。一个标准的防御方法是“栈金丝雀”——一个放置在返回地址旁边的秘密数字,就像一个绊索。在返回之前,函数检查金丝雀是否还在那里。如果它被覆盖了,程序就知道自己受到了攻击并停止运行。

但这有一个经典的间谍电影式缺陷:如果攻击者可以直接从栈中读取秘密的金丝雀值,然后在覆盖返回地址后小心地把它写回去呢?如果入侵者知道绊索在哪里以及如何跨过它,绊索就毫无用处了。使用 TEE,我们可以发明一个好得多的绊索。函数入口代码不再是在栈上放置一个静态的秘密,而是可以询问飞地:“请用你隐藏的密钥,计算这个返回地址和这个栈帧的密码学签名 (HMAC)。”飞地计算出签名——一个“标签”——并将其交回。这个标签就是金丝雀。它不是秘密;攻击者可以读取它。但它是不可伪造的。如果攻击者改变了返回地址的哪怕一个比特,他们也需要飞地的密钥才能计算出新的、正确的标签。他们做不到。所以,当函数即将退出时,它只需请飞地对(可能被修改的)返回地址重新计算标签,并与原始标签进行比较。如果它们不匹配,警报就会拉响 [@problem-id:3625645]。我们程序的完整性得以保护,不是通过隐藏一个秘密,而是通过使用 TEE 的不可伪造的过程。

堡垒还必须守卫其边界。一台现代计算机不仅仅是一个中央处理器;它是一个由外围设备——网卡、磁盘控制器、图形处理器——组成的繁华城市,这些设备通常可以直接写入内存,这一特性称为直接内存访问 (DMA)。一个攻破了网卡的攻击者原则上可以命令它读取飞地的“受保护”内存,从而完全绕过 CPU 的防御。为了防止这种情况,平台需要一个输入输出内存管理单元 (IOMMU)。IOMMU 对每个设备都像一个边境守卫,检查其每次内存访问的“护照”。为了授予一个设备访问飞地内存缓冲区的权限,我们在 IOMMU 的表中为该设备创建一个严格、明确的已批准内存页列表。对于一个有 mmm 个设备需要访问总大小为 SSS 的缓冲区的系统,在页大小为 PPP 的情况下,这需要创建 mmm 个独立的权限集,每个权限集包含 ⌈SP⌉\left\lceil \frac{S}{P} \right\rceil⌈PS​⌉ 个条目。这种细致的配置确保了即使是流氓设备也被限制在其预先批准的区域内,无法自由漫游和窥探飞地的秘密。

信任的成本与节奏

然而,这种强大的安全性并非没有代价。每次我们跨越边界进入飞地,都会有成本。处理器必须暂停、检查凭证、切换上下文并保卫边界。这种开销虽然微小,但会累积起来,它迫使我们像工程师一样思考,在安全与性能之间寻求平衡。

想象一个高安全性数据库,它将其数据存储在飞地内部的一个 Merkle 树中,以保证其完整性。每一片数据都通过密码学与其邻居相连,邻居又与它们的父节点相连,一直连接到唯一的、可信的“根哈希”。要读写哪怕一页数据,TEE 都必须验证从该页的叶子到根的整个哈希链。这是巨大的工作量。对于一个拥有数百万页的数据库,一个仅触及几十页的简单事务就可能触发数千次密码学计算和内存访问,因为系统在费力地重新验证和更新这些完整性证明。性能成本不是一个缺陷;它是我们正在构建的信任的物理体现,一周期一周期地累积。

我们甚至可以量化这种权衡。假设我们正在设计一个系统,可以选择在每次上下文切换进入飞地时都执行一次完整的证明——即对飞地身份和状态的密码学证明。这样做会极大地降低机密性泄露的风险,比如从百万分之一的几率降低到十亿分之一。但证明过程本身需要时间:它涉及哈希飞地的内存、生成签名并进行验证。我们可以计算这个时间,也许是 1.5581.5581.558 毫秒。如果我们的工作负载每秒切换进飞地 100100100 次,这意味着我们将花费大约 15.6%15.6\%15.6% 的 CPU 时间仅仅用于证明。这值得吗?这不再是一个纯粹的技术问题。这是一个策略决策,是在可接受的风险水平和可接受的性能开销之间取得的平衡,但现在这个决策有了具体数字作为依据。

这种信任与成本的节奏在一些意想不到的地方上演。考虑一个现代视频游戏,其中一个反作弊系统在飞地内部运行。它定期采样游戏状态以确保没有人作弊。为了保证此检查的完整性,每次采样都需要进入飞地,这会使主渲染循环停顿。如果我们采样过于频繁,我们可能会更快地抓住作弊者,但持续的停顿会导致游戏的帧率下降,破坏诚实玩家的体验。如果我们采样频率太低,作弊行为可能会在很长一段时间内未被发现。设计者必须找到正确的平衡点,根据采样周期计算预期的检测延迟,并权衡其对游戏有效每周期指令数 (IPC) 的影响,所有这些都是为了创造一个公平且可玩的游戏。

将信任编织到世界的结构中

安全飞地最深远的影响可能不在于它们如何改变我们的计算机,而在于它们如何改变我们的计算机与世界的关系。

以蓬勃发展的物联网 (IoT) 为例。像智能恒温器这样的简单设备是一个信息物理系统;它的软件直接控制着物理世界。一个黑客如果攻破了它,可能会造成真正的损害。通过将核心控制循环——传感器读数、决策逻辑和执行器命令——放置在 TEE 内部,我们可以保证其完整性。恒温器上的操作系统可能被彻底攻破,但 TEE 确保了打开暖气的命令只能来自真实、未经篡改的控制逻辑。为了设计这样一个系统,我们不仅要考虑内存隔离——计算飞地代码、栈和密码学密钥所需的确切 KiB 数量——还要考虑实时约束。一个控制周期的总时间,从感应温度到驱动熔炉,必须小于某个界限,否则系统会变得不稳定。进入 TEE、验证传感器数据和退出的开销成为这个“延迟预算”的关键部分,我们必须计算我们的安全系统能够承受的来自不受信任的操作系统的最大可容忍“抖动”——即不可预测的延迟。

当与像区块链这样的去中心化系统相结合时,这种提供可验证的“基准真相”的能力是革命性的。区块链是一个全球性的、分布式的账本,极难被篡改。但它有一个根本问题:它是一个封闭的世界。区块链上的智能合约对真实世界一无所知。它如何能信任来自外部来源的信息?TEE 可以充当一座桥梁。一个飞地可以运行一个程序,例如,从金融数据源获取股票价格。然后,它可以生成一个证明报告——一份来自硬件本身、经过密码学签名的声明,内容是:“我是一个类型为 X 的、真正的、安全的飞地,我运行了确切的代码 Y,结果是 Z。”这个证明可以提交给区块链。被编程用来验证这些签名的智能合约,现在可以信任这些数据了。它获得了关于信息来源和完整性的硬件根源的保证。这种信任的成本甚至可以用区块链的原生单位来衡量,比如“gas”,通过对必要的哈希计算和签名验证的计算开销进行建模。

也许最具未来感的应用是构建无需中央权威的协作系统。想象一下,几个组织,比如医院,想要联合分析他们的病人数据以找到一种疾病的治疗方法。但由于隐私法规,他们不能共享原始数据。使用 TEE,他们可以构建一个由多个互不信任的飞地组成的系统。每家医院都将自己的数据放入自己的飞地内。这些飞地可以相互建立安全的、经过证明的通信渠道。然后,它们可以参与一个协议来共同计算一个结果——例如,一个统计模型——而无需向彼此透露任何个人病历。这样的系统需要精心设计密钥轮换和分发协议,其中一个新的共享密钥在一圈飞地之间传递。密码学操作的复杂性和速率成为系统效率的关键度量,是参与者数量 nnn 和轮换周期 π\piπ 的函数,可以用一个类似 3n−2π\frac{3n-2}{\pi}π3n−2​ 的表达式来表示。

从处理器的核心到互联网的边缘,从保护单个密钥到实现全球协作,安全飞地是一个简单的概念,却蕴含着惊人的意义。它是数字世界的一个新的基本构建模块,一个让我们能够构建不仅强大而且可证明是可信的系统的模块。我们才刚刚开始探索这种新型信任所能实现的架构。