Merge branch 'master' into debugger_dev

This commit is contained in:
Michael Scire 2018-12-07 14:55:28 -08:00
commit aca8f53050
4 changed files with 85 additions and 41 deletions

View file

@ -33,7 +33,7 @@ static const uint8_t g_seal_key_sources[CRYPTOUSECASE_MAX_5X][0x10] = {
{0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D}, {0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D},
{0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE}, {0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE},
{0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9}, {0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9},
{0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9} {0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE6, 0xD8, 0x9A, 0xCF, 0xE5, 0x3F, 0xB3, 0x4B}
}; };
bool usecase_is_invalid(unsigned int usecase) { bool usecase_is_invalid(unsigned int usecase) {

View file

@ -15,6 +15,7 @@
*/ */
#include "car.h" #include "car.h"
#include "timers.h"
#include "utils.h" #include "utils.h"
static inline uint32_t get_clk_source_reg(CarDevice dev) { static inline uint32_t get_clk_source_reg(CarDevice dev) {
@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
void clkrst_reboot(CarDevice dev) { void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev); clkrst_disable(dev);
if (dev == CARDEVICE_KFUSE) {
/* Workaround for KFUSE clock. */
clk_enable(dev);
udelay(100);
rst_disable(dev);
udelay(200);
} else {
clkrst_enable(dev); clkrst_enable(dev);
}
} }
void clkrst_enable_fuse_regs(bool enable) { void clkrst_enable_fuse_regs(bool enable) {

View file

@ -15,6 +15,7 @@
*/ */
#include "car.h" #include "car.h"
#include "timers.h"
#include "utils.h" #include "utils.h"
static inline uint32_t get_clk_source_reg(CarDevice dev) { static inline uint32_t get_clk_source_reg(CarDevice dev) {
@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
void clkrst_reboot(CarDevice dev) { void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev); clkrst_disable(dev);
if (dev == CARDEVICE_KFUSE) {
/* Workaround for KFUSE clock. */
clk_enable(dev);
udelay(100);
rst_disable(dev);
udelay(200);
} else {
clkrst_enable(dev); clkrst_enable(dev);
}
} }
void clkrst_enable_fuse_regs(bool enable) { void clkrst_enable_fuse_regs(bool enable) {

View file

@ -20,6 +20,8 @@
#include "timers.h" #include "timers.h"
#include "tsec.h" #include "tsec.h"
#define TSEC_KEYGEN_MAX_RETRIES 25
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR; void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
static void safe_memcpy(void *dst, void *src, uint32_t sz) { static void safe_memcpy(void *dst, void *src, uint32_t sz) {
@ -168,14 +170,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
/* Copy package1 into IRAM. */ /* Copy package1 into IRAM. */
memcpy((void *)0x40010000, package1, package1_size); memcpy((void *)0x40010000, package1, package1_size);
/* Load the TSEC firmware from IRAM. */
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
}
/* Disable the aperture since it has precedence over the SMMU. */
mc_disable_ahb_redirect();
/* Setup TSEC's address space. */ /* Setup TSEC's address space. */
uint32_t *pdir = smmu_setup_tsec_as(1); uint32_t *pdir = smmu_setup_tsec_as(1);
@ -189,6 +183,45 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
volatile uint32_t *iram_pages = smmu_alloc_page(48); volatile uint32_t *iram_pages = smmu_alloc_page(48);
volatile uint32_t *expv_page = smmu_alloc_page(1); volatile uint32_t *expv_page = smmu_alloc_page(1);
/* Map all necessary pages. */
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x7000E000, (uint32_t)pmc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x60007000, (uint32_t)flow_page, 1, _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70012000, (uint32_t)se_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70019000, (uint32_t)mc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x40010000, (uint32_t)iram_pages, 48, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x6000F000, (uint32_t)expv_page, 1, _READABLE | _WRITABLE | _NONSECURE);
/* Enable the SMMU. */
smmu_enable();
/* Loop retrying TSEC firmware execution, in case we lose the SE keydata race. */
uint32_t key_buf[0x20/4] = {0};
unsigned int retries = 0;
while (true) {
if (retries++ > TSEC_KEYGEN_MAX_RETRIES) {
fatal_error("[SMMU] TSEC key generation race was lost too many times!");
}
/* Load the TSEC firmware from IRAM. */
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
}
/* Disable the aperture since it has precedence over the SMMU. */
mc_disable_ahb_redirect();
/* Clear all pages. */
memset((void *)car_page, 0, SMMU_PAGE_SIZE);
memset((void *)fuse_page, 0, SMMU_PAGE_SIZE);
memset((void *)pmc_page, 0, SMMU_PAGE_SIZE);
memset((void *)flow_page, 0, SMMU_PAGE_SIZE);
memset((void *)se_page, 0, SMMU_PAGE_SIZE);
memset((void *)mc_page, 0, SMMU_PAGE_SIZE);
memset((void *)iram_pages, 0, 48 * SMMU_PAGE_SIZE);
memset((void *)expv_page, 0, SMMU_PAGE_SIZE);
/* Copy CAR, MC and FUSE. */ /* Copy CAR, MC and FUSE. */
safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000); safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000);
safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000); safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000);
@ -204,35 +237,31 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
mc_page[0x65C/4] = 0; mc_page[0x65C/4] = 0;
mc_page[0x660/4] = 0x80000000; mc_page[0x660/4] = 0x80000000;
/* Map all necessary pages. */
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x7000E000, (uint32_t)pmc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x60007000, (uint32_t)flow_page, 1, _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70012000, (uint32_t)se_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70019000, (uint32_t)mc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x40010000, (uint32_t)iram_pages, 48, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x6000F000, (uint32_t)expv_page, 1, _READABLE | _WRITABLE | _NONSECURE);
/* Enable the SMMU. */
smmu_enable();
/* Run the TSEC firmware. */ /* Run the TSEC firmware. */
tsec_run_fw(); tsec_run_fw();
/* Extract the keys from SE. */ /* Extract the keys from SE. */
uint32_t key_buf[0x20/4] = {0};
volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320); volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320);
uint32_t old_key_data = *key_data; uint32_t old_key_data = *key_data;
uint32_t buf_counter = 0; uint32_t buf_counter = 0;
while (!(tsec->FALCON_CPUCTL & 0x10)) { while (!(tsec->FALCON_CPUCTL & 0x10)) {
if (*key_data != old_key_data) { const uint32_t new_key_data = *key_data;
old_key_data = *key_data; if (new_key_data != old_key_data) {
key_buf[buf_counter] = *key_data; old_key_data = new_key_data;
key_buf[buf_counter] = new_key_data;
buf_counter++; buf_counter++;
} }
} }
/* Enable back the aperture. */
mc_enable_ahb_redirect();
if (buf_counter == 8) {
break;
}
}
/* Check if the TSEC firmware wrote over the exception vectors. */ /* Check if the TSEC firmware wrote over the exception vectors. */
volatile uint32_t *tsec_done_check = (volatile uint32_t *)((void *)expv_page + 0x200); volatile uint32_t *tsec_done_check = (volatile uint32_t *)((void *)expv_page + 0x200);
if (!(*tsec_done_check)) { if (!(*tsec_done_check)) {
@ -248,9 +277,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
/* Clear TSEC's address space. */ /* Clear TSEC's address space. */
smmu_clear_tsec_as(1); smmu_clear_tsec_as(1);
/* Enable back the aperture. */
mc_enable_ahb_redirect();
/* Return the decrypted package1 from emulated IRAM. */ /* Return the decrypted package1 from emulated IRAM. */
memcpy(package1_dec, (void *)iram_pages, package1_size); memcpy(package1_dec, (void *)iram_pages, package1_size);