摘要

非易失性存储器(NVM)被提出,它为主存储器提供了一种有吸引力的结构。与DRAM不同,NVMM在断电后保留数据。这允许内存在崩溃和重新启动期间持久承载数据,但为攻击者在启动期间窥探、篡改数据提供了机会。虽然DRAM系统的内存加密和完整性验证已经得到了很好的研究,但如果我们想同时保持安全保证、崩溃/重新启动的数据恢复、良好的持久性性能和快速恢复,NVM将面临新的挑战。

在本文中,我们使用所有安全元数据(计数器、MAC和Merkle树)探讨数据的持久性,以实现安全持久性。我们表明,为了确保安全保证,除了计数器之外,还需要维护消息身份验证码(MAC)和Bonsai Merkle树(BMT),它们导致了大部分的持久性开销。我们分析了实现持久性和非持久性内存区域的安全持久性的需求。我们发现,内存的非易失性可能会在重新启动时触发完整性验证失败,因此我们提出了一种单独的机制来支持非持久性内存区域。第四,我们提出了快速恢复的设计。我们的评估表明,与严格持久性相比,所提出的设计Triad-NVM可以将吞吐量平均提高2倍。此外,与没有安全元数据持久性的系统相比,Triad NVM可以实现数量级更快的恢复时间。

1. 引言

非易失性主存储器(NVMM)与DRAM相比,它提供了一系列引人注目的功能。最近发布的Intel Optane DC持久性内存提供高达3TB/插槽的高容量、低比特成本、字节寻址能力和非易失性。由于数据在没有电源的情况下仍保留在NVMM中,因此数据剩磁是一个真正的安全漏洞,因此Optane DC附带了硬件内存端加密。虽然内存端加密可以作为独立解决方案提供良好的第一道防线,但由于没有为应用程序提供安全的执行环境,它的安全保护较弱。为了实现更全面的保护,处理器端内存安全是必要的。

NVMM还支持持久化应用程序,这些应用程序可以在崩溃或重新启动后通过将数据持久化到内存中进行恢复。虽然持久性和安全性似乎是正交的,但它们应该在NVMM中一起研究,因为系统应该能够安全地恢复,并在崩溃/重新启动期间保证其数据完整性和机密性。然而,持久性和安全性在很大程度上是分开调查的;除了在冷启动攻击下,DRAM等易失性内存不具备跨崩溃恢复内存的功能。在这样的系统中,安全元数据预计将在启动时重新初始化。此外,最近关于持久性和安全性的研究侧重于正常运行的性能,而没有考虑跨崩溃和重新启动的持久性。最后,NVMM中的内存持久性和崩溃恢复是一个活跃的研究课题,但它们关注的是持久性问题,而不是安全性。

我们认为,由于数据剩磁漏洞,持久性和内存安全性需要综合考虑以下要求:

  • 维护安全保障。内存加密和完整性验证应保证数据的机密性和完整性,即使内存是非易失的。
  • 数据可恢复性。NVMM可分为持久性区域和非持久性区域,其中程序员在持久性区域中保存持久数据,在非持久性区域中保存临时数据。持久区域中的数据应可在崩溃和系统重新启动时恢复。同时,NVMM应该阻止从非持久性区域恢复数据。
  • 快速持久性和恢复。持久性不应显著降低执行速度。崩溃/重启后恢复应该相对较快,以确保高可用性。

目前的研究不符合上述所有要求。例如,最近的研究探索了NVMM上原子持久化的数据和加密计数器。虽然它们提供了数据可恢复性,但却忽略了数据和计数器的完整性保护,这对于计数器模式内存加密安全至关重要。因此,由于系统容易受到数据直接篡改和计数器重放攻击,即重放旧版本的数据及其计数器以逃避加密,因此无法保留安全保证。此外,研究也没有讨论如何区别对待内存的持久性和非持久性区域,也没有讨论恢复时间的问题。

本文介绍了在具有内存加密和完整性验证的系统环境中全面提供持久性的第一项工作。我们讨论了在采用内存加密和完整性验证的NVMM系统中持久化安全元数据的问题。稍后,我们定义了一个新概念,即安全持久性,它定义了安全恢复完整性保护和加密内存系统的要求。最后,我们讨论了几种松弛方案以及利用它们优化性能的综合设计。

本文的主要贡献如下。首先,我们展示了NVMM中的持久和非持久区域必须根据安全元数据进行不同的处理。其次,为了确保安全保障,除了计数器之外,还需要维护消息身份验证码(MAC)和Bonsai Merkle树(BMT)等元数据。第三,每次在NVMM中保存新的数据值时,BMT都需要从叶到根进行更新,否则数据可以恢复,但恢复后其完整性无法再得到保证。事实上,持久化BMT元数据比持久化计数器的开销高得多,因此之前的研究低估了在安全内存中持久化数据的开销。第四,对于非持久性数据,我们发现内存的非易失性可能会导致重新启动时的完整性验证失败,因此我们提出了一种单独的机制来支持非持久性内存区域。第五,我们展示了使用TB级的NVMM进行恢复可能需要一个多小时,因此我们提出了延迟恢复优化,以加快恢复速度。

