Skip to content

Commit

Permalink
add calibration utility
Browse files Browse the repository at this point in the history
  • Loading branch information
dgruss committed May 12, 2015
1 parent baa55a3 commit 575817c
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .gitignore
@@ -0,0 +1,6 @@
*.o
spy
victim
*~
core
calibration
24 changes: 22 additions & 2 deletions README.md
@@ -1,2 +1,22 @@
# cache_template_attacks
This repository contains several tools to perform Cache Template Attacks
# Cache Template Attacks
This repository contains several tools to perform Cache Template Attacks.

Cache Template Attacks are a new generic attack technique, allowing to profile and exploit cache-based information leakage of any program automatically, without prior knowledge of specific software versions or even specific system information.

The underlying cache attack used in this repository is Flush+Reload as presented by Yarom and Falkner in "[FLUSH+RELOAD: a High Resolution, Low Noise, L3 Cache Side-Channel Attack](https://eprint.iacr.org/2013/448.pdf)" (2014).

# Getting started: Calibration
Before starting the Cache Template Attack you have to find the cache hit/miss threshold of your system.

Use the calibration tool for this purpose:
```
cd calibration
make
./calibration
```
This program should print a histogram for cache hits and cache misses. Based on the histogram it suggests a suitable threshold value (this value is also returned by the program).

# Getting started: Keypresses
It is helpful to start with well observable events like key strokes and an application which is known to process such events (for instance an editor).


56 changes: 56 additions & 0 deletions cacheutils.h
@@ -0,0 +1,56 @@
#ifndef CACHEUTILS_H
#define CACHEUTILS_H

#ifndef HIDEMINMAX
#define MAX(X,Y) (((X) > (Y)) ? (X) : (Y))
#define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
#endif

uint64_t rdtsc_nofence() {
uint64_t a, d;
asm volatile ("rdtsc" : "=a" (a), "=d" (d));
a = (d<<32) | a;
return a;
}

uint64_t rdtsc() {
uint64_t a, d;
asm volatile ("mfence");
asm volatile ("rdtsc" : "=a" (a), "=d" (d));
a = (d<<32) | a;
asm volatile ("mfence");
return a;
}

void maccess(void* p)
{
asm volatile ("movq (%0), %%rax\n"
:
: "c" (p)
: "rax");
}

void flush(void* p) {
asm volatile ("clflush 0(%0)\n"
:
: "c" (p)
: "rax");
}

void prefetch(void* p)
{
asm volatile ("prefetcht1 %0" : : "m" (p));
}

void longnop()
{
asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
"nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
}
#endif
3 changes: 3 additions & 0 deletions calibration/Makefile
@@ -0,0 +1,3 @@
all: calibration
calibration: calibration.c ../cacheutils.h
gcc -std=gnu11 -O2 -o $@ $@.c
83 changes: 83 additions & 0 deletions calibration/calibration.c
@@ -0,0 +1,83 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sched.h>
#include "../cacheutils.h"

size_t array[5*1024];

size_t hit_histogram[80];
size_t miss_histogram[80];

size_t onlyreload(void* addr)
{
size_t time = rdtsc();
maccess(addr);
size_t delta = rdtsc() - time;
return delta;
}

size_t flushandreload(void* addr)
{
size_t time = rdtsc();
maccess(addr);
size_t delta = rdtsc() - time;
flush(addr);
return delta;
}

int main(int argc, char** argv)
{
memset(array,-1,5*1024*sizeof(size_t));
maccess(array + 2*1024);
sched_yield();
for (int i = 0; i < 4*1024*1024; ++i)
{
size_t d = onlyreload(array+2*1024);
hit_histogram[MIN(79,d/5)]++;
sched_yield();
}
flush(array+1024);
for (int i = 0; i < 4*1024*1024; ++i)
{
size_t d = flushandreload(array+2*1024);
miss_histogram[MIN(79,d/5)]++;
sched_yield();
}
printf(".\n");
size_t hit_max = 0;
size_t hit_max_i = 0;
size_t miss_min_i = 0;
for (int i = 0; i < 80; ++i)
{
printf("%3d: %10zu %10zu\n",i*5,hit_histogram[i],miss_histogram[i]);
if (hit_max < hit_histogram[i])
{
hit_max = hit_histogram[i];
hit_max_i = i;
}
if (miss_histogram[i] > 3 && miss_min_i == 0)
miss_min_i = i;
}
if (miss_min_i > hit_max_i+4)
printf("Flush+Reload possible!\n");
else if (miss_min_i > hit_max_i+2)
printf("Flush+Reload probably possible!\n");
else if (miss_min_i < hit_max_i+2)
printf("Flush+Reload maybe not possible!\n");
else
printf("Flush+Reload not possible!\n");
size_t min = -1UL;
size_t min_i = 0;
for (int i = hit_max_i; i < miss_min_i; ++i)
{
if (min > (hit_histogram[i] + miss_histogram[i]))
{
min = hit_histogram[i] + miss_histogram[i];
min_i = i;
}
}
printf("The lower the threshold, the lower the number of false positives.\n");
printf("Suggested cache hit/miss threshold: %zu\n",min_i * 5);
return min_i * 5;
}

0 comments on commit 575817c

Please sign in to comment.