缓存攻击原理

信息安全 定时攻击 缓存 侧信道
2021-08-17 19:25:43

有许多处理缓存攻击的科学出版物。最近,发布了 CacheBleed 攻击,该攻击利用英特尔 Sandy Bridge 架构上的缓存库冲突。大多数定时攻击使用类似的方法:

  1. 攻击者用他控制的相同随机数据填充缓存。
  2. 攻击者在他的受害者进行一些计算(例如加密)时等待。
  3. 攻击者继续执行并测量加载他在步骤 1 中写入缓存的每组数据的时间。如果受害者访问了一些缓存集,它将驱逐攻击者的一些行,攻击者观察到内存增加这些线路的访问延迟。

通过这样做,攻击者可以找出受害者访问了哪些缓存集,甚至是哪些缓存行。

我读过的大多数论文都会自动得出结论,攻击者有可能推断出写入这些缓存位置的数据(例如安全私钥)。这是我不明白的:

如果我知道受害者 V 访问了某个缓存位置,我如何获取他的数据?许多内存地址映射到相同的缓存位置,即使我有完整的内存地址,我也怀疑攻击者可以执行 DMA。

作为参考,您可以参考最近发布的CacheBleed攻击。

2个回答

显然,这个话题引起了你们许多人的极大兴趣。在做了更多的研究之后,我上个月向一群科学家展示了 CacheBleed 攻击。现在,我想与您分享我的结果并实际回答我自己的问题。

上述通用 Prime+Probe 攻击的三个步骤是正确的。但是,缺少决定性的步骤,即如何推导出密钥。攻击者无法执行 DMA,也无法读取缓存行中保存的数据。理解这一点非常重要,否则整个攻击会容易得多。

攻击者仅通过测量时间延迟知道访问了哪个缓存行。此外,他知道 RSA 是如何实现的,以及使用了哪些算法。OpenSSL 使用固定窗口求幂算法来计算消息m

m = c^d mod p

我们需要了解这种求幂算法是如何工作的。Menezes、van Oorschot 和 Vanstone的应用密码学手册建议使用以下伪代码:

固定指数求幂算法

请不要混淆上述算法中的密钥d和指数e因为我们只对解密步骤感兴趣,e所以不是公钥而是秘密。因此d = e在我们的案例中。有趣的一点是 中的乘法3.2它使用预先计算的乘法器g_j,实际上加速了幂运算。但是,它们的选择取决于密钥。

如果攻击者知道当前乘数的索引,即使用什么乘数,他就知道了密钥的一些位。乘数并不重要

OpenSSL 使用所谓的scatter-gather 技术来避免对缓存行粒度的缓存攻击。乘数的存储位置是可预测的。总共有 32 个乘法器。出于这个原因,每个都需要 5 位来唯一标识。两个最高有效位选择高速缓存行,而三个最低有效位标识 bin。每个高速缓存行由八个 bin 组成。

攻击者能够推断出在解密操作期间访问了哪些 bin。这揭示了所用乘数的索引的三位,因此部分是私钥。由于 RSA 密钥中的冗余,可以计算丢失的两位。

综上所述,没有执行 DMA,攻击者没有从缓存中读取数据。关键因素是缓存位置部分暴露了密钥。这是由于秘密相关的内存访问。对 AES 的类似攻击也利用了缓存位置。实际数据并不重要,但该位置揭示了合理的数据。

这种攻击类似于 Flush+Reload 攻击,但是您的攻击使用缓存填充而不是刷新来强制缓存驱逐。

请参阅本文的第 3 部分和第 4 部分: https ://eprint.iacr.org/2013/448.pdf

基本上,由于模幂运算的工作原理,通过了解内存中每次访问私钥之间的时间,您可以推断出密钥。

两次访问之间的长时间延迟意味着乘法是 1。

两次访问之间的短暂延迟意味着二进制移位为 0。

然后你把它们全部加起来,你就有了一个非常接近的密钥表示。多次尝试并添加一些统计魔法,最终你会得到关键。

如果有人想进一步粗俗化这篇论文,请随时编辑此答案。