为了评估我们的设计,我们使用Gem5,一个全系统周期精确模拟器。我们使用 Linux 内核版本 4.14 以及基于 Ubuntu 16.04 的磁盘映像。 此外,我们初始化内核以将最后 4GB(16GB 中的)专用于持久区域,稍后我们将其挂载为可直接访问 (DAX) ext4 文件系统。 任何支持持久内存的库都可以使用持久区域,但是,除了四个基于 DAX 的合成工作负载外,我们选择使用英特尔的 PMDK 库 [24](以前称为 PMEM)来构建三个微基准测试,以及 12 个 来自 SPEC2006 套件的基准测试 [25]。 我们还评估了四种运行持久(PMDK 和 DAX)和非持久 (SPEC) 工作负载组合的工作负载。 我们的模拟结果表明 Triad-NVM 可以将吞吐量平均提高 2 倍(相对于严格的持久性)。 此外,Triad-NVM 对于 8TB NVM 系统保持不到 4 秒的恢复时间(64TB 为 30.6 秒),这比没有安全元数据持久性的系统快 3648 倍。

本文的其余部分安排如下。 首先,我们在第 2 节中讨论了安全 NVM 系统的问题和背景,我们还讨论了在安全 NVM 中持久保存安全元数据的传统方法。 稍后,在第 3 节中,我们将讨论安全持久内存系统的要求。 稍后,我们将讨论不同的松弛方案及其对 NVM 系统的安全性、性能和弹性的影响。 在第 4 节中,我们讨论了我们的评估方法。 我们的评估结果和讨论在第 5 节中介绍。第 6 节讨论了与我们的论文最相关的工作。 最后,我们在第 7 节结束我们的工作。我们将从背景讨论开始我们的部分,然后讨论安全元数据的崩溃一致性问题。 稍后,我们将提供有关问题影响的动机数据。

2. 背景和动机

我们将从背景讨论开始我们的部分,然后讨论安全元数据的崩溃一致性问题。 稍后,我们将提供有关问题影响的动机数据。

2.1 背景

非易失性主存储器 (NVMM),例如 Micron 3D XPoint 或 Intel DC Persistent Memory [26],即将面世,预计很快就会上市。 与 DRAM 相比,它们具有更高的密度、更低的每比特成本和更低的空闲功耗,并且具有非易失性 [27-29],但访问延迟更高且写入耐久性有限。 由于它们的非易失性,它们可以用作托管文件系统的存储,或用作持久或非持久内存。 具体来说,基于 NVM 的 DIMM 可用于保存文件和常规内存页面,并且可以通过加载/存储操作以类似于 DRAM 的方式进行访问。 为了实现这一点,新的操作系统 (OS) 开始支持将内存配置为持久性和传统的非持久性内存。 例如,最近的 Linux 内核和 Windows 开始支持对文件系统的直接访问 (DAX) [30]。 在支持 DAX 的文件系统中,例如带有 DAX 的 ext4,文件可以直接进行内存映射并通过典型的加载/存储操作访问,而无需像在传统文件系统中那样将其页面复制到页面缓存。 例如,NVMM 可以配置为具有专用于保存文件系统的分区。 在 Linux 中,在初始化内核时,可以使用参数 memmap=4G!12G 将地址 12GB 开始的 4GB 专用于可直接访问的文件系统。 因此,单个物理内存空间可以托管持久区域(用于文件)和非持久区域(用于常规内存页面)。

2.1.1 NVM安全

由于非易失性,NVM 容易受到被动机密性破坏(例如通过数据剩余攻击)以及通过数据篡改导致的主动完整性破坏。非易失性为攻击者提供了充足的时间在操作期间执行被动和主动攻击,但最重要的是在通电事件之间的关闭周期期间。 因此,NVM 必须与内存加密和完整性验证相结合。加密可以在内存端或处理器端执行。内存端加密是针对依赖内存作为信任根的内存产品的独立解决方案。它嵌入了一个加密引擎,在将数据写入内存行之前对其进行加密,并在将其发送到处理器之前对其进行解密。但是,它的保护较弱。数据仍以明文形式在系统总线上进行通信,从而使其面临机密性泄露。与处理器建立安全通信通道需要复杂的身份验证过程。它也不能为处理器上运行的应用程序提供安全的执行环境,因为它无法区分来自处理器的访问请求的合法性。处理器端内存加密以处理器芯片为安全边界,从而消除了上述缺点,但需要对处理器进行修改。数据在离开处理器芯片之前被加密,当它从 NVMM 获取时,它被解密并验证其完整性。

2.1.2 内存加密和完整性验证

