gpt4 book ai didi

侧信道攻击的 C 时序内存访问

转载 作者:太空宇宙 更新时间:2023-11-04 04:43:18 26 4
gpt4 key购买 nike

我正在学习密码学类(class),我必须做一个关于边信道攻击的演示。因此,我正在尝试自己实现一个。

我特别想关注 this paper .但是,我在使用这种低级编程时遇到了一些问题。

我写了一个简短的 C 程序来计时访问一个变量,以查明它是否被访问过(尽管在这种情况下我是访问它的人,所以我事先知道答案) .然后重点是将其概括为了解其他进程何时达到某个特定状态。

基本上,它运行了 10k 次迭代,并且在每次迭代中以 1/10 的概率访问一个指针。在每次迭代中,处理器访问指针所花费的时间都会被记录下来,然后指针就会从缓存中被清除。这些值被打印到文件中。

下面是我写的代码(汇编部分其实是我引用的论文):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

int probe(char *adrs) {
volatile unsigned long time;

asm __volatile__ (
" mfence \n"
" lfence \n"
" rdtsc \n"
" lfence \n"
" movl %%eax, %%esi \n"
" movl (%1), %%eax \n"
" lfence \n"
" rdtsc \n"
" subl %%esi, %%eax \n"
" clflush 0(%1) \n"
: "=a" (time)
: "c" (adrs)
: "%esi", "%edx");
return time;
}

void myfunc(void* buffer[]) {
int nptrs;

nptrs = backtrace(buffer, 10);
}

int main(int argc, char** argv) {
srand(time(NULL));

int r = rand(), i;
struct timespec tim, tim2;
tim.tv_sec = 0;
tim.tv_nsec = 5000L;
void* buffer[10];
char letter = 'c';
char* p = &letter;

FILE *f = fopen("output.txt","w");
if(f == NULL) printf("Error opening file!\n");

myfunc(buffer);
for(i=0; i < 10000; i++) {
r = rand();
nanosleep(&tim,&tim2);
if(r%10 == 3) { // 3 is completely arbitrary; could be any value really
myfunc(buffer);
printf("%c ",letter);
}
fprintf(f,"%d,%d,%d\n", r%10 == 3, probe(buffer[0]),probe(p)); // print the timings to file, and whether the variable was accessed or not
}

return 0;
}

现在我的问题是:如果 r % 10 == 3,这应该写入带有小 x 和 y 的文件“1,x,y”,否则写入带有大 x 和 y 的“0,x,y” .我尝试在两个运行 Debian(32 位和 64 位)的不同虚拟机上运行它,在这两个虚拟机中都使用 gcc 4.7.2 编译(唯一使用的标志是 -g),但我得到了不同的结果,这些都不是我想要的.

在 32 位 VM 中,“probe(buffer[0])”似乎可以工作,但并非总是如此。但是“probe(p)”总是返回低值(这完全没有给我任何信息)。这是输出的相关部分(完整输出可用 here ):

0,250,48
1,33,54
0,74,33
1,36,33
0,61,33
0,92,33
0,48,62
0,405,33

在 64 位 VM 中,这两个值几乎总是高于 4000,与是否访问指针无关。另一个相关部分(和完整输出 here ):

1,4341,4371
0,4320,4341
0,4495,4320

所以我的问题是:

  • 在 32 位虚拟机中,为什么访问 char* 总是非常快? (void*和char*有区别吗?还是其他原因)
  • 为什么 VM 有不同的结果?
  • 在 64 位 VM 中,为什么两个值都在 4000 左右?

最佳答案

这是一个非常有趣的问题。

char* 和 void* 之间应该没有区别,唯一的区别在于指针算法。但是,我认为您看到的从 32 位到 64 位时代的差异是由于体系结构的变化。 64 位访问内存的速度通常比 32 位慢,但由于有更多的寄存器,它们通常不必访问内存那么多。 Here's a link to info on 64-bit architecture, and the difference from 32-bit.

关于侧信道攻击的 C 时序内存访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23771265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com