mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 13:52:21 +00:00
Merge branch 'master' into debugger_dev
This commit is contained in:
commit
aca8f53050
4 changed files with 85 additions and 41 deletions
|
@ -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},
|
||||
{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},
|
||||
{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) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "car.h"
|
||||
#include "timers.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
|
@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
|
|||
|
||||
void clkrst_reboot(CarDevice 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);
|
||||
}
|
||||
}
|
||||
|
||||
void clkrst_enable_fuse_regs(bool enable) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "car.h"
|
||||
#include "timers.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
|
@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
|
|||
|
||||
void clkrst_reboot(CarDevice 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);
|
||||
}
|
||||
}
|
||||
|
||||
void clkrst_enable_fuse_regs(bool enable) {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "timers.h"
|
||||
#include "tsec.h"
|
||||
|
||||
#define TSEC_KEYGEN_MAX_RETRIES 25
|
||||
|
||||
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
|
||||
|
||||
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. */
|
||||
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. */
|
||||
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 *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. */
|
||||
safe_memcpy((void *)car_page, (void *)0x60006000, 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[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. */
|
||||
tsec_run_fw();
|
||||
|
||||
/* Extract the keys from SE. */
|
||||
uint32_t key_buf[0x20/4] = {0};
|
||||
volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320);
|
||||
uint32_t old_key_data = *key_data;
|
||||
uint32_t buf_counter = 0;
|
||||
while (!(tsec->FALCON_CPUCTL & 0x10)) {
|
||||
if (*key_data != old_key_data) {
|
||||
old_key_data = *key_data;
|
||||
key_buf[buf_counter] = *key_data;
|
||||
const uint32_t new_key_data = *key_data;
|
||||
if (new_key_data != old_key_data) {
|
||||
old_key_data = new_key_data;
|
||||
key_buf[buf_counter] = new_key_data;
|
||||
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. */
|
||||
volatile uint32_t *tsec_done_check = (volatile uint32_t *)((void *)expv_page + 0x200);
|
||||
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. */
|
||||
smmu_clear_tsec_as(1);
|
||||
|
||||
/* Enable back the aperture. */
|
||||
mc_enable_ahb_redirect();
|
||||
|
||||
/* Return the decrypted package1 from emulated IRAM. */
|
||||
memcpy(package1_dec, (void *)iram_pages, package1_size);
|
||||
|
||||
|
|
Loading…
Reference in a new issue