在计数器模式加密中,加密算法(例如 AES)以初始化向量 (IV) 作为其输入以生成一次性填充 (OTP),如图 2 所示。稍后,当块到达处理器芯片时, 执行与填充(加密的 IV)的低成本按位异或以获得明文。 通过这样做,解密延迟与内存访问延迟重叠。 除了其性能优势之外,计数器模式内存加密还可以防御各种攻击。 计数器模式加密可以安全地抵御基于字典的攻击、已知明文攻击和总线窥探攻击。

有几种可能的计数器格式,包括单片(在 SGX 中使用)和拆分格式。Monolithic 对所有内存块使用一个(全局)计数器,每次将任何块写回内存 10 时,计数器都会增加,以避免计数器重用。 全局计数器的溢出需要代价高昂的整个内存重新加密。 因此,单片计数器需要很大,例如 64 位。 由于用于加密块的计数器值需要保留和检索以备将来解密,因此大型计数器还需要大型片上缓存以降低计数器缓存未命中率。 在拆分计数器方案中,加密计数器被组织为主要计数器(在同一页面的缓存块之间共享)和特定于每个缓存块的次要计数器 [7]。 这种组织允许将 64 个缓存块的计数器打包到一个 64B 块中; 7 位次要计数器和 64 位主要计数器。 当主计数器的一个从计数器溢出时,主计数器会增加,其中所有相应的次计数器将被重置,整个页面将使用新的主计数器 [7] 重新加密。 主计数器足够大(例如 64 位),不会在系统生命周期内溢出。 拆分计数器方案比单片计数器方案的空间效率高得多,并且实现了更高的计数器命中率,因此它的性能明显优于单片计数器方案。 因此,我们假设了一个拆分计数器方案,正如最近的研究[7-9, 31] 中所假设的那样。

计数器模式加密的基本安全保证要求计数器值不能重复,否则加密可以被破解。 为避免计数器重放,计数器必须通过默克尔树(称为Bonsai Merle树或 BMT)防止篡改。 这是先前研究中忽略的一个方面。 使用 BMT,数据只需要通过 MAC 而不是 Merkle Tree 保护。 如图 1 所示,每个与一组数据块相关联的加密计数器块用于计算哈希值 (MAC),该哈希值将与来自其他计数器组的其他哈希值一起使用以创建较低级别 哈希值。 最后,生成的 MAC 值称为根,始终保存在处理器中。 每次从不安全区域(例如内存模块)中取出计数器时,都会通过计算上哈希值来验证它,并查看结果是否与处理器中保存的根匹配。 此外,当处理器写入内存块并更新相应的计数器时,必须更新 BMT 父节点以反映最近的更改。修改传播到根取决于数据恢复的要求。

2.1.3 持久性对安全性的影响

NVMM 可能托管持久数据,这些数据需要在崩溃/重启后恢复。 由于加密数据需要使用用于对其进行加密的正确(最新)计数器值进行解密,因此当数据保留在内存中时,其计数器也必须保留。 否则,在崩溃时,如果使用过时的计数器值解密,则数据可能无法恢复。 刘等 [18] 进行了这一观察并提出了以原子方式持久化数据及其计数器的方案,要么严格(在每个持久化),要么在epoch或事务边界。 原子性不仅需要保证可恢复性,还需要保证加密的安全性,因为内存中的陈旧计数器可用于诱导填充重用 [19]。

2.2 安全元数据崩溃一致性

重要的是不仅要持久化数据及其计数器。 如前所述,计数器模式加密从根本上依赖于要保持的计数器的完整性。 因此,崩溃恢复也必须考虑默克尔树。 发生崩溃后,系统必须能够恢复和恢复其加密的内存数据及其随附的安全元数据。 图 3 讨论了 Ye 等人 [19] 所描述的崩溃一致性所需的逻辑步骤。

如图 3 所示,BMT的根(片上)应该与处理器内受影响的中间节点一起更新/持久化(步骤 1),一直到 BMT 的根。 然而,只有树的根需要保留在安全区域中。 在步骤 2 中,更新的计数器块在计数器缓存中更新时被持久化(写入内存)。 最后,在步骤 3 中,写入的数据块将被发送到内存中。 请注意,更新根、计数器和数据可以通过内部 NVM 寄存器或易失性寄存器自动完成,一旦检测到崩溃,这些寄存器或易失性寄存器将被复制到内部 NVM 寄存器中。

2.3 动机

既然我们现在了解了保证安全元数据崩溃一致性的问题,那么现在让我们讨论一下确保这种一致性对 NVMM 性能的影响。 如前所述,安全持久系统将在每次内存写入操作中持久保存对 BMT、加密计数器、数据和 MAC 的任何更改。 当这些操作以原子方式执行时,将导致显着的减速。

