Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
170 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.o | ||
spy | ||
victim | ||
*~ | ||
core | ||
calibration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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). | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
all: calibration | ||
calibration: calibration.c ../cacheutils.h | ||
gcc -std=gnu11 -O2 -o $@ $@.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |