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;
  read_code(key_data_buf, key_data_addr, key_data_size);
  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);
  read_code(boot_base_addr, blob1_addr, blob1_size);
  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;
  upload_code(blob1_virt_addr, boot_base_addr, blob1_size, blob1_virt_addr, use_secret);
  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;
  read_code(key_data_buf, key_data_addr, key_data_size);
  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 *)TSEC_DMA_UNK = 0xFFF;
  *(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 *)TSEC_SCP_CTL_AUTH_MODE = 0;
  *(u32 *)TSEC_SCP_CTL_LOCK = 0;
   
   
  return;
  return;
Line 526: Line 526:
   
   
  // Load blob0 code again
  // Load blob0 code again
  read_code(boot_base_addr, blob0_addr, blob0_size);
  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 version = 0;
  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, version);
  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
       read_code(boot_base_addr, blob2_addr, blob2_size);
       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 version = 0;
       u32 use_imem = 0;
        
        
       // Decrypt Keygen blob
       // Decrypt Keygen blob
       do_crypto(src_addr, src_size, iv_addr, dst_addr, mode, version);
       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;
       upload_code(blob2_virt_addr, boot_base_addr, blob2_size, blob2_virt_addr, use_secret);
       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;
  read_code(key_data_buf, key_data_addr, key_data_size);
  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);
  read_code(boot_base_addr, blob1_addr, blob1_size);
  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;
  upload_code(blob1_virt_addr, boot_base_addr, blob1_size, blob1_virt_addr, use_secret);
  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);
  read_code(flcn_hdr_buf, blob4_flcn_hdr_addr, 0x18);
  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);
  read_code(flcn_os_hdr_buf, blob4_flcn_os_hdr_addr, 0x10);
  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);
  read_code(boot_base_addr, blob4_flcn_os_hdr_addr, flcn_os_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;
  upload_code(blob4_flcn_os_boot_virt_addr, boot_base_addr, blob4_flcn_os_boot_size, blob4_flcn_os_boot_virt_addr, use_secret);
  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;
  upload_code(blob4_flcn_os_img_virt_addr, boot_base_addr + 0x100, blob4_flcn_os_img_size, blob4_flcn_os_img_virt_addr, use_secret);
  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);
  read_code(0, blob4_flcn_os_img_hash_addr, 0x10);
  memcpy_i2d(0, blob4_flcn_os_img_hash_addr, 0x10);
   
   
  // Read data segment size from IO space
  // Read data segment size from IO space