图 4 描述了使用严格的持久安全性时的相对系统吞吐量。 如图所示,大多数工作负载由于额外写入操作的影响而导致性能严重下降,以确保安全元数据的持久性。 值得注意的是,与不保证此类持久性的系统相比,某些工作负载的速度可以降低多达 9.4 倍。 持久安全元数据的影响主要取决于正在运行的应用程序的内存行为和写入强度。 不幸的是,由于这样的性能开销,许多用户可能会避免启用持久安全性,这会使他们的系统不安全并且可能无法恢复他们的数据。为了解决这个问题,在本文中,我们定义了安全持久系统的要求,并研究了不同方案对系统性能、恢复时间和弹性的影响。 据我们所知,我们的论文是第一个考虑安全持久内存上的所有安全元数据的论文。

3. 设计

在本节中,我们首先分析持久安全系统的要求。 稍后,我们将讨论可用于实现持久安全系统的不同设计选项。 最后,我们讨论了我们提出的结合了几种新颖优化的设计。

3.1 威胁模型

我们假设一个单处理器芯片系统,其中芯片边界形成安全边界。 信任根必须自包含在处理器芯片中,包括默克尔树的任何密钥和根。

我们假设攻击者能够从 NVMM 执行被动读取内存值并监听连接处理器和内存的总线。 我们还假设攻击者能够更改存储在 NVMM 中的值,无论是在计算机系统开机和运行时,还是在电源事件的各个阶段。 攻击者可以通过物理篡改内存(例如使用热风枪或电流)或通过将其从目标系统上卸载并将其安装到不同的系统来实现这一点。 但是,我们的目标是确保内存数据的机密性和完整性,而不是其可用性。 因此,拒绝服务不是本文的重点。

我们还假设整个主内存都受到保护,而不仅仅是安全飞地内的一小部分。 因此,我们的保护目标与 Intel SGX 不同,需要保护整个内存。

3.2 安全持久性的要求

我们的第一个贡献是对安全 NVMM 要求的分析。 NVMM 将被划分为一个持久化区域,该区域承载持久化数据(内存数据结构或文件系统的一部分)和非持久化数据。 安全持久内存的第一个要求是保留数据机密性和完整性的安全保证。 这适用于持久性和非持久性内存区域。 对于计数器模式内存加密,此要求意味着使用计数器模式加密数据,使用 MAC 保护数据,使用盆景默克尔树 (BMT) 保护计数器,其中根永久保存在芯片上。 此外,数据和安全元数据的操作应该是这样的: ① 块的相同计数器值不能在不更改密钥的情况下重复使用, ② BMT 根必须反映内存的最新状态。

第二个要求是数据可恢复性,它适用于持久性和非持久性区域。 持久性区域中的数据应该可以在崩溃和重启后恢复,并且安全元数据(计数器、MAC 和 BMT 节点)应该以能够恢复的方式持久保存。 我们认为,为了支持跨崩溃或重新启动的数据恢复,任何持久化数据还必须保留其最新的安全元数据(计数器、MAC 和 BMT)。 但是,出于不同的原因,需要持续存在不同类型的元数据。 持久化的最新计数器使数据能够被解密为正确的值。 保留的最新 MAC 值允许检测数据篡改。 具体而言,在不保留最新 MAC 值的情况下,攻击者可能会将数据回滚到与陈旧 MAC 匹配的陈旧版本,而不会被检测到。 BMT 还必须反映最新的计数器值,以便检测任何重放旧计数器值的尝试。 但是,我们注意到只有根需要持久化,因为中间 BMT 节点可以重新计算。 因此,持久化数据需要大量成本来确保数据和安全元数据的原子更新。 我们将此要求称为安全元数据的严格持久性。

多次更新(对数据、计数器、MAC 和 BMT)的原子性可以通过事务机制实现,例如硬件日志记录,或者利用内存控制器 (MC) 中的写挂起队列 (WPQ) 的轻量级机制 [32, 18, 33]。 在这项工作中,我们依靠后一种机制以原子方式持久保存数据和安全元数据。

BMT 的分层实现减少了读取操作的验证开销。 如果从内存中读取一个计数器,如果它的父节点已经连续缓存在处理器芯片中,即已经验证过,则无需进一步验证。 类似地,如果它的祖父节点存在但它的直接父节点不存在,那么只需要从内存中获取直接父节点并针对祖父节点进行验证,同时针对获取的父节点验证计数器/叶节点。 在最坏的情况下,当在芯片上没有找到计数器的祖先节点时,必须获取所有节点,并且必须从叶到根进行完整性验证。 然而,考虑到大多数应用程序的空间局部性,它们很少需要访问超过几个级别的祖先。

