0.论文介绍
论文标题: "GoFetch: Breaking Constant-Time Cryptographic Implementations Using Data Memory-Dependent Prefetchers"
作者: Boru Chen, Yingchen Wang, Pradyumna Shome, Christopher W. Fletcher, David Kohlbrenner, Riccardo Paccagnella, Daniel Genkin
发表会议: USENIX Security Symposium
发表年份: 2024USENIX Security Symposium 该论文研究了数据内存依赖预取器(DMP)攻击如何破坏常时间密码实现。通过开发GoFetch工具,作者展示了DMP如何在现代处理器(如苹果M系列芯片)上执行端到端的密钥提取攻击。实验结果表明,这种攻击可以有效地绕过现有的侧信道防御措施,并揭示了DMP对高价值软件构成的严重安全威胁。论文还提出了若干反制措施,以应对这种新型攻击。
1.摘要
微架构侧信道攻击已经动摇了现代处理器设计的基础。防御这些攻击的关键策略是确保安全关键程序不使用依赖于秘密数据的地址。简单来说,就是不要将秘密数据作为地址传递给数据内存指令。然而,数据内存依赖预取器(DMPs)的发现——它们在内存系统内部直接将程序数据转换为地址——使这一防御方法的安全性受到质疑。
本文指出,DMPs带来的安全威胁远比之前认为的要严重得多,并展示了利用苹果M系列DMP对安全关键软件进行的首个端到端攻击。本文展示攻击基于对DMP行为的新理解,表明苹果DMP会在任何受害者程序的代表下激活,并尝试“泄露”任何看起来像指针的缓存数据。基于这种理解,本文设计了一种新的选择输入攻击,利用DMP对一些流行的常数时间实现的经典(如OpenSSL Diffie-Hellman密钥交换、Go RSA解密)和后量子密码学算法(如CRYSTALS-Kyber和CRYSTALS-Dilithium)进行端到端密钥提取。
2.引言
过去十多年里,现代处理器面临了多种微架构侧信道攻击,例如通过缓存、TLBs、分支预测器、片上互连、内存管理单元、推测执行、电压频率调节等进行的攻击。
这些攻击中最突出的一类是程序的内存访问模式依赖于秘密数据时发生的攻击。例如,当程序的数据内存访问模式依赖于秘密数据时,就会发生缓存和TLB侧信道攻击。其他攻击,例如监控片上互连的攻击,可以类比于程序的指令内存访问模式。这导致了各种防御措施的发展——包括广泛使用的常数时间编程模型、基于信息流的跟踪等——所有这些措施都旨在防止秘密数据被用作内存/控制流指令的地址。
然而,最近Augury展示了苹果M系列CPU通过引入数据内存依赖预取器(DMP)破坏了这种编程模型。DMP会尝试预取程序内存内容中发现的地址。因此,理论上,苹果的DMP可以通过缓存侧信道泄露内存内容,即使这些内存从未作为地址传递给内存/控制流指令。
尽管苹果DMP具有泄露信息的能力,但其限制性的行为阻止了其在攻击中的应用。特别是,DMP仅在存在一种相当特殊的程序内存访问模式时激活(即程序通过一个指针数组进行流式访问并架构性地解引用这些指针)。这种访问模式通常不会出现在侧信道加固的常数时间代码等安全关键软件中——因此使这些代码免受DMP泄露的影响。由于DMP的安全影响因子尚不明确,本文将探讨以下问题:
DMP是否对软件构成严重安全威胁?攻击是否可以利用DMP绕过常数时间编程等侧信道防御?
1.1 我们的贡献
本文肯定地回答了上述问题,展示了苹果的DMP实现如何对常数时间编码范式构成严重威胁。本文展示了对四种最先进的加密实现进行端到端密钥提取攻击,这些实现都采用了常数时间编程。
分析DMP激活模式
本文首先重新审视了Augury的发现,发现其对DMP激活模型的分析条件限制严格,忽略了几种DMP激活的场景。通过新的逆向工程,我们发现DMP可以代表任何程序激活,并尝试引用任何被缓存且看起来像指针的数据。这种行为将大量程序数据置于风险之中,消除了之前研究中报告的限制。最后,除了苹果,我们还确认在英特尔最新的第13代(Raptor Lake)架构中存在类似的DMP,其激活标准更加严格。
破解常数时间加密
接下来,我们展示了如何利用DMP攻击破解安全关键的软件。我们展示了在最先进的常数时间加密软件中广泛存在易受DMP辅助攻击的代码,这些软件涵盖了从经典到后量子密钥交换和签名算法。虽然DMP只解引用指针,但攻击者可以精心构造程序输入,使这些输入与加密秘密混合后,只有在秘密满足攻击者选择的条件时,生成的中间状态才看起来像指针。例如,假设程序有一个秘密,接受输入并计算然后存储到其程序内存中。攻击者可以构造不同的,通过观察DMP是否能够解引用来推断的部分(甚至全部)信息。我们首先利用这一观察打破了推荐用于加密实现的标准常数时间交换原语的保障。然后,展示了如何破解设计为抵御选择输入攻击的完整加密实现。 本文贡献如下:
逆向工程苹果和英特尔DMPs:
逆向工程了苹果CPU中的DMP,发现了新的激活标准。
开发DMP利用技术:
基于对DMP的新理解,开发了一种新的与受害者无关的选择输入攻击及相关攻击原语,不需要攻击者与受害者共享内存。我们使用这些原语对常数时间交换操作进行了概念验证攻击。
破解常数时间加密:
基于选择输入攻击框架,开发了对经典加密(OpenSSL Diffie-Hellman密钥交换和Go RSA解密)和后量子加密(CRYSTALS-Kyber和CRYSTALS-Dilithium)的常数时间实现的端到端密钥提取攻击。
2. 背景
缓存架构
现代处理器使用多级缓存来减少内存访问延迟。通常,高级缓存较小且访问速度快,而低级缓存较大但访问速度慢。例如,本文研究的苹果处理器有两级缓存:一个核心私有的L1缓存和一个共享的L2缓存。缓存是组相联的,每个缓存组可以容纳固定数量的缓存行。我们的实验主要在苹果M1的4个Firestorm核心上进行,每个Firestorm核心有128 KB的8路组相联L1数据缓存,这些核心共享一个12 MB的12路组相联L2数据缓存。
缓存侧信道攻击
缓存侧信道攻击通过观察受害者程序对缓存的秘密依赖访问的副作用来推断受害者的秘密。这些攻击通常包括三个步骤:攻击者将缓存置于已知状态,让受害者执行程序,然后检查缓存状态以获取受害者的执行信息。常见的攻击技术有Flush+Reload和Prime+Probe。
经典预取器
预取器是一种硬件优化,用于隐藏内存访问延迟。它们通过在核心请求数据之前将数据预加载到缓存中来工作。经典预取器根据程序的内存访问模式预测下一个访问的地址。
经典预取器的安全隐患
先前的研究表明,经典预取器可能会导致安全隐患。受害者程序与预取器的非预期交互可以创建缓存状态变化,攻击者可以通过测量这些变化泄露信息。然而,这些泄露仅限于受害者的访问模式,可以通过常数时间编程来缓解。
数据内存依赖预取器(DMPs)
DMPs是一类预取器,用于预取不规则内存访问模式。与经典预取器不同,DMPs不仅考虑内存访问模式,还直接考虑数据内存的内容来决定预取的内容。
DMP的安全隐患
Vicarte等人首次分析了DMP的安全隐患,发现间接内存预取器可能用于泄露程序的整个内存,类似于Spectre攻击。最近,Augury展示了苹果处理器中的一种DMP,即指针数组DMP。这种DMP的行为将在论文中进一步详细描述。
3.威胁模型与设置
3.1威胁模型
在本文中,我们假设一个典型的微架构攻击场景,其中受害者和攻击者在同一台机器上运行不同的进程。
软件方面:对于我们的加密攻击,我们假设攻击者运行的是非特权代码,能够通过正常的软件接口与受害者交互,触发受害者执行私钥操作。我们假设受害者使用的是常数时间软件,不存在已知的微架构侧信道泄漏。最后,我们假设攻击者和受害者不共享内存,但攻击者可以监控其可用的任何微架构侧信道(例如,缓存延迟)。由于我们测试的是非特权代码,因此我们只考虑macOS常见分配给用户空间(EL0)程序的内存地址。
硬件方面:除非特别说明,否则我们主要关注苹果硬件。基于M1的实验在运行macOS 13.5的苹果M1 Mac Mini上进行。对于我们对M2/M3微架构的研究,我们使用了运行macOS 14.2.1的苹果M2 Mac Mini和运行macOS 14.2的苹果M3 MacBook Pro。最后,在研究英特尔DMP实现时,我们使用了运行Ubuntu 23.04,内核版本为6.2.0的英特尔Core i9-13900K(Raptor Lake)CPU。
3.2设置
实验平台:
苹果M1和M2/M3设备分别运行不同版本的macOS,用于实验。英特尔设备运行Ubuntu系统。
目标软件:
我们的攻击目标是加密软件,假设攻击者运行非特权代码,可以通过软件接口与受害者交互,并监控微架构侧信道。
DMP行为分析:
我们通过逆向工程分析DMP行为,发现DMP在任何程序中都可能激活,并尝试解引用任何类似指针的缓存数据。这种行为使大量程序数据面临风险。
攻击目标
经典密码学:
我们展示了如何利用DMP攻击来破解安全关键的软件。我们展示了在现代常数时间加密软件中存在广泛易受DMP辅助攻击的代码,包括经典和后量子密钥交换和签名算法。
选择输入攻击:
攻击者可以精心构造程序输入,使这些输入与加密秘密混合后,生成的中间状态只有在秘密满足攻击者选择的条件时才会看起来像指针。通过观察DMP是否能够解引用这些状态,攻击者可以推断出部分或全部秘密信息。
这幅图片比较了Augury的研究结果和本文工作的不同之处,特别是关于数据内存依赖预取器(DMP)如何解引用内存数据的场景。图片中的不同部分和箭头解释如下:
Augury的工作:
红色箭头(Dereferenced by code):表示代码中直接解引用的指针。
绿色虚线箭头(Dereferenced by DMP):表示由DMP解引用的指针。
在Augury的工作中,代码依次解引用ptr[0]、ptr[1]、ptr[2]等指针。这些指针会被流预取器(stream prefetcher)预取到缓存中。DMP则解引用这些被预取的指针数据。
本文工作(第一种情况):
这一行展示了一种新的场景,其中使用了虚拟指针(dummy pointers)来混淆DMP。dummy指针不会被代码直接解引用,但DMP会尝试解引用其中的ptr[N]和ptr[M-1]。
本文工作(第二种情况):
这一行展示了DMP解引用指针数组的场景。这里代码不会直接解引用这些指针,但DMP会依次解引用ptr[0]、ptr[1]、ptr[2]等指针。
本文工作(第三种情况):
这一行展示了缓存行内数据的加载情况。ptr[1]和ptr[7]等指针在同一个缓存行中一起加载。即使代码只访问了一个指针,DMP仍会解引用同一缓存行中的其他指针数据。
这幅图表明,本文通过不同的方法展示了DMP的更广泛的激活场景和潜在的安全威胁,这些场景在之前的研究中没有被充分认识到。
这部分内容为本文的威胁模型和实验设置,展示了我们的攻击方法和实验平台的详细信息。
DMP激活模式 数据内存依赖预取器(DMP)的激活模式是指DMP在何种情况下会启动并尝试预取内存数据的条件和行为。根据论文中的描述,DMP的激活模式有以下几种情况:
按照指针数组解引用 在这种模式下,DMP会尝试预取指针数组中的数据,即使这些数据并未被代码实际解引用。这意味着DMP会扫描内存中类似指针的数据并进行预取操作。 示例:ptr[0]、ptr[1]、ptr[2]等指针,DMP会自动解引用这些指针并预取相应的数据。
存在虚拟指针 在一些情况下,代码中会存在虚拟指针(dummy pointers),这些指针并不实际指向有效数据。然而,DMP仍会尝试解引用这些虚拟指针,从而带来潜在的安全风险。 示例:使用虚拟指针(dummy pointers)替代部分实际指针,DMP会尝试解引用这些虚拟指针。
缓存行内解引用 当多个指针位于同一个缓存行内,即使代码只访问了其中一个指针,DMP仍会尝试解引用该缓存行内的所有指针数据。这种行为增加了DMP对内存数据的预取范围和影响。
4微结构特性
4.1 重新审视DMP数据访问模式
在这一部分,论文详细探讨了数据内存依赖预取器(DMP)的数据访问模式,并通过实验和代码分析揭示了其行为特性。
DMP的基本行为:
通过逆向工程,我们发现DMP会尝试解引用任何被缓存并看起来像指针的数据。当L1缓存被填充时,DMP会扫描其中的数据,如果检测到指针,且指针的目标地址不在历史过滤器中且缓存行没有“禁止扫描”标记,则DMP会解引用这些指针。 这种行为大大增加了程序数据被DMP解引用的可能性,带来了更高的安全风险。
实验设计与结果:
为了验证DMP的行为,我们设计了一系列实验。以下是一个典型的实验代码示例:
// 声明一个大小为 M 的指针数组 aop
uint64_t* aop[M];
// 假设填充了 aop 数组的每个元素(具体填充步骤在论文中未展示)
// 遍历指针数组 aop,并解引用每个指针
for (int i = 0; i < N; i++) {
*aop[i % N]; // 解引用指针数组中的元素。i % N 确保索引在 0 到 N-1 之间循环
}
// 测量测试地址的延迟
该代码段展示了遍历一个包含指针的数组,并对每个指针进行解引用的操作。即使在不进行架构性解引用的情况下,DMP仍会预取这些指针。
实验结果分析:
实验结果表明,当遍历包含指针的数组时,即使不进行架构上的指针解引用,DMP仍会激活并预取这些指针。 以下是实验结果的部分数据生成的四张图表,展示了数据内存依赖预取器(DMP)在不同场景下的激活模式和预取行为。每个图表分别显示了不同测试索引下,含指针和不含指针情况下的访问延迟(以周期为单位)。
图(a) Row 1:遍历指针数组(AoP)并进行解引用;预取越界指针
说明:这张图展示了遍历指针数组并对每个指针进行解引用的场景。
实验:
在含指针和不含指针的情况下,分别测量访问延迟。 结果显示,含指针情况下的访问延迟显著低于不含指针的情况,表示DMP成功预取了这些指针。
结论:DMP在遍历并解引用指针数组时会预取越界指针,从而减少访问延迟。
图(b) Row 2:遍历指针数组但不进行解引用;预取越界指针 说明:这张图展示了遍历指针数组但不对指针进行解引用的场景。
实验: 在含指针和不含指针的情况下,分别测量访问延迟。 结果显示,即使不进行解引用,DMP仍会预取这些指针,含指针情况下的访问延迟显著降低。
结论:DMP在遍历指针数组时会预取越界指针,即使不进行解引用。
图(c) Row 3:遍历指针数组但不进行解引用;预取范围内指针
说明:这张图展示了遍历指针数组但不进行解引用,且指针在预取范围内的场景。
实验: 在含指针和不含指针的情况下,分别测量访问延迟。 结果显示,DMP在遍历指针数组时会预取范围内的指针,含指针情况下的访问延迟降低。
结论:DMP在遍历指针数组时会预取范围内的指针,即使不进行解引用。
图(d) Row 4:一次加载指针数组;预取同一缓存行中的指针 说明:这张图展示了仅一次加载指针数组,预取同一缓存行中的指针的场景。
实验:
在含指针和不含指针的情况下,分别测量访问延迟。 结果显示,即使只进行一次加载,DMP也会预取同一缓存行中的所有指针,含指针情况下的访问延迟降低。 结论:DMP在进行一次加载时会预取同一缓存行中的所有指针,从而减少访问延迟。
综合结论 通过这四张图表,可以看出DMP在不同访问模式下的广泛激活行为,包括解引用和非解引用场景,以及预取越界和范围内指针的能力。这些实验结果表明,DMP能够显著减少访问延迟,但也带来了潜在的安全隐患,因为它可能泄露敏感信息。
与之前研究的对比:
之前的研究(例如Augury)认为DMP的激活条件较为严格,认为需要特定的程序访问模式。然而,我们的研究发现,DMP在更多场景下都可能激活,包括非架构性解引用和跨缓存行解引用。
安全影响:
DMP的这种行为对常数时间加密实现构成了严重威胁。由于DMP会解引用看起来像指针的所有数据,即使在没有架构性解引用的情况下,DMP仍可能通过预取操作泄露敏感信息。 进一步研究还发现,类似的DMP存在于英特尔第13代(Raptor Lake)架构中,尽管其激活条件更为严格。这表明DMP可能在多种处理器架构中广泛存在,带来普遍的安全隐患。
4.2 DMP激活条件
在4.2节中,论文详细讨论了数据内存依赖预取器(DMP)的激活条件。通过逆向工程和实验,作者们发现了多种影响DMP激活的因素和模式。以下是对该部分的总结:
4.2.1. 基本激活条件
DMP的基本激活条件包括:
缓存中的数据模式:
DMP会扫描缓存中的数据,并尝试解引用任何看起来像指针的内容。特别是,如果数据包含可以被解引用的地址,则DMP会激活并尝试预取这些地址指向的数据。
历史过滤器和扫描标记:
如果指针的目标地址不在DMP的历史过滤器中,并且缓存行没有“禁止扫描”标记,DMP就会解引用这些指针。
4.2.2. 实验和结果
实验设计展示了DMP的激活行为,特别是在以下情况下的激活模式:
越界指针:
当程序遍历指针数组并解引用越界指针时,DMP会尝试预取这些指针。即使这些指针在程序逻辑中不被解引用,DMP也会激活并进行预取操作。
非解引用模式:
在一些实验中,即使程序不解引用指针,DMP也会激活并预取这些数据。这表明DMP在数据访问模式中的作用比预期的更广泛。
4.2.3. 影响DMP激活的其他因素
缓存级别:
DMP在L1缓存填充时扫描数据,并在特定情况下激活。这意味着DMP的行为与缓存层级密切相关。
内存对齐和地址过滤:
DMP的扫描范围限定在4GB对齐的区域内,并忽略地址的高8位。这种设计使得DMP在特定的内存布局中更容易激活。
4.3.4. 安全影响
由于DMP的广泛激活条件,它可能会在未预期的情况下泄露敏感信息。特别是对于使用常数时间编程的安全关键应用,DMP的行为可能导致意外的信息泄露。
这张图展示了数据内存依赖预取器(DMP)的成功激活率在不同位置偏移下的表现。
图表布局:
图表分为上下两个部分,每个部分展示了不同位置偏移下的成功率。
X轴(Position Offset):
表示位置偏移,从0到15的范围。
Y轴(Success Rate %):
表示成功率,百分比形式,从0%到100%。
上部图表:
成功率几乎为100%且一致,这表明在这些位置偏移下,DMP能够非常稳定地成功激活。
下部图表:
成功率也接近100%,但从位置偏移8开始有一个显著的变化。这可能表示某种内存对齐或缓存行为影响了DMP的激活。 图表展示了不同测试索引下的访问延迟,其中含指针和不含指针的访问延迟数据对比明显。含指针情况下的延迟显著降低,表明DMP成功预取这些指针。
4.3 Dereferenced Pointers的限制
在4.3节中,论文详细讨论了对解引用指针的限制条件。通过逆向工程和实验,作者们发现了多种影响解引用指针行为的因素。
4.3.1. 访问控制
访问控制机制:
解引用指针的操作受到严格的访问控制机制的限制。具体来说,如果指针指向的地址不在允许访问的内存范围内,解引用操作将会失败。
缓存级别和内存对齐:
解引用指针的行为与缓存级别和内存对齐密切相关。如果指针指向的地址不符合缓存级别的内存对齐要求,解引用操作将会失败。
4.3.2. 实验和结果
实验设计展示了解引用指针操作在不同条件下的行为:
缓存命中和未命中:
当指针指向的地址在缓存中时,解引用操作成功率较高;而当指针指向的地址不在缓存中时,解引用操作成功率较低。
地址过滤和历史记录:
DMP会根据地址过滤和历史记录来决定是否解引用指针。如果指针指向的地址在历史记录中多次出现,解引用操作将会成功;反之,则可能失败。
4.3.3. 安全影响
由于解引用指针行为的复杂性和多样性,这种操作可能带来潜在的安全隐患。特别是在使用常数时间编程的安全关键应用中,解引用指针操作可能导致意外的信息泄露。
4.4DMP行为模型
现在我们总结前两个小节并进行一些新的观察 。 步骤 1: 观察缓存行数据。如果行未标记为“不扫描”提示(即,自进入缓存以来,该行尚未被扫描;第 4.2 节),则当该行已填充到 L1 时,DMP 会扫描该行中的数据。DMP 通过检查缓存行中每个指针大小对齐的块(前 64 位、后 64 位等)来执行扫描。
步骤 2:地址检查。接下来,DMP 对每个块(候选指针)应用额外的检查和过滤,以查看是否应取消引用它。位 [63:56] 被忽略(第 4.3 节)。此外,根据第 4.3 节,存储指针(其位置)的缓存行必须与指针指向的缓存行(其目标)位于相同的 4 GByte(log2 4 GByte = 32 位)对齐区域中。换句话说,DMP 检查候选指针的位 [55:32] 是否与目标缓存行地址的相应位匹配。最后,DMP 检查候选指针是否存在于历史过滤器中(第 4.2 节)。如果位 [55:32] 匹配且指针不在历史过滤器中,则 DMP 尝试预取两个 L2 行。具体而言,它首先预取 64 位块所针对的缓存行,忽略顶部字节值。接下来,它触发 CPU 的下一行预取器并将相邻的缓存行也提取到 CPU 的 L2 缓存中(第 4.3 节)。然后将两个预取地址插入到历史过滤器中。 作为预取过程的一部分,DMP 查找转换后备缓冲区 (TLB) 并触发页表遍历以获取与每个候选指针对应的物理地址(即虚拟地址 [33])。在 TLB 未命中时,DMP 将缺失的转换插入 TLB。
4.5 其他微架构
在这一节中,作者讨论了除了Apple M系列处理器之外,其他微体系结构中数据内存依赖预取器(DMP)的行为和影响。通过比较不同处理器的设计和DMP实现,作者展示了DMP在不同平台上的一致性和差异性。
4.5.1. Intel处理器
通过对Intel处理器的研究,作者发现:
DMP的存在:最新的Intel处理器(如Raptor Lake架构)中也存在类似的DMP机制。这些DMP同样试图预取指针指向的数据,以提高缓存命中率。
激活条件:与Apple的DMP相比,Intel的DMP激活条件更加严格,需要特定的内存访问模式才能触发。 性能影响:尽管激活条件更加严格,Intel的DMP在提高程序性能方面仍然表现出色,特别是在高性能计算任务中。
4.5.2. ARM架构
在ARM处理器中,DMP的设计和实现也有一些独特之处:
轻量级设计:ARM的DMP设计更加轻量级,旨在尽可能减少硬件资源的消耗。
安全考虑:ARM在DMP的设计中加入了更多的安全考虑,以防止潜在的信息泄露。
4.5.3. 其他处理器
对于其他处理器(如AMD和IBM的处理器),作者发现:
多样化实现:不同厂商在DMP的实现上有很大的差异。这些差异主要体现在DMP的激活条件、预取策略和安全措施上。
一致性问题:尽管存在这些差异,DMP在不同处理器上的基本行为模式是一致的,都是通过预取指针指向的数据来提高缓存命中率。
实验和结果
作者通过一系列实验对不同处理器上的DMP行为进行了验证:
实验设计:
实验包括在不同的内存访问模式和缓存配置下测试DMP的激活和预取行为。
实验结果:
实验结果表明,不同处理器上的DMP在识别和解引用指针方面表现出高度的准确性和一致性。
安全影响
尽管DMP在提高程序性能方面表现优异,但其在不同处理器上的实现也揭示了潜在的安全风险:
信息泄露:由于DMP会预取并解引用指针,它可能在处理敏感数据时泄露这些数据。
攻击向量:恶意程序可以利用DMP的预测和预取机制,推测出其他程序的内存访问模式,从而获取敏感信息。
Apple M2:
在不包含指针的情况下,访问延迟大约在550个周期左右。 在包含指针的情况下,访问延迟显著降低至250个周期左右。 误差线显示在所有行访问条件下延迟的一致性。
Intel Raptor Lake:
在不包含指针的情况下,访问延迟在不同行访问条件下波动较大,从350到500个周期不等。 在包含指针的情况下,访问延迟显著降低,但变化幅度不如Apple M2显著。 误差线显示在不同行访问条件下延迟的波动性更大。
通过对不同微体系结构中DMP的研究,作者揭示了DMP在现代处理器中的广泛应用及其对程序性能和安全的影响。尽管DMP在提高缓存命中率和减少内存访问延迟方面有显著优势,但其在不同处理器上的实现也带来了潜在的安全隐患。未来的工作需要进一步研究和开发相应的防御措施,以应对DMP带来的安全威胁。
5.攻击常数时间条件交换
这一部分详细讨论了利用数据内存依赖预取器(DMP)来攻击常数时间条件交换操作的方法和实验结果。
5.1 攻击概述与挑战
攻击概述
攻击目标:常数时间编程模型用于防止通过时间测量泄露秘密信息。条件交换操作是其中常见的一部分,其形式为 if (cond) { swap(a, b); }。在常数时间条件交换中,无论条件是否成立,交换操作都应该在所有情况下花费相同的时间。
攻击方法:利用DMP的行为,通过测量访问延迟,推测条件交换的执行路径。DMP会尝试预取指针指向的内存地址,如果攻击者能够控制输入数据,使得在某些条件下DMP会预取特定的内存地址,便可以通过延迟测量判断条件是否成立。
攻击挑战
精确控制输入:攻击者需要设计精确的输入数据,使得DMP能够识别并预取特定的内存地址。
延迟测量准确性:攻击成功依赖于精确的延迟测量,需要足够的分辨率来区分DMP是否预取了目标地址。
5.2 复合逐出集合构建
逐出集合概述
逐出集合是指能够完全填满缓存一个集合的地址集合。在攻击中,通过逐出集合可以确保DMP在预取特定地址时不会受到干扰。复合逐出集合的构建用于增加攻击的有效性和稳定性。
逐出集合构建方法
测量访问延迟:通过测量访问不同地址的延迟,识别潜在的逐出集合。具体步骤如下:
访问不同的内存地址,记录每次访问的延迟时间。
分析延迟数据,识别出能够显著增加延迟的地址集合。
验证逐出集合:通过实验验证逐出集合的有效性,确保其能够成功触发DMP的预取机制。
构建复合逐出集合,并反复测试其在不同内存访问模式下的行为。
确认逐出集合在攻击目标环境中能够稳定地触发DMP的预取行为。
5.3 概念验证结果
实验设计
为了验证攻击的可行性和有效性,作者设计了一系列实验,包括条件交换实验和逐出集合测试。
条件交换实验:
在不同条件下执行条件交换操作,通过延迟测量分析DMP的预取行为。
使用精确控制的输入数据,使得DMP在特定条件下预取目标地址。
逐出集合测试:
构建并测试复合逐出集合,验证其在触发DMP预取方面的有效性。
通过测量不同逐出集合的访问延迟,优化攻击策略。
实验结果
延迟测量:
在特定条件下,访问延迟显著降低,表明DMP成功预取了目标地址。
延迟测量结果显示,当条件成立时,DMP能够更有效地预取数据,从而导致访问延迟减少。
攻击成功率:
分析延迟测量结果,成功推测出条件交换的执行路径,从而破坏常数时间编程模型。
实验结果表明,利用复合逐出集合的攻击方法在不同条件下均具有较高的成功率。
这一部分详细介绍了利用DMP攻击常数时间条件交换的方法。通过构建复合逐出集合和精确测量访问延迟,攻击者可以成功推测出条件交换的执行路径,破坏常数时间编程模型的安全性。这一结果强调了需要进一步研究和开发防御措施,以应对DMP带来的安全威胁。
6.攻击传统密码学
在这一章中,作者探讨了如何利用数据内存依赖预取器(DMP)来攻击传统密码学算法,具体分析了Go的RSA加密和OpenSSL的Diffie-Hellman密钥交换。
6.1 Go的RSA加密
攻击概述
RSA加密:RSA是一种广泛使用的公钥加密算法,其安全性基于大整数因数分解的难度。
攻击目标:通过DMP攻击,提取RSA密钥或解密过程中使用的敏感数据。
攻击方法
触发DMP预取:在RSA加密过程中,构造特定的输入数据,使DMP预取关键的内存地址。
延迟测量:测量不同地址的访问延迟,通过分析延迟变化,推测出RSA密钥或其他敏感数据。
实验和结果
实验设计:在Go的RSA实现中,执行一系列加密操作,记录内存访问延迟。
实验结果:结果表明,通过延迟测量,可以成功推测出RSA密钥或解密过程中使用的部分关键数据。
6.2 OpenSSL的Diffie-Hellman密钥交换
攻击概述
Diffie-Hellman密钥交换:Diffie-Hellman是一个允许两个参与者在不安全信道上建立共享秘密的算法,其安全性基于离散对数问题的难度。
攻击目标:利用DMP攻击,推测出参与密钥交换的秘密参数。
攻击方法
触发DMP预取:在Diffie-Hellman密钥交换过程中,构造特定的输入数据,使DMP预取涉及到的内存地址。
延迟测量:通过测量访问延迟,推测出参与密钥交换的秘密参数。
实验和结果
实验设计:在OpenSSL的Diffie-Hellman实现中,执行一系列密钥交换操作,记录内存访问延迟。
实验结果:实验结果表明,通过延迟测量,可以成功推测出参与密钥交换的部分秘密参数。
作者展示了如何利用DMP攻击来破坏传统密码学算法的安全性。通过精确控制输入数据和测量内存访问延迟,攻击者可以推测出RSA加密和Diffie-Hellman密钥交换过程中使用的敏感数据。这些结果强调了在设计和实现密码学算法时,需要考虑DMP带来的潜在安全威胁,并开发相应的防御措施以保障系统的安全性。
6.3数学公式概念说明
6.3.1RSA算法简介
RSA加密算法包括三个主要步骤:密钥生成、加密和解密。
密钥生成:
选择两个大素数和。
计算和。
选择一个与互质的整数,作为公钥指数。
计算私钥指数,使得:
加密:
对消息进行加密,得到密文:
解密:
使用私钥指数解密密文,得到明文:
6.3.2DMP攻击公式
攻击者可以通过测量RSA加密或解密过程中的访问延迟,推测出密钥参数。假设攻击者可以构造特定的输入数据,使得DMP预取关键的内存地址,通过延迟测量推测出密钥的部分信息。
公式推导
延迟测量公式:
是参与密钥交换的内存地址。
私钥推测公式: 根据测量的延迟,推测出私钥参数
公式推导过程:
Step1.Diffie-Hellman密钥关系:
在Diffie-Hellman密钥交换算法中,参与者A和B选择私钥和,并计算公共值
Step2.延迟与私钥的关系:
假设通过延迟测量公式
得到了延迟时间。
延迟时间可以用于推测私钥参数
Step3.私钥推测公式:
根据延迟测量值,通过以下公式推测私钥
7.攻击后量子密码学
在这一章中,作者探讨了如何利用数据内存依赖预取器(DMP)来攻击后量子密码学算法,具体分析了Kyber和Dilithium两种后量子密码学方案。
7.1 Kyber
Kyber算法简介
Kyber是一种基于格的后量子密码学方案,用于密钥交换和加密。
Kyber密钥交换流程:
密钥生成:生成公钥和私钥对。
加密:使用公钥加密消息。
解密:使用私钥解密密文。
Kyber的安全性:基于格问题的难度,特别是学习同余问题(Learning With Errors, LWE)。
DMP攻击方法
通过DMP攻击,可以推测出Kyber算法中的密钥信息。
触发DMP预取:在Kyber算法的加密和解密过程中,构造特定的输入数据,使DMP预取关键的内存地址。
延迟测量:测量不同地址的访问延迟,通过分析延迟变化,推测出密钥信息。
实验和结果
实验设计:在Kyber算法的实现中,执行一系列加密和解密操作,记录内存访问延迟。
实验结果:结果表明,通过延迟测量,可以成功推测出Kyber算法的密钥信息。
7.2 Dilithium
Dilithium算法简介
Dilithium是一种基于格的后量子数字签名方案。
Dilithium签名流程:
密钥生成:生成公钥和私钥对。
签名生成:使用私钥对消息生成签名。
签名验证:使用公钥验证签名的有效性。
Dilithium的安全性:基于模块学习同余问题(Module Learning With Errors, MLWE)和短整数解问题(Short Integer Solution, SIS)。
DMP攻击方法
通过DMP攻击,可以推测出Dilithium算法中的私钥信息。
触发DMP预取:在Dilithium算法的签名生成和验证过程中,构造特定的输入数据,使DMP预取关键的内存地址。
延迟测量:测量不同地址的访问延迟,通过分析延迟变化,推测出私钥信息。
实验和结果
实验设计:在Dilithium算法的实现中,执行一系列签名生成和验证操作,记录内存访问延迟。
实验结果:结果表明,通过延迟测量,可以成功推测出Dilithium算法的私钥信息。
在第七章中,作者展示了如何利用DMP攻击来破坏后量子密码学算法的安全性。通过精确控制输入数据和测量内存访问延迟,攻击者可以推测出Kyber和Dilithium算法中的密钥信息。这些结果强调了在设计和实现后量子密码学算法时,需要考虑DMP带来的潜在安全威胁,并开发相应的防御措施以保障系统的安全性。
7.3数学公式概念说明
7.3.1Kyber
Kyber算法简介 Kyber是一种基于格的后量子密码学方案,用于密钥交换和加密。
Kyber密钥交换流程:
密钥生成:生成公钥和私钥对。 加密:使用公钥加密消息。 解密:使用私钥解密密文。 Kyber的安全性:基于格问题的难度,特别是学习同余问题(Learning With Errors, LWE)。
Kyber的数学公式
Step1.密钥生成:
Step2.加密:
Step3.解密:
7.3.2Dilithium算法简介
Dilithium是一种基于格的后量子数字签名方案。
Dilithium签名流程:
密钥生成:生成公钥和私钥对。
签名生成:使用私钥对消息生成签名。
签名验证:使用公钥验证签名的有效性。
Dilithium的安全性:基于模块学习同余问题(Module Learning With Errors, MLWE)和短整数解问题(Short Integer Solution, SIS)。
Dilithium的数学公式
Step1.密钥生成:
Step2:签名生成
Step3.签名认证:
8.反制措施
在第八章中,作者探讨了针对数据内存依赖预取器(DMP)攻击的几种反制措施,以提高后量子密码学算法的安全性。以下是反制措施的详细解释。
8.1 随机化
随机化的概念 随机化是一种通过在算法执行过程中引入随机性来抵抗侧信道攻击的技术。它可以通过随机化内存访问模式、执行顺序等方式,使攻击者难以预测和利用固定的模式进行攻击。
实施方法
内存访问随机化:
随机化访问内存的顺序,使得DMP无法有效预测和预取内存地址。
例如,在加密过程中随机选择访问内存地址的顺序,而不是按固定顺序访问。
执行顺序随机化:
随机化指令执行的顺序,使得攻击者难以通过测量执行时间来推断关键操作。
例如,在解密过程中随机调整指令的执行顺序。
8.2 隐藏内存访问模式
概念
隐藏内存访问模式是一种通过在内存访问过程中引入假访问(dummy accesses)来掩盖真实内存访问模式的方法。这样可以使攻击者难以通过内存访问模式来推测敏感数据。
实施方法
假访问:
在实际内存访问前后插入假访问,干扰DMP的预取逻辑。 例如,在加密过程中插入一些对无关内存地址的访问。
固定访问模式:
使用固定的内存访问模式,无论数据的实际值如何,都采用相同的访问模式。
例如,在解密过程中,总是按固定模式访问内存,而不依赖于密钥值。
8.3 增强硬件支持
概念
增强硬件支持是一种通过改进硬件设计来抵抗DMP攻击的方法。它可以通过在硬件层面引入防护措施,来减少DMP攻击的可能性。
实施方法
硬件随机数生成器:
在硬件中集成高质量的随机数生成器,用于随机化内存访问和执行顺序。
例如,使用硬件随机数生成器来生成加密过程中的随机数。
硬件防护机制:
在硬件中引入专门的防护机制,如内存访问监控和异常检测,来识别和阻止可疑的内存访问模式。
例如,使用硬件防护机制来检测和阻止DMP的预取行为。
通过详细解释和探讨随机化、隐藏内存访问模式以及增强硬件支持等反制措施,可以有效提高后量子密码学算法的安全性。这些反制措施不仅可以抵抗DMP攻击,还可以增强算法在实际应用中的安全性和可靠性。在设计和实现后量子密码学算法时,需要综合考虑这些反制措施,以应对不断发展的攻击技术。
9.结论
作者总结了他们的研究成果,强调了数据内存依赖预取器(DMP)在现代处理器中带来的安全风险,并提出了相应的防御措施。
主要研究成果
DMP攻击的威胁:
研究展示了DMP对高价值软件构成的严重安全威胁。 通过对苹果和英特尔处理器的DMP逆向工程,发现了更多的DMP激活模式,并证实了其能够对安全关键软件进行攻击。
攻击方法:
研究开发了新的DMP利用技术,包括选择输入攻击和相关攻击原语(如驱逐集构建)。
展示了这些技术如何突破现有的侧信道防御措施,如常时间编程模型。
实验证明:
研究进行了概念验证攻击,成功破坏了常时间交换操作和经典及后量子密码学实现。
展示了DMP攻击在破坏密码学安全性方面的有效性。
未来研究方向
扩展DMP攻击范围:
进一步研究其他处理器架构上的DMP实现,以评估其安全风险。 探索更多DMP激活模式和利用技术。
改进防御措施:
发展更强大的防御机制,以抵御DMP攻击。 结合硬件和软件层面的防御技术,构建综合的安全防护体系。
提升密码学实现的安全性:
在设计和实现密码学算法时,综合考虑DMP攻击带来的安全威胁。
开发新的密码学方案,确保在存在DMP攻击的情况下仍能保持安全性。
通过详细的研究和实验证明,作者揭示了DMP对现代处理器和密码学实现构成的严重安全威胁。研究展示了DMP攻击的有效性,并提出了相应的防御措施。未来的研究将继续探索DMP攻击的更多可能性,并发展更强大的防御机制,以保障系统的安全性。
附录1:
Compound Eviction Set Construction
在计算机体系结构中,缓存是提高内存访问速度的关键组件。缓存通常是有限的,因此需要一种机制来决定哪些数据应该被保留,哪些数据应该被逐出。这种机制通常被称为缓存替换策略。逐出集合(Eviction Set)是指一组内存地址,这些地址会映射到缓存中的同一个缓存集合,并且能够完全填满该集合,从而导致缓存中的旧数据被逐出。
1. 缓存概念
缓存层次结构:
现代处理器通常具有多级缓存,如L1、L2和L3缓存。每一级缓存都有不同的大小和速度。
缓存是分块的,每块称为一个缓存行。缓存行的大小通常是固定的,如64字节。
缓存映射:
缓存采用组相联(Set-Associative)映射,每个缓存集合包含若干个缓存行。
地址映射到缓存集合是通过地址中的一部分位(称为索引位)来实现的。
2. 逐出集合
逐出集合定义:
逐出集合是一组内存地址,这些地址映射到缓存中的同一个集合,并且能够完全填满该集合,从而导致之前存储在该集合中的数据被逐出。
逐出集合的重要性:
在侧信道攻击中,攻击者可以利用逐出集合来强制逐出缓存中的特定数据,从而观察缓存命中和未命中带来的时间差异。 在DMP攻击中,逐出集合可以用于触发DMP的预取行为,从而推测程序的执行路径。
3. 复合逐出集合构建
复合逐出集合构建涉及到识别和验证能够有效触发缓存逐出的地址集合。这个过程通常包括以下步骤:
地址选择:
选择一组内存地址,确保这些地址映射到同一个缓存集合。 地址选择可以通过分析地址的索引位来实现。 测量访问延迟:
访问这些内存地址并记录每次访问的延迟时间。 延迟时间可以通过处理器的时间戳计数器(如RDTSC指令)来测量。
验证逐出集合:
通过实验验证这些地址是否能够有效地逐出缓存中的数据。 验证方法包括重复访问这些地址并观察访问延迟的变化。如果访问延迟显著增加,说明这些地址成功逐出了缓存数据。
4.复合逐出集合构建步骤
为了攻击这个常数时间交换函数,我们可以利用数据内存依赖预取器(DMP)和复合逐出集合技术。以下是构建复合逐出集合的步骤和相关代码示例:
步骤1:选择地址 选择一组内存地址,这些地址映射到缓存中的同一个集合。
步骤2:测量访问延迟 通过访问这些地址并测量每次访问的延迟时间,识别出潜在的逐出集合。
步骤3:验证逐出集合 通过实验验证这些地址是否能够有效地逐出缓存中的数据。
#include <stdint.h>
#include <stddef.h>
void ct_swap(uint64_t secret, uint64_t *a, uint64_t *b, size_t len) {
uint64_t delta;
uint64_t mask = ~(secret-1);
for (size_t i = 0; i < len; i++) {
delta = (a[i] ^ b[i]) & mask;
a[i] = a[i] ^ delta;
b[i] = b[i] ^ delta;
}
}
4. 实验示例
以下是一个构建逐出集合的简单示例代码:
import time
import numpy as np
# 初始化一块大内存区域
memory_size = 1024 * 1024 # 1MB
memory = np.zeros(memory_size, dtype=np.uint8)
# 选择一组地址,确保它们映射到同一个缓存集合
# 这里假设缓存行大小为64字节
cache_line_size = 64
num_addresses = 16
addresses = [i * cache_line_size for i in range(num_addresses)]
# 测量访问延迟
def measure_access_time(address):
start_time = time.time()
_ = memory[address]
end_time = time.time()
return (end_time - start_time) * 1e6 # 转换为微秒
# 验证逐出集合
def verify_eviction_set(addresses):
times = [measure_access_time(addr) for addr in addresses]
return times
# 执行验证
access_times = verify_eviction_set(addresses)
for i, time in enumerate(access_times):
print(f"地址 {addresses[i]} 的访问延迟(微秒):{time:.2f} µs")
1.https://www.usenix.org/system/files/sec24fall-prepub-1297-chen-boru.pdf