Difference between revisions of "Second Loader"

From Vita Development Wiki
Jump to navigation Jump to search
Line 162: Line 162:
 
Factory firmware version is retrieved from idstorage and written to keyring slot 0x50F. The factory firmware must be not higher than this second_loader version, otherwise the boot is aborted to prevent downgrading below factory firmware version.
 
Factory firmware version is retrieved from idstorage and written to keyring slot 0x50F. The factory firmware must be not higher than this second_loader version, otherwise the boot is aborted to prevent downgrading below factory firmware version.
  
=== TODO ===
+
=== IDPS and OpenPSID ===
  
 
<pre>
 
<pre>
Line 170: Line 170:
 
   {
 
   {
 
     set_status(95LL);
 
     set_status(95LL);
 +
</pre>
 +
 +
IDPS and OpenPSID are retrieved from idstorage and written to keyslots 0x509 and 0x50D.
 +
 +
=== TODO ===
 +
<pre>
 
     v22 = calls_syscon_0x88E_8089F0(6LL);
 
     v22 = calls_syscon_0x88E_8089F0(6LL);
 
     v50 = v22;
 
     v50 = v22;

Revision as of 19:07, 22 June 2018

Boot process (3.60)

TODO

int __usercall boot_800432@<W4>()
{
  v51 = v0;
  setup_gpio_0_1_leds_809422();
  gpio_something_809582(0LL, 7LL, 0LL);
  gpio_something2_80950A(0LL, 7LL);
  memset_FF_16_bytes_802302();
  sub_80193E();
  clear_line_0x516_80255C();
  set_emmc_hook_80712A(0x80374ELL);             // syscon_setup_80374E
  ret = try_init_emmc_801070();
  v50 = ret;
  if ( ret )
    goto LABEL_97;
  get_syscon_setup_cached_retval_807132((__int64)&v50);
  ret = v50;
  if ( v50 )
    goto LABEL_97;
  model_info = get_cached_model_info_8038F2();
  model_info_1 = model_info;
  set_global_model_info_808C24(model_info);
  model_upper = model_info_1 & 0xFF0000;
  if ( model_upper == 0x600000 )
    goto its_devkit;
  if ( model_upper > 0x600000 )
    goto LABEL_8;
  if ( model_upper == 0x310000 )
    goto its_devkit;
  v5 = 0x100000;
  if ( model_upper > 0x310000 )
  {
    if ( model_upper == 0x410000 )
      goto its_devkit;
LABEL_8:
    if ( model_upper == 0x800000 || model_upper <= 0x800000 && model_upper == 0x700000 || model_upper == 0x820000 )
      goto its_devkit;
    v5 = 0x900000;
    goto LABEL_13;
  }
  do
  {
LABEL_13:
    if ( model_upper == v5 )
    {
its_devkit:
      sub_802044();
      enable_leds_808B7A();
    }
    set_status(65LL);
    v6 = get_syscon_ver_8038EC();
    v5 = 0x802FF;
    syscon_ver = v6;
  }
  while ( v6 <= 0x802FF );
  keyring_writeX_80250C(0x508LL, (__int64)&syscon_ver, 4LL);
  model_info_2 = get_cached_model_info_8038F2();
  keyring_writeX_80250C(0x51BLL, (__int64)&model_info_2, 4LL);
  if ( (model_info_2 & 0xFF0000u) > 0x7FFFFF )
    v7 = 0x1030;
  else
    v7 = 0x10;
  dword_E3100180 = v7;
  set_status(67LL);
  boot_type = 0;
  v8 = syscon_cmd_0x10_get_boot_type_80452A((__int64)&boot_type);
  v50 = v8;
  if ( (_DWORD)v8 )
  {
    v9 = 67LL;
LABEL_21:
    v10 = 0LL;
LABEL_22:
    report_error_808CAA(2LL, v9, v8, v10);
LABEL_23:
    ret = v50;
    goto LABEL_97;
  }
  set_status(68LL);
  ret_from_E002_1 = dword_E0020004;
  ret_from_E002 = ret_from_E002_1;
  ret_from_brom_1 = dword_E0010004;
  ret_from_brom = ret_from_brom_1;
  v15 = dword_E0062020;
  v8 = check_0x501_protection_and_compare_800DBC(ret_from_E002, ret_from_brom);
  v50 = v8;
  if ( (_DWORD)v8 )
  {
    v9 = 68LL;
    goto LABEL_21;
  }
  set_status(69LL);
  is_resume = (boot_type >> 7) & 1;
  v17 = something_with_dram_808662(1LL, is_resume);
  v50 = v17;
  if ( (_DWORD)v17 )
  {
    v18 = (unsigned __int8)sub_80877E();
    v19 = sub_808784();
    v9 = 69LL;
    v8 = v17;
    v10 = (v18 << 8) | (unsigned int)v19;
    goto LABEL_22;
  }
  if ( !(_DWORD)is_resume )
    goto LABEL_32;
  if ( !check_tz_magic_800A82() )
  {
    is_resume = 0LL;
LABEL_32:
    v20 = 0;
    clear_sysroot_801C0C();
    goto LBL_123;
  }
  if ( copy_sysroot_to_0x4001FD00_801C1E() )
  {
    is_resume = 1LL;
    goto LABEL_32;
  }
  is_resume = 1LL;
  v20 = 1;
LBL_123:
  emmc_key_reg = dword_E0070004;
  if ( emmc_key_reg & 1 )
  {
    set_status(82LL);
    report_error_808CAA(2LL, 82LL, 0x800F0029LL, 0LL);
    ret = 0x800F0029;
    goto LABEL_97;
  }
  sub_806B58(0x40000500LL, 0x1000LL);
  set_status(84LL);

Factory firmware check

  a3 = 0;
  v8 = get_factory_fw_801BAC((__int64)&a3);
  v50 = v8;
  if ( (_DWORD)v8 )
  {
    v9 = 84LL;
    goto LABEL_21;
  }
  v10 = a3;
  if ( a3 >= 0x3600001 )
  {
    v8 = 0x800F0030LL;
    v50 = 0x800F0030;
    v9 = 84LL;
    goto LABEL_22;
  }
  keyring_writeX_80250C(0x50FLL, (__int64)&a3, 4LL);
  set_status(85LL);

Factory firmware version is retrieved from idstorage and written to keyring slot 0x50F. The factory firmware must be not higher than this second_loader version, otherwise the boot is aborted to prevent downgrading below factory firmware version.

IDPS and OpenPSID

  ret = idps_and_openpsid_800B06();
  v50 = ret;
  if ( !ret )
  {
    set_status(95LL);

IDPS and OpenPSID are retrieved from idstorage and written to keyslots 0x509 and 0x50D.

TODO

    v22 = calls_syscon_0x88E_8089F0(6LL);
    v50 = v22;
    if ( (_DWORD)v22 )
      report_error_808CAA(1LL, 95LL, v22, 0LL);
    some_set_clock_808960(6LL);
    some_set_clock2_808982();
    v23 = 0x800F0026;
    if ( !(_DWORD)is_resume )
    {
      dmac_init_804BEC(&ctx);
      v23 = dmac_memset_int_804F04(0x40000000LL, 0x200000LL, 0LL, &ctx);
    }
    set_status(86LL);
    v24 = syscon_read_cmd_0x1082_ptr_0x480_into_gbuf_80232A();
    v50 = v24;
    if ( (_DWORD)v24 )
      report_error_808CAA(1LL, 86LL, v24, 0LL);
    if ( !v20 )
      syscon_read_cmd_0x1082_ptr_0x4a0_into_sysroot_802346();
    if ( !(_DWORD)is_resume && !v23 )
      dmac_wait_804C16(&ctx);
    set_status(77LL);
    if ( (_DWORD)is_resume )
      v25 = syscon_ver > 0x1000101;
    else
      v25 = 0LL;
    v50 = derive_slots_and_set_0x50B_8023A2(v25);
    if ( v50 )
    {
      syscon_unk_808C2A();
      v9 = 77LL;
LABEL_77:
      v8 = (unsigned int)v50;
      goto LABEL_21;
    }
    set_status(81LL);
    v50 = pervasive_and_syscon_cmd_0x888_optional_801038(v26);
    if ( v50 )
    {
      syscon_unk_808C2A();
      v9 = 81LL;
      goto LABEL_77;
    }
    memset((__int64)line_0x510, 0LL, 0x20LL);
    if ( sub_802050() )
    {
      set_status(87LL);
      v27 = read_syscon_cmd_0x90_off_0xE0_802056((__int64)line_0x510);
      v50 = v27;
      if ( (_DWORD)v27 )
        report_error_808CAA(1LL, 87LL, v27, 0LL);
      if ( !is_bit_set_802088((__int64)line_0x510, 0x9FLL) && !is_bit_set_802088((__int64)line_0x510, 0x81LL) )
        sub_808B66(1LL);
    }
    write_sysroot_fields_from_syscon_801FC0();
    keyring_writeX_80250C(0x510LL, (__int64)line_0x510, 0x20LL);
    memset((__int64)line_0x50A, 0LL, 0x10LL);
    set_keys_0x506_0x507_8020EA();
    if ( !is_bit_set_802088((__int64)line_0x510, 0xF0LL) )
    {
      set_status(88LL);
      v28 = some_syscon_derivation_802112((__int64)line_0x50A);
      v50 = v28;
      if ( (_DWORD)v28 != 0x800F0002 && (_DWORD)v28 != 0x800F0025 )
      {
        if ( (_DWORD)v28 )
        {
          report_error_808CAA(1LL, 88LL, v28, 0LL);
        }
        else if ( is_bit_set_802088((__int64)line_0x510, 241LL) )
        {
          unset_bit_8022F4((__int64)line_0x50A, 13LL, 1LL);
          unset_bit_8022F4((__int64)line_0x50A, 14LL, 1LL);
        }
      }
    }
    keyring_writeX_80250C(0x50ALL, (__int64)line_0x50A, 0x10LL);
    set_status(70LL);
    ret = zero_801B0E();
    v50 = ret;
    if ( !ret )
    {
      set_status(71LL);
      v50 = zero_801B24();
      if ( v50 )
      {
        syscon_unk_808C2A();
        report_error_808CAA(2LL, 71LL, (unsigned int)v50, 0LL);
        set_status(79LL);
        goto LABEL_23;
      }
      set_status(73LL);
      kbl_fw_version = 0;
      if ( (_DWORD)is_resume && (boot_type & 0x7F) != 0x17 )
      {
        copy_arm_tz_reset_vectors_800A9A();
      }
      else
      {
        v50 = decrypt_kernel_boot_loader_self_801162((__int64)&kbl_fw_version);
        if ( v50 )
        {
          syscon_unk_808C2A();
          v9 = 73LL;
          goto LABEL_77;
        }
      }
      set_status(89LL);
      syscon_unk_808C2A();
      print_info_log_800A5E();
      seven = ret_7_801B2C();
      six = ret_6_801B30();
      *(_DWORD *)(unsigned int)&dword_80C698 = zero_801B34();
      sub_804764((unsigned int)&unk_801888);
      set_status(78LL);
      v8 = set_and_check_current_fw_version_800E74(kbl_fw_version, is_resume);
      v50 = v8;
      if ( (_DWORD)v8 )
      {
        v9 = 78LL;
        goto LABEL_21;
      }
      sub_804786((__int64)&v50);
      v8 = (unsigned int)v50;
      if ( v50 )
      {
        v9 = 74LL;
        goto LABEL_21;
      }
      set_status(94LL);
      if ( (_DWORD)is_resume || kbl_fw_version >= a3 )
      {
        set_status(90LL);
        write_sysroot_801C36((__int64)line_0x510, (__int64)line_0x50A, boot_type, is_resume, a3);
        set_status(96LL);
        v29 = reads_pervasivevid_calls_syscon_0x88E_80899C(seven);
        v50 = v29;
        if ( (_DWORD)v29 )
          report_error_808CAA(1LL, 0x4CLL, v29, 0LL);
        set_status(0x4CLL);
        v8 = prepare_to_start_arm_80878A(seven, *(unsigned int *)(unsigned int)&dword_80C698, 0LL);
        v50 = v8;
        if ( (_DWORD)v8 )
        {
          v9 = 0x4CLL;
          goto LABEL_21;
        }
        v30 = some_line;
        set_status(80LL);
        read_line32_8003E8(0x602LL, (__int64)some_line);
        v31 = 0xE0020100LL;
        v32 = some_line;
        v33 = 8;
        do
        {
          v34 = *(_DWORD *)v32;
          v32 = (char *)(unsigned int)((_DWORD)v32 + 4);
          *(_DWORD *)v31 = v34;
          v31 = (unsigned int)(v31 + 4);
          --v33;
        }
        while ( v33 );
        read_line32_8003E8(0x601LL, (__int64)some_line);
        v35 = 8;
        do
        {
          v36 = *(_DWORD *)v30;
          v30 = (char *)(unsigned int)((_DWORD)v30 + 4);
          *(_DWORD *)v31 = v36;
          v31 = (unsigned int)(v31 + 4);
          --v35;
        }
        while ( v35 );
        nullsub_2();
        if ( six < 7 )
        {
          if ( six != 6 )
          {
            some_set_clock_808960(six);
            calls_syscon_0x88E_8089F0(six);
          }
        }
        else
        {
          calls_syscon_0x88E_8089F0(six);
          some_set_clock_808960(six);
        }
      }
      else
      {
        report_error_808CAA(2LL, 94LL, a3, kbl_fw_version);
        ret = 0x800F0030;
      }
    }
  }
LABEL_97:
  protect_lines_and_set_E002_8010CE();
  if ( ret )
  {
    send_status_to_arm_8010E2(0LL);
    print_info_log_800A5E();
    set_number_base_808D40((unsigned int)&g_unused, 0x10LL);
    printnum_808D46(2LL);
    printf((unsigned int)aB1B004fa16);          // boot failed
    randnum = dword_E005003C;
    sleep_8051D0((unsigned __int16)randnum);
    if ( !sub_808B82() && sub_803744() )
      syscon_cmd_0xC0_804606(0LL, 0LL);
  }
  else
  {
    send_status_to_arm_8010E2(1LL);
    syncm_8003E0();
    set_status(64LL);
  }
  return ret;
}

eeprom protection

On 0.995 and 3.60 the following lines are protected after starting arm: 0x0-0x7F, 0x140-0x17F, 0x200-0x203, 0x206-0x20D, 0x344-0x353, 0x400-0x47F, 0x502-0x57F, 0x700-0x77F

The protection it sets is 0x1C1F (so f00d read disabled).

Bypassing version checks

memeprom line 0x50B offset 0x4 bit 1 set = ignore version mismatch errors. This line itself is set from SNVS 0xD2 block 0. Alternatively set version to 0xDEADBEEF to skip.

Session key/coredump encryption

0x20 random bytes are generated and written to keyslot 0x51A. Then, the buffer is encrypted with aes128-cbc using coredump_key and coredump_iv. The result is copied to sysroot buffer +0x100 (0x1F000200)