如果主存储器是易失性的,那么写操作的开销也很低。 当计数器值被更新时,它的父节点也被更新(如果在芯片上),但所有后续的祖先节点都不需要。 如果稍后从缓存中驱逐父节点,则在驱逐父节点之前更新祖父节点(如果在芯片上)。 因此,基于 BMT 节点的驱逐,BMT 修改缓慢地从叶到根传播。 然而,对于 NVMM,这种延迟更新违反了可恢复性,因为当断电时,中间 BMT 节点的值在反映到根之前就会丢失,从而导致根失效。 陈旧的 BMT 根阻止验证计数器完整性,并可能允许计数器重放攻击未被检测到。 因此,在 NVMM 中,必须以不同的方式处理写操作。 当一个计数器被更新时,在严格的持久性下,它的所有祖先必须一直更新到 BMT 的根。 这是昂贵的。 由于 NVM 预计具有巨大的容量,例如数十 TB,因此预计 Merkle 树的高度为数十级,这将需要更新数十个祖先节点块。 稍后,我们将提出一个优化来加速 BMT 的非持久区域部分。

NVMM 的非持久性区域的数据可恢复性有不同的要求。 非持久性数据在崩溃/重启后不需要恢复。 因此,对写入 NVMM 应用严格的持久性并不重要。 我们可以让 NVMM 写入数据、计数器、MAC 和 BMT 节点异步发生(没有原子性)。 在崩溃/重启之后,我们可以假设数据被丢弃并且所有安全元数据都将被重建。 然而,这引入了一个新的困境。 由于 NVMM 中的数据和安全元数据不匹配,在崩溃/重启后处理器对数据的第一次访问很可能会触发完整性验证失败。 为了避免这种情况,我们可以将非持久内存区域的初始化合并到启动过程中,并在此期间重建所有安全元数据。 然而,NVMM 预计具有巨大的容量 (TB),启动过程可能需要不可接受的延迟。

这将我们带到了快速持久性和恢复的最后一个要求。 持久性不应显着减慢执行速度。 同时,崩溃/重启后的恢复应该相对较快,即使对于非持久内存区域也是如此。 在接下来的部分中,我们将讨论我们对刚才讨论的基本安全持久内存设计的性能优化,我们将其统称为 Triad-NVMM。

3.3 Triad-NVM设计

3.3.1 持久和非持久区域

在当前系统中,在启动时,内核会使用一个值进行初始化,该值决定了内存地址的哪个范围被认为是持久的。 这样的区域可以格式化并挂载为文件系统,例如 ext4 文件系统。 此外,这种持久性区域可以由持久性 API 使用,例如 PMDK,它将通过持久性区域中的文件备份持久性数据结构。 持久区域中的任何文件都可以进行内存映射,并通过加载/存储指令进行访问。 同时,无法保证NVM设备中的非持久化区域崩溃后的可恢复性; 应用程序只能在恢复后访问持久化区域中持久化的数据。 图 5 描绘了在 NVM 设备中具有持久性和非持久性区域的加密计数器的系统。 请注意,持久性和非持久性内存区域之间的这种区别对于如何处理安全元数据至关重要,因为这些区域具有不同的数据恢复要求。

我们注意到先前的工作将持久性模型暴露给硬件,以放松数据及其计数器的持久性。 例如,数据和计数器仅在纪元或事务边界持久化。 这种方法的代价是必须有一种架构机制来将高级编程语言构造(内存持久性)与曾经对软件透明的低级安全元数据机制联系起来。 虽然我们选择了不同的方法,但我们注意到它与我们的工作是正交的,如果需要,可以添加到我们的机制中。

正如持久性和非持久性区域的计数器是分开的一样,保护数据的 MAC 也是分开的。持久区域的安全元数据(计数器和 MAC)在区域本身中分配,而非持久区域的安全元数据(计数器和 MAC)在非持久区域中分配。通过这种方式,它们可以单独通过它们的地址进行处理和处理。

尽管 BMT 涵盖了所有加密计数器,无论它们的持久性要求如何,但并非 BMT 的所有部分都需要持久化。 具体来说,鉴于当前系统在启动时定义了 NVM 的持久区域,内存中有一个范围可以保证不用于持久数据。 基于这样的观察,BMT 可以分为两种不同的方式。 划分BMT的一种方法是仍然使用单个BMT但将其拆分为多个子树,即某些部分仅覆盖主内存的前4GB,因此仅需要严格持久化persistent-region子树。 如图 6 所示。

如图 6 所示,当持久内存位置发生更新时,BMT 中所有级别的该位置的所有相应部分都应更新到根(处理器芯片内部)。 对持久数据的 BMT 更新应持久更新以下内容(在内存或内部 NVM 寄存器中)和缓存(如果可缓存)① Merkle 树的根;② 拥有更新计数器的根的子节点,以及所有其他中间 对应于更新的计数器的节点(如 ② 和 ③ )。 最后,如在 ④ 中,计数器同时保留在内存和计数器缓存中。 然而,对于非持久性数据,更新缓存中的 BMT 中间节点和计数器并在它们自然地从缓存中被逐出时懒惰地将它们写回内存就足够了。 显然,属于持久区域的子树应该是可分离的,即根的某些部分仅属于持久区域,而其他部分仅属于非持久区域。 让某些部分同时属于两者是具有挑战性的,并且在恢复时可能会导致无法验证的部分; 该部分将反映两种类型数据的最新值,但由于中间节点和非持久数据计数器的更新丢失,我们将无法重现根。 对于持久性和非持久性数据,唯一在同一块上具有 MAC 值的级别是根,但是,它们显然是可分离的。 为了避免 BMT 节点同时覆盖两种数据的情况,persistent 和persistent-data 的内存空间比应该是 0:8, 1:7, 2:6, 3:5, 4:4, 5:3, 6:2、7:1 或 8:0。 换句话说,根中的每个 MAC 值应涵盖持久性或非持久性数据,但不能同时涵盖两者。 请注意,根保存在处理器中的持久寄存器中,因此不需要在内存中更新。

