Changes

9,522 bytes added ,  19:26, 21 February 2019
no edit summary
Line 1,387: Line 1,387:  
     set_excp_vec(entry_addr);
 
     set_excp_vec(entry_addr);
   −
     // Fill the top 0x500 bytes in DMEM with a pointer to trap function (just exits)
+
     // Fill the top 0x500 bytes in DMEM with a pointer to trap function (just exits 3 times)
 
     for (int i = 0; i < 0x500; i += 0x04) {
 
     for (int i = 0; i < 0x500; i += 0x04) {
 
         *(u32 *)i = (u32)trap_func();
 
         *(u32 *)i = (u32)trap_func();
Line 1,421: Line 1,421:  
</pre>
 
</pre>
   −
[7.0.0+]
+
[7.0.0+] Many changes were introduced to mitigate and prevent attacks.
 +
<pre>
 +
    // Recover the transfer base address from the stack
 +
    u32 xfer_ext_base_addr = *(u32 *)scratch_data_addr;
 +
 
 +
    // Return the TLB entry that covers the virtual address
 +
    u32 tlb_entry = vtlb(xfer_ext_base_addr);
 +
   
 +
    // Clear Falcon CPU control
 +
    *(u32 *)FALCON_CPUCTL = 0;
 +
   
 +
    // Halt if the external page is marked as secret
 +
    if ((tlb_entry & 0x4000000) != 0)
 +
        exit();
 +
   
 +
    // Read data segment size from IO space
 +
    u32 data_seg_size = *(u32 *)FALCON_HWCFG;
 +
    data_seg_size >>= 0x01;
 +
    data_seg_size &= 0xFF00;
 +
 +
    // Set the stack pointer
 +
    $sp = data_seg_size;
 +
   
 +
    // Fill all DMEM with a pointer to a trap function (just exits 3 times)
 +
    for (int i = 0; i < data_seg_size; i += 0x04) {
 +
        *(u32 *)i = (u32)trap_func();
 +
    }
 +
 
 +
    // Initialize the TRNG and generate random data in DMEM
 +
    init_rnd();
 +
   
 +
    // Issue a randomized delay and return a random value
 +
    u32 rnd_val = rnd_delay(0xFF);
 +
 
 +
    // Enable and test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x01);
 +
 
 +
    // Issue a randomized delay and return a random value
 +
    rnd_val = rnd_delay(0xFF);
 +
 
 +
    // Test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x00);
 +
 
 +
    // Issue a randomized delay and return a random value
 +
    rnd_val = rnd_delay(0xFF);
 +
 
 +
    // Test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x00);
 +
 
 +
    // Fill SE keyslots 12 and 13 with random data
 +
    se_set_keyslot_rnd();
 +
 
 +
    // Test randomized offsets for read/write integrity in MC, FUSE, IRAM and TZRAM
 +
    u32 test_res = test_mc_fuse_iram_tzram();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Try to detect virtualization by enabling and disabling random CAR devices
 +
    test_res = test_car();
 +
   
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Test memory transfer integrity
 +
    test_res = test_mem_xfer();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Set FLOW_MODE_WAITEVENT in FLOW_CTLR_HALT_COP_EVENTS_0
 +
    halt_bpmp();
 +
 
 +
    // Initialize the CCPLEX
 +
    ccplex_init();
 +
 
 +
    // Check if SE is ready
 +
    u32 se_status = check_se_status();
 +
 
 +
    if (se_status != 0)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Load the TSEC key from SOR1 registers into DMEM
 +
    sor1_get_key();
 +
 
 +
    // Initialize CAR registers
 +
    car_init();
 +
 
 +
    // Check certain CAR, PMC and FUSE registers
 +
    test_car_pmc_fuse();
 +
 
 +
    // Try to detect virtualization by enabling and disabling random CAR devices
 +
    test_res = test_car();
 +
   
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Ensure FUSE_SKU_INFO is 0x83
 +
    test_fuse_sku_info();
 +
 
 +
    // Try to detect virtualization using MC_SMMU_AVPC_ASID and FUSE_ECO_RESERVE_0
 +
    test_smmu_fuse();
 +
 
 +
    // Test MC_IRAM_BOM and MC_IRAM_TOM
 +
    test_res = test_mc_iram_aperture();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Check certain CAR, PMC and FUSE registers
 +
    test_car_pmc_fuse();
 +
 
 +
    // Test memory transfer integrity
 +
    test_res = test_mem_xfer();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Try to detect virtualization using MC_SMMU_AVPC_ASID and FUSE_ECO_RESERVE_0
 +
    test_smmu_fuse();
 +
 
 +
    // Test MC_IRAM_BOM and MC_IRAM_TOM
 +
    test_res = test_mc_iram_aperture();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x00);
 +
 
 +
    // Decrypt Package1
 +
    decrypt_pk11();
 +
 
 +
    // Write TSEC root key to SE keyslot 0x0D
 +
    se_set_keyslot_13();
 +
 
 +
    // Write TSEC key to SE keyslot 0x0C
 +
    se_set_keyslot_12();
 +
 
 +
    // Clear the cauth signature
 +
    csigclr();
 +
 
 +
    // Check certain CAR, PMC and FUSE registers
 +
    test_car_pmc_fuse();
 +
 
 +
    // Test memory transfer integrity
 +
    test_res = test_mem_xfer();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
   
 +
    // Try to detect virtualization using MC_SMMU_AVPC_ASID and FUSE_ECO_RESERVE_0
 +
    test_smmu_fuse();
 +
 
 +
    // Test randomized offsets for read/write integrity in MC, FUSE, IRAM and TZRAM
 +
    test_res = test_mc_fuse_iram_tzram();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Test MC_IRAM_BOM and MC_IRAM_TOM
 +
    test_res = test_mc_iram_aperture();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x00);
 +
 
 +
    // Parse Package1 header and return entry address
 +
    u32 entry_addr = parse_pk11();
 +
 
 +
    // Set the exception vectors
 +
    set_excp_vec(entry_addr);
 +
 
 +
    // Fill the top 0x500 bytes in DMEM with a pointer to trap function (just exits)
 +
    for (int i = 0; i < 0x500; i += 0x04) {
 +
        *(u32 *)i = (u32)trap_func();
 +
    }
 +
 
 +
    // Clear all crypto registers
 +
    cxor($c0, $c0);
 +
    cxor($c1, $c1);
 +
    cxor($c2, $c2);
 +
    cxor($c3, $c3);
 +
    cxor($c4, $c4);
 +
    cxor($c5, $c5);
 +
    cxor($c6, $c6);
 +
    cxor($c7, $c7);
 +
   
 +
    // Take SCP out of lockdown
 +
    unlock_scp();
 +
 
 +
    // Test memory transfer integrity
 +
    test_res = test_mem_xfer();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Try to detect virtualization using MC_SMMU_AVPC_ASID and FUSE_ECO_RESERVE_0
 +
    test_smmu_fuse();
 +
 
 +
    // Test MC_IRAM_BOM and MC_IRAM_TOM
 +
    test_res = test_mc_iram_aperture();
 +
 
 +
    if (test_res != 0xAAAAAAAA)
 +
    {
 +
        // Fill SE keyslots 12 and 13 with random data
 +
        se_set_keyslot_rnd();
 +
 
 +
        // Clear the entire DMEM region and every crypto register
 +
        clear_dmem_and_crypto();
 +
 
 +
        // Halt 5 times for no good reason
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
        exit();
 +
    }
 +
 
 +
    // Test SMMU bypassing in the TFBIF
 +
    tfbif_smmu_cfg(0x00);
 +
 
 +
    // Clear FLOW_CTLR_HALT_COP_EVENTS_0
 +
    resume_bpmp();
 +
 
 +
    // Clear the entire DMEM region and every crypto register
 +
    clear_dmem_and_crypto();
 +
       
 +
    // Halt 5 times for no good reason
 +
    exit();
 +
    exit();
 +
    exit();
 +
    exit();
 +
    exit();
 +
 
 +
    return;
 +
</pre>
    
== Key data ==
 
== Key data ==