TSEC Firmware: Difference between revisions

No edit summary
No edit summary
Line 1,289: Line 1,289:


==== exec_secboot ====
==== exec_secboot ====
This is the signed and encrypted portion of the [[#SecureBoot|SecureBoot]] payload.
<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);
    // 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();
    // Ensure CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0 is 0x02
    test_clk_source_tsec();
    // Set FLOW_MODE_WAITEVENT in FLOW_CTLR_HALT_COP_EVENTS_0
    halt_bpmp();
    // Initialize the CCPLEX
    ccplex_init();
    // Check certain CAR, PMC and FUSE registers
    test_car_pmc_fuse();
    bool is_se_ready = false;
    // Wait for SE to be ready
    while (!is_se_ready)
        is_se_ready = check_se_status();
   
    // Test MC_IRAM_BOM and MC_IRAM_TOM
    u32 mc_iram_aperture_res = test_mc_iram_aperture();
    if (mc_iram_aperture_res != 0xAAAAAAAA)
    {
        // Clear the entire DMEM region
        clear_dmem();
       
        // Halt 5 times for no good reason
        exit();
        exit();
        exit();
        exit();
        exit();
    }
   
    // Ensure FUSE_SKU_INFO is 0x83
    test_fuse_sku_info();
    // Write TSEC key to SE keyslot 0x0C
    se_set_keyslot_12();
    // Write TSEC root key to SE keyslot 0x0D
    se_set_keyslot_13();
    // Decrypt Package1
    decrypt_pk11();
    // Check certain CAR, PMC and FUSE registers
    test_car_pmc_fuse();
    // 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();
    // Clear FLOW_CTLR_HALT_COP_EVENTS_0
    resume_bpmp();
    // Clear the entire DMEM region
    clear_dmem();
       
    // Halt 5 times for no good reason
    exit();
    exit();
    exit();
    exit();
    exit();
    return;
</pre>
[7.0.0+]


== Key data ==
== Key data ==