另一种为持久和非持久区域拆分 BMT 的方法是拥有两个完全独立的BMT,它们具有不同的根。使用单独的 BMT,无需担心必须在持久性和非持久性区域之间保持固定的容量比率。 此外,这允许持久区域 BMT 存储在持久区域本身中。同样,非持久化区域BMT也可以存储在非持久化区域中。这使其与两个区域的计数器和 MAC 的分离保持一致,并允许安全引擎根据其物理地址对安全元数据进行不同的处理。因此,我们选择了这种方法。

3.3.2 放宽加密计数器持久性

正如我们现在了解操作系统将如何利用未来的 NVM 设备一样,现在让我们讨论如何根据区域的持久性来区别对待加密计数器。 虽然出于正确性和安全性原因必须正确恢复持久性数据的加密计数器,但可以放宽非持久性数据的加密计数器确保恢复后的正确性。 如前所述,对于非持久性数据,我们可以放宽对数据和安全元数据的严格持久性,这将提高访问此类数据的性能。

但是请注意,尽管不需要数据恢复,但非持久性区域安全性具有不同于易失性内存的独特漏洞。特别是,计数器重放可以跨引导情节执行,而不仅仅是在引导情节内。放松非持久性数据的安全元数据的严格持久性会引入跨引导计数器重用的安全漏洞。为了说明这一点,请考虑已持久化但其对应的计数器值尚未持久化的数据。如果此时断电,最近的计数器值将丢失,并且我们在 NVMM 中留下一个陈旧的计数器值。在重新启动时,从内存中读取过时的计数器值,因此发生了计数器重用。这违反了计数器模式加密的安全要求。为了避免在启动过程中重复使用计数器,我们研究了两种方案。第一种方案依赖于使用两种不同的密钥:持久性密钥和易失性密钥。 持久密钥用于加密/解密持久数据区域,而易失密钥用于非持久数据。易失性密钥在重新启动时更改,这避免了计数器重用,即使我们放宽了非持久性数据的加密计数器的严格持久性。我们的设计只需要修改内存控制器,使其能够接收来自内核的命令,该命令将持久区域的开始和结束地址通知给 MC,并使用这些信息来决定使用哪个密钥。 此外,内核需要通过内存映射寄存器向内存控制器发送命令,以在恢复或重启时更改易失性密钥。

另一种方案是使用单个密钥,但除了 IV 的其他组件(主要和次要计数器、页面 ID、页面偏移量等)之外,还向加密 IV 添加会话计数器。 持久性数据使用session 0,因为它需要在重新启动后保持数据恢复,但非持久性数据使用非零会话计数器,该计数器在每次启动时递增。 会话计数器方法降低了必须生成和管理多个安全密钥的复杂性,因为只能使用一个密钥。 然而,更重要的是,它将允许我们为下一个会话预先计算 BMT 根,以实现 BMT 的快速恢复(这将在后面讨论)。 当前会话计数器值必须与 BMT 根一起永久保存在芯片上。 由于它的优点,我们选择了这种方法。

3.3.3 放宽merkle树持久性

正如我们在前一部分关于如何将 BMT 垂直划分为持久性和非持久性子树的讨论,我们现在将讨论哪些级别的 Merkle Tree 需要更新以及可能的松弛方案的影响。

与加密计数器不同,BMT 中间节点如果丢失可以重建,它们的主要用途是加快验证和更新 BMT 的根。 然而,如果加密计数器被保证严格持久和最新,那么在崩溃之后有可能重建所有级别的中间节点,一直到需要匹配处理器中的根值的根。 虽然这看起来是一种直接的优化,但它实际上可能会造成单点故障; 如果任何计数器已损坏,例如由于内存错误,我们只能知道 Merkle 树根不匹配,因此没有任何内存是可完整性验证的。 虽然 Merkle 树根可以保存 64B 而不是仅 8B 值,但不可纠正的计数器错误仍会导致八分之一的内存丢失/无法验证。 由于预计 NVM 将包含数 TB 的数据,因此任何计数器的不可纠正错误可能导致大部分内存无法验证的可能性是不可接受的。 此外,由于需要遍历所有加密计数器以重建所有级别的 Merkle 树,因此仅保证加密的持久性将需要很长的恢复时间。

