内存依赖推测是否阻止BN_consttime_swap成为常数时间? 上下文

内存依赖推测是否阻止BN_consttime_swap成为常数时间? 上下文,c,assembly,openssl,constant-time,micro-architecture,C,Assembly,Openssl,Constant Time,Micro Architecture,OpenSSL中的BN\u consttime\u swap是一件美妙的事情。在此代码段中,条件已计算为0或(BN_ULONG)-1: #define BN_CONSTTIME_SWAP(ind) \ do { \ t = (a->d[ind] ^ b->d[ind]) & condition; \ a->d[ind] ^= t; \ b->d[ind] ^= t; \ } w

OpenSSL中的
BN\u consttime\u swap
是一件美妙的事情。在此代码段中,
条件
已计算为
0
(BN_ULONG)-1

#define BN_CONSTTIME_SWAP(ind) \
    do { \
            t = (a->d[ind] ^ b->d[ind]) & condition; \
            a->d[ind] ^= t; \
            b->d[ind] ^= t; \
    } while (0)
…
    BN_CONSTTIME_SWAP(9);
…
    BN_CONSTTIME_SWAP(8);
…
    BN_CONSTTIME_SWAP(7);
其目的是为了确保更高级别的bignum操作占用恒定的时间,此函数要么交换两个bignum,要么将它们保留在恒定的时间内。当它保留它们时,它实际上读取每个bignum的每个单词,计算一个与旧单词相同的新词,并将结果写回原始位置

这样做的目的是,这将需要相同的时间,就好像这些大人物已经被有效地交换了一样

在这个问题上,我假设一个现代的,广泛的建筑,比如阿格纳·福格在他的书中描述的那些。还假定将C代码直接转换为程序集(无需C编译器撤销程序员的工作)

问题: 我试图理解上述结构是以“尽力而为”的恒定时间执行,还是完美的恒定时间执行为特征。

特别是,我关注这样一种情况:调用函数
BN\u consttime\u swap
时,bignum
a
已经在一级数据缓存中,并且函数返回后的代码立即开始处理bignum
a
。在现代处理器上,当使用bignum
a
时,可以同时执行足够多的指令,使拷贝在技术上不会完成。调用
BN\u consttime\u swap
后,允许指令在
a
上工作的机制是内存依赖推测。为了论证起见,让我们假设一下

问题似乎归结为:

当处理器最终检测到从内存中读取的与推测相反已写入函数内部的代码
BN_consttime_swap
后,它是否会在检测到已写入地址后立即取消推测执行,或者,当检测到已写入的值与已写入的值相同时,它是否允许自己保留该值?

在第一种情况下,
BN\u consttime\u swap
似乎实现了完美的恒定时间。在第二种情况下,这只是最大努力的恒定时间:如果没有交换bignum,则调用
BN\u consttime\u swap
后的代码执行速度将明显快于交换它们时的速度

即使在第二种情况下,在可预见的将来(只要处理器仍然足够幼稚),也可以通过在再次写入旧值或新值之前,为两个bignum中的每个字写入一个不同于两个可能最终值的值来解决这个问题。有时可能需要使用
volatile
类型限定符,以防止普通编译器过度优化序列,但听起来还是有可能的

注意:我知道,但商店转发只是一种快捷方式。它不会阻止在写入之前执行读取。在某些情况下,它会失败,尽管在这种情况下,人们不会期望它会失败

还假定将C代码直接转换为程序集(无需C编译器撤销程序员的工作)

我知道这不是你问题的重点,我知道你知道这一点,但我需要大声说一分钟。这甚至不符合提供恒定时间执行的“尽力”尝试。编译器被授权检查
条件
的值,如果
条件
为零,则跳过整个过程。模糊设置
条件
会降低这种情况发生的可能性,但这并不能保证

据称“常量时间”代码不应该用C语言编写,句号为。即使今天是固定时间,在您测试的编译器上,一个更智能的编译器也会出现并击败您。您的一个用户将在您使用此编译器之前使用此编译器,并且他们不会意识到您使他们面临的风险。我知道有三种方法可以实现恒定时间:专用硬件、汇编或生成机器代码的DSL加上恒定时间执行的证明



抛开Rant不谈,谈谈手头上的实际体系结构问题:假设是一个愚蠢幼稚的编译器,这段代码在时间上是恒定的,我非常熟悉,可以用它来评估这个问题,我希望它大体上是正确的,原因很简单:power。我希望检查存储队列或缓存中存储的值是否与已经存在的值匹配,并有条件地短路存储或避免弄脏每个存储上的缓存线,这比避免某些工作的罕见情况下节省的能量要多。但是,我不是CPU设计师,也不想代表他们发言,所以请在假设这是真的之前先咨询一个问题。恒定时间实现背后的思想不是在恒定时间内实际执行所有操作。这在一个无序的体系结构上永远不会发生。 要求通过定时分析不能泄露任何秘密信息。 为了防止这种情况,基本上有两个要求:

a) 不要将任何秘密用作循环的停止条件或分支的谓词。否则将使您面临分支预测攻击

b) 不要使用任何机密作为内存访问的索引。这会导致缓存定时攻击

至于你的代码:假设你的秘密是“条件”,可能是a和b的内容,那么代码的执行时间是完全恒定的,从这个意义上说,它的执行不会被破坏