TSEC Firmware: Difference between revisions
better names |
|||
Line 232: | Line 232: | ||
u32 key_data_addr = 0x300; | u32 key_data_addr = 0x300; | ||
u32 key_data_size = 0x7C; | u32 key_data_size = 0x7C; | ||
memcpy_i2d(key_data_buf, key_data_addr, key_data_size); | |||
// Read the next code segment into boot base | // Read the next code segment into boot base | ||
u32 blob1_addr = 0x400; | u32 blob1_addr = 0x400; | ||
u32 blob1_size = *(u32 *)(key_data_buf + 0x74); | u32 blob1_size = *(u32 *)(key_data_buf + 0x74); | ||
memcpy_i2d(boot_base_addr, blob1_addr, blob1_size); | |||
// Upload the next code segment into Falcon's CODE region | // Upload the next code segment into Falcon's CODE region | ||
u32 blob1_virt_addr = 0x300; | u32 blob1_virt_addr = 0x300; | ||
bool use_secret = true; | bool use_secret = true; | ||
memcpy_d2i(blob1_virt_addr, boot_base_addr, blob1_size, blob1_virt_addr, use_secret); | |||
u32 boot_res = 0; | u32 boot_res = 0; | ||
Line 333: | Line 333: | ||
u32 key_data_addr = 0x300; | u32 key_data_addr = 0x300; | ||
u32 key_data_size = 0x84; | u32 key_data_size = 0x84; | ||
memcpy_i2d(key_data_buf, key_data_addr, key_data_size); | |||
// Calculate the next blob's address | // Calculate the next blob's address | ||
Line 350: | Line 350: | ||
This method takes '''key_data_buf''' (a 16 bytes buffer) as argument and writes its contents to SOR1 registers. | This method takes '''key_data_buf''' (a 16 bytes buffer) as argument and writes its contents to SOR1 registers. | ||
// This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40) | // This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40) | ||
*(u32 *) | *(u32 *)TSEC_DMA_CFG = 0xFFF; | ||
// Read the key's words | // Read the key's words | ||
Line 434: | Line 434: | ||
// fuc5 crypt cxset instruction | // fuc5 crypt cxset instruction | ||
// Clear overrides | // Clear overrides | ||
cxset(0x80); | cxset(0x80); | ||
Line 514: | Line 514: | ||
// Exit Authenticated Mode | // Exit Authenticated Mode | ||
// This is TSEC_MMIO + 0x1000 + (0x10300 / 0x40) | // This is TSEC_MMIO + 0x1000 + (0x10300 / 0x40) | ||
*(u32 *) | *(u32 *)TSEC_SCP_CTL_LOCK = 0; | ||
return; | return; | ||
Line 526: | Line 526: | ||
// Load blob0 code again | // Load blob0 code again | ||
memcpy_i2d(boot_base_addr, blob0_addr, blob0_size); | |||
// Generate "CODE_SIG_01" key into c4 crypto register | // Generate "CODE_SIG_01" key into c4 crypto register | ||
Line 540: | Line 540: | ||
u32 dst_addr = sig_key; | u32 dst_addr = sig_key; | ||
u32 mode = 0x02; // AES-CMAC | u32 mode = 0x02; // AES-CMAC | ||
u32 | u32 use_imem = 0; | ||
// Do AES-CMAC over blob0 code | // Do AES-CMAC over blob0 code | ||
do_crypto(src_addr, src_size, iv_addr, dst_addr, mode, | do_crypto(src_addr, src_size, iv_addr, dst_addr, mode, use_imem); | ||
// Compare the hashes | // Compare the hashes | ||
Line 568: | Line 568: | ||
// Read Keygen encrypted blob | // Read Keygen encrypted blob | ||
memcpy_i2d(boot_base_addr, blob2_addr, blob2_size); | |||
// Generate "CODE_ENC_01" key into c4 crypt register | // Generate "CODE_ENC_01" key into c4 crypt register | ||
Line 578: | Line 578: | ||
u32 dst_addr = boot_base_addr; | u32 dst_addr = boot_base_addr; | ||
u32 mode = 0; // AES-128-ECB | u32 mode = 0; // AES-128-ECB | ||
u32 | u32 use_imem = 0; | ||
// Decrypt Keygen blob | // Decrypt Keygen blob | ||
do_crypto(src_addr, src_size, iv_addr, dst_addr, mode, | do_crypto(src_addr, src_size, iv_addr, dst_addr, mode, use_imem); | ||
// Upload the next code segment into Falcon's CODE region | // Upload the next code segment into Falcon's CODE region | ||
bool use_secret = true; | bool use_secret = true; | ||
memcpy_d2i(blob2_virt_addr, boot_base_addr, blob2_size, blob2_virt_addr, use_secret); | |||
// Clear out the decrypted blob | // Clear out the decrypted blob | ||
Line 925: | Line 925: | ||
u32 key_data_addr = 0x300; | u32 key_data_addr = 0x300; | ||
u32 key_data_size = 0x84; | u32 key_data_size = 0x84; | ||
memcpy_i2d(key_data_buf, key_data_addr, key_data_size); | |||
// Read the KeygenLdr blob from memory | // Read the KeygenLdr blob from memory | ||
Line 931: | Line 931: | ||
u32 blob1_addr = 0x400; | u32 blob1_addr = 0x400; | ||
u32 blob1_size = *(u32 *)(key_data_buf + 0x74); | u32 blob1_size = *(u32 *)(key_data_buf + 0x74); | ||
memcpy_i2d(boot_base_addr, blob1_addr, blob1_size); | |||
// Upload the next code segment into Falcon's CODE region | // Upload the next code segment into Falcon's CODE region | ||
u32 blob1_virt_addr = 0x300; | u32 blob1_virt_addr = 0x300; | ||
bool use_secret = true; | bool use_secret = true; | ||
memcpy_d2i(blob1_virt_addr, boot_base_addr, blob1_size, blob1_virt_addr, use_secret); | |||
// Backup the key data | // Backup the key data | ||
Line 991: | Line 991: | ||
// Read the SecureBoot blob's Falcon header from memory | // Read the SecureBoot blob's Falcon header from memory | ||
u32 blob4_flcn_hdr_addr = (((blob0_size + blob1_size) + 0x100) + blob2_size); | u32 blob4_flcn_hdr_addr = (((blob0_size + blob1_size) + 0x100) + blob2_size); | ||
memcpy_i2d(flcn_hdr_buf, blob4_flcn_hdr_addr, 0x18); | |||
blob1_size = *(u32 *)(key_data_buf + 0x74); | blob1_size = *(u32 *)(key_data_buf + 0x74); | ||
Line 1,000: | Line 1,000: | ||
// Read the SecureBoot blob's Falcon OS header from memory | // Read the SecureBoot blob's Falcon OS header from memory | ||
u32 blob4_flcn_os_hdr_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_hdr_size); | u32 blob4_flcn_os_hdr_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_hdr_size); | ||
memcpy_i2d(flcn_os_hdr_buf, blob4_flcn_os_hdr_addr, 0x10); | |||
blob1_size = *(u32 *)(key_data_buf + 0x74); | blob1_size = *(u32 *)(key_data_buf + 0x74); | ||
Line 1,010: | Line 1,010: | ||
// Read the SecureBoot blob's Falcon OS image from memory | // Read the SecureBoot blob's Falcon OS image from memory | ||
u32 blob4_flcn_os_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size); | u32 blob4_flcn_os_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size); | ||
memcpy_i2d(boot_base_addr, blob4_flcn_os_hdr_addr, flcn_os_size); | |||
// Upload the SecureBoot's Falcon OS image boot stub code segment into Falcon's CODE region | // Upload the SecureBoot's Falcon OS image boot stub code segment into Falcon's CODE region | ||
Line 1,016: | Line 1,016: | ||
u32 blob4_flcn_os_boot_size = 0x100; | u32 blob4_flcn_os_boot_size = 0x100; | ||
use_secret = false; | use_secret = false; | ||
memcpy_d2i(blob4_flcn_os_boot_virt_addr, boot_base_addr, blob4_flcn_os_boot_size, blob4_flcn_os_boot_virt_addr, use_secret); | |||
flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); | flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); | ||
Line 1,024: | Line 1,024: | ||
u32 blob4_flcn_os_img_size = (flcn_os_size - 0x100); | u32 blob4_flcn_os_img_size = (flcn_os_size - 0x100); | ||
use_secret = true; | use_secret = true; | ||
memcpy_d2i(blob4_flcn_os_img_virt_addr, boot_base_addr + 0x100, blob4_flcn_os_img_size, blob4_flcn_os_img_virt_addr, use_secret); | |||
// Wait for all code loads to finish | // Wait for all code loads to finish | ||
Line 1,037: | Line 1,037: | ||
// Read the SecureBoot blob's falcon OS image's hash from memory | // Read the SecureBoot blob's falcon OS image's hash from memory | ||
u32 blob4_flcn_os_img_hash_addr = (((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size) + flcn_os_code_size); | u32 blob4_flcn_os_img_hash_addr = (((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size) + flcn_os_code_size); | ||
memcpy_i2d(0, blob4_flcn_os_img_hash_addr, 0x10); | |||
// Read data segment size from IO space | // Read data segment size from IO space |