为了在保持恢复时间可控的同时实现识别不可验证位置的高分辨率,我们建议保留 Merkle 树的前N个级别(从叶向上),同时可选地在处理器内维护多个 NVM 寄存器。 N 的值取决于可接受的性能/恢复时间权衡。 保持低级别的 Merkle 树可以帮助隔离问题并识别哪些计数器已损坏/无法纠正。 此外,保证持久性的级别数越多,重建默克尔树的恢复时间就越短。 另请注意,由于更高级别的 Merkle Tree 具有更少的中间节点,因此将它们持久化可以减少由于不可纠正的错误而无法构建 Merkle Tree 的机会。

3.3.4 非持久区域崩溃恢复

对于重启后恢复,必须再次重建 BMT 才能验证任何篡改。 在恢复过程中,在承认系统的当前状态为已验证之前,需要通过重构默克尔树的相应部分并验证其生成正确的根来验证所有持久位置。 这确保了数据从(或之前)崩溃时间到恢复时间都没有被篡改。 但是,对于非持久化数据位置,虽然我们不需要在恢复时验证数据的完整性,但我们需要能够在恢复后对其进行验证。 回想一下 NVMM 中数据和安全元数据不匹配的困境,即在崩溃/重启触发完整性验证失败后处理器首次访问数据时,即使我们不希望恢复数据或安全元数据。 为了避免这种情况,我们可以通过将所有非持久内存区域清零来将非持久内存区域的初始化合并到启动过程中,并在此期间重建所有安全元数据,包括增加会话计数器、清零所有其他计数器、重新计算所有 MAC ,并重建 BMT。 然而,NVMM 预计具有巨大的容量 (TB),启动过程可能需要不可接受的延迟。 为了更好地理解开销,让我们假设一个 6TB 的 NVM,其中 50% 用作非持久性数据,即普通内存。 在恢复时,如果读取每个数据块并初始化它需要 100ns,那么仅在 3TB(非持久区域)上迭代将需要 5154 秒(近 85.9 分钟)。 这与持久数据区域(另一个 3TB)形成鲜明对比,其中 BMT 的低级节点以及数据和计数器都被严格持久化。 因此,只需要重建默克尔树的上层。 例如,如果只有默克尔树的第一级(计数器块的父级),读取每个块并计算其 MAC 值需要 100 纳秒,那么这将只需要 92 秒(1.5 分钟)。 因此,我们希望显着加快非持久区域的重启过程。

为了避免重建计数器和非持久区域的默克尔树部分的意外长恢复时间,我们提出了一种延迟恢复方法。 由于计数器和数据块的数量在较低级别中最大,并且它们消耗了大部分重建时间,因此我们可以按如下方式延迟更新它们。 通过用零初始化第 1 层的所有中间节点(计数器块的父节点),并依次构造所有上层,我们可以获得非持久数据的初始根值(或根的一部分)。 稍后,对任何计数器值的任何更新,如果父中间节点的值为零,我们不会标记错误或篡改,因为 Merkle 树(和根)的上层已经更新以反映该值,但是,我们知道 这是恢复后对计数器块的第一次写入,因此我们将计数器值清零(或初始化)并相应地更新父节点。 请注意,由于每个计数器块的 MAC 值存储在 64B 父节点的 8 个字节中,因此只有父节点中对应的 8B 会指示它是否是恢复后的第一次更新。 虽然计数器块值自然会导致 64 位零 MAC 值的几率仅为2的64次方分之一 ,但为了避免错误地假设初始化的计数器值,如果计数器块的 MAC 值自然为 0,我们会增加其次要值之一 计数器,重新加密对应于该计数器的缓存行,并计算其新的 MAC 值,如果不等于零,它将在父节点中使用。 通过非持久化数据和计数器块的延迟更新,我们确保恢复过程只需要迭代级别 1 或 2 而不是所有相应的数据和计数器块。

3.3.5 总体设计

图 7 描述了 Triad-NVM 设计。 如前所述,写挂起队列(WPQ)被认为是现代处理器中持久域(电源故障保护域)的一部分[34]。 因此,到达那里的任何东西都应该是一致的,或者有一种方法可以确保其一致性。 为此,每个写操作,在被持久化(从易失性缓冲区中删除)之前,它会将其所有相应的更新(计数器、数据、MT 节点和根)记录到处理器内部的持久性寄存器中,然后设置一个持久性位(称为 READY_BIT) . 如果在将持久寄存器中的更新复制到 WPQ 时发生崩溃,那么当系统恢复时,内存控制器将再次尝试将持久寄存器写入 NVM(或 WPQ)。 在将内容从寄存器复制到 WPQ 时,Triad-NVM 有选择地选择是将计数器或默克尔树节点复制到 WPQ 还是在缓存中更新它们就足够了(如步骤 8 和 9 所示)。 请注意,一旦脏块从这些缓存中被逐出,它将像往常一样进入 WPQ。 持久性寄存器可以实现为快速 NVM 寄存器或易失性寄存器将通过利用 ADR 或剩余功率在发生崩溃时刷新到较慢的 NVM 寄存器。 持久寄存器的数量取决于 Triad-NVM 模型,例如,如果使用 TriadNVM-2,那么我们只需要 5 个寄存器,而如果我们使用不切实际的严格持久性,那么我们可能需要多达 15 个寄存器。 请注意,在最先进的工作中也假设使用持久寄存器 [19]。

如果更新后的加密计数器对应一个持久内存区域,则会严格更新(复制到 WPQ)。 但是,对于 Merkle Tree,如果更新的部分属于持久内存区域,并且级别高于持久级别,那么更新将被持久化到 NVM(复制到 WPQ)。 请注意,持久级别是保证严格持久化的默克尔树的最高级别,例如,如果这样的级别为 2,则每次更新后都保证计数器、它们的父母和祖父母都被持久化。 请注意,TriadNVM 恢复过程就像在持久级别的中间笔记上迭代并构建持久内存区域的上层一样简单,但是,对于非持久内存,另外将此类级别的中间节点初始化为零 在构建树的上层之前的区域。

4. 方法

5. 评估

6. 相关工作

直到最近很少研究持久性安全元数据。Liu 等人的近期工作[18] 指出需要原子地持久化数据和计数器来实现崩溃一致性。 他们提出了严格的持久性,以及一种优化,其中数据和计数器仅在纪元或事务边界以原子方式持久化。 原子性机制利用 ADR 平台功能,该功能要求内存控制器的写入挂起队列 (WPQ) 位于非易失性域中。 左等人[20] 通过将单个计数器块上不同计数器的多个更新组合/合并到单个内存写入中,添加了写减少优化。Ye等人最近的另一项研究[19] 建议重新利用纠错码 (ECC) 来对加密计数器进行完整性检查。 通过这样做,可以放松加密计数器的严格持久性; 可以通过尝试多个连续值直到发生 ECC 匹配来恢复计数器值。 我们在论文中假设了严格的反持久性,但请注意,上面讨论的技术 [18-20] 是正交的,在我们的案例中也可以应用于减少 NVMM 写入。Triad-NVM 的一项并发工作是 Anubis [36]。Anubis 通过持续跟踪元数据缓存中的地址来解决安全 NVM 中的恢复时间问题。Triad-NVM 处理具有持久性和非持久性区域的弹性、性能、恢复系统,而 Anubis 则专注于减少恢复时间。Anubis 实现了更好的恢复时间,但在某些计数器损坏时可能会引入单点故障。 另一方面,Anubis 解决了恢复可并行化 Merkle 树的问题,例如 Intel 的 SGX 中的那些。

上面讨论的先前研究与我们的工作之间的一个显着区别是,虽然它们提供了数据可恢复性,但它们忽略了分别通过消息身份验证代码 (MAC) 和Bonsai Merkle树 (BMT) 对数据和计数器的完整性保护。 任何计数器模式加密技术的安全性都取决于避免通过 BMT 提供的计数器重用 [21]。 因此,在这些研究中,没有保留安全保证,因为系统容易受到直接篡改数据和计数器重放攻击的影响。 罗杰斯等人解决了在共享多处理器系统中实现完整性验证和加密的问题。 类似的工作还通过为处理器-处理器通信和一致性消息提供更有效的保护来解决共享多处理器系统的问题。据我们所知,我们的工作是第一个采用整体方法包括所有安全元数据并讨论与它们的持久性、性能、弹性和恢复时间有关的问题。 此外,我们研究的独特之处在于调查了必须如何区别对待持久性和非持久性内存区域。

根据所需的软件和硬件更改,NVMM 中的持久数据具有不同的模型。为了将数据保存在 NVMM 中并利用操作系统对 PMEM 的支持,例如英特尔 PMDK,已经开发了多个 API 和库。 在本文中,我们的支持重点是在写入 NVMM 时将伴随持久数据的安全元数据持久化,因此我们不需要在应用程序或库级别进行任何更改,因此 Triad-NVM 可以与大多数持久性模型集成。

最后,其他旨在减少 NVMM 写入的研究,并未考虑持久化安全元数据的问题。

7. 总结

在本文中,我们提出了 Triad-NVM,一种提供安全持久内存的架构,我们首次讨论了如何为持久和非持久内存提供数据和安全元数据(计数器、MAC 和默克尔树)的持久性。 非易失性主内存的持久内存区域。 我们全面探索了持久性、性能、弹性和恢复时间等问题,并展示了我们提出的优化如何影响上述问题。 我们的评估结果表明,与严格持久化相比,Triad-NVM 将吞吐量提高了大约 2 倍,同时为 8TB NVMM 系统实现了不到 4 秒的恢复时间,这比没有安全元数据持久化的系统小三个数量级以上。