fusee: basic byok support for 7.0.0

This commit is contained in:
Michael Scire 2019-01-31 02:23:43 -08:00
parent a71b2d9329
commit 752e0757d9
5 changed files with 97 additions and 8 deletions

View file

@ -308,6 +308,60 @@ static const instruction_t MAKE_KERNEL_HOOK_NAME(600, proc_id_send)[] = {0xA9BF2
*/ */
static const uint8_t MAKE_KERNEL_PATTERN_NAME(600, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE9, 0x6F, 0x40, 0xF9, 0xE8, 0x03, 0x15, 0x2A, 0xB5, 0x0A, 0x00, 0x11}; static const uint8_t MAKE_KERNEL_PATTERN_NAME(600, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE9, 0x6F, 0x40, 0xF9, 0xE8, 0x03, 0x15, 0x2A, 0xB5, 0x0A, 0x00, 0x11};
static const instruction_t MAKE_KERNEL_HOOK_NAME(600, proc_id_recv)[] = {0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; static const instruction_t MAKE_KERNEL_HOOK_NAME(600, proc_id_recv)[] = {0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0x70]
mov w10, w25
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x21]
ldr x8, [x8, #0x38]
mov x0, x21
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(700, proc_id_send)[] = {0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x15, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x03, 0x19, 0x2A, 0x39, 0x0B, 0x00, 0x11, 0x08, 0xF5, 0x7E, 0xD3};
static const instruction_t MAKE_KERNEL_HOOK_NAME(700, proc_id_send)[] = {0xA9BF2FEA, 0xF9403BEB, 0x2A1903EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0x98]
mov w10, w22
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x27]
ldr x8, [x8, #0x38]
mov x0, x27
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(700, proc_id_recv)[] = {0x68, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1B, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xA9, 0x83, 0x50, 0xF8, 0xE8, 0x03, 0x16, 0x2A, 0xD6, 0x0A, 0x00, 0x11};
static const instruction_t MAKE_KERNEL_HOOK_NAME(700, proc_id_recv)[] = {0xA9BF2FEA, 0xF9404FEB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/* Hook Definitions. */ /* Hook Definitions. */
static const kernel_hook_t g_kernel_hooks_100[] = { static const kernel_hook_t g_kernel_hooks_100[] = {
@ -436,6 +490,24 @@ static const kernel_hook_t g_kernel_hooks_600[] = {
.payload = MAKE_KERNEL_HOOK_NAME(600, proc_id_recv) .payload = MAKE_KERNEL_HOOK_NAME(600, proc_id_recv)
} }
}; };
static const kernel_hook_t g_kernel_hooks_700[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(700, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_HOOK_NAME(700, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_HOOK_NAME(700, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(700, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_HOOK_NAME(700, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_HOOK_NAME(700, proc_id_recv)
}
};
#define KERNEL_HOOKS(vers) .num_hooks = sizeof(g_kernel_hooks_##vers)/sizeof(kernel_hook_t), .hooks = g_kernel_hooks_##vers, #define KERNEL_HOOKS(vers) .num_hooks = sizeof(g_kernel_hooks_##vers)/sizeof(kernel_hook_t), .hooks = g_kernel_hooks_##vers,
@ -481,6 +553,11 @@ static const kernel_info_t g_kernel_infos[] = {
.hash = {0x85, 0x97, 0x40, 0xF6, 0xC0, 0x3E, 0x3D, 0x44, 0xDE, 0xA4, 0xA0, 0x35, 0xFD, 0x12, 0x9C, 0xD4, 0x4F, 0x9C, 0x36, 0x53, 0x74, 0x54, 0x2C, 0x9C, 0x55, 0x47, 0xC4, 0x25, 0xF1, 0x42, 0xFB, 0x97}, .hash = {0x85, 0x97, 0x40, 0xF6, 0xC0, 0x3E, 0x3D, 0x44, 0xDE, 0xA4, 0xA0, 0x35, 0xFD, 0x12, 0x9C, 0xD4, 0x4F, 0x9C, 0x36, 0x53, 0x74, 0x54, 0x2C, 0x9C, 0x55, 0x47, 0xC4, 0x25, 0xF1, 0x42, 0xFB, 0x97},
.free_code_space_offset = 0x5EE00, .free_code_space_offset = 0x5EE00,
KERNEL_HOOKS(600) KERNEL_HOOKS(600)
},
{ /* 7.0.0. */
.hash = {0xA2, 0x5E, 0x47, 0x0C, 0x8E, 0x6D, 0x2F, 0xD7, 0x5D, 0xAD, 0x24, 0xD7, 0xD8, 0x24, 0x34, 0xFB, 0xCD, 0x77, 0xBB, 0xE6, 0x66, 0x03, 0xCB, 0xAF, 0xAB, 0x85, 0x45, 0xA0, 0x91, 0xAF, 0x34, 0x25},
.free_code_space_offset = 0x5FE80,
KERNEL_HOOKS(700)
} }
}; };

View file

@ -222,6 +222,7 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
case ATMOSPHERE_TARGET_FIRMWARE_500: case ATMOSPHERE_TARGET_FIRMWARE_500:
case ATMOSPHERE_TARGET_FIRMWARE_600: case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620: case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10); decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10); decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
decrypt_data_into_keyslot(0xE, 0xC, masterkey_4x_seed, 0x10); decrypt_data_into_keyslot(0xE, 0xC, masterkey_4x_seed, 0x10);

View file

@ -166,8 +166,10 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
fatal_error("[NXBOOT]: Unable to identify package1!\n"); fatal_error("[NXBOOT]: Unable to identify package1!\n");
} }
} }
case 0x0F:
return ATMOSPHERE_TARGET_FIRMWARE_700;
default: default:
return 0; fatal_error("[NXBOOT]: Unable to identify package1!\n");
} }
} }
@ -381,7 +383,7 @@ uint32_t nxboot_main(void) {
/* Read the TSEC firmware from a file, otherwise from PK1L. */ /* Read the TSEC firmware from a file, otherwise from PK1L. */
if (loader_ctx->tsecfw_path[0] != '\0') { if (loader_ctx->tsecfw_path[0] != '\0') {
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path); tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900)) { if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000)) {
fatal_error("[NXBOOT]: TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path); fatal_error("[NXBOOT]: TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
} else if (tsec_fw_size == 0) { } else if (tsec_fw_size == 0) {
fatal_error("[NXBOOT]: Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path); fatal_error("[NXBOOT]: Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
@ -400,7 +402,9 @@ uint32_t nxboot_main(void) {
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) { if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
fatal_error("[NXBOOT]: Failed to read the TSEC firmware from Package1loader!\n"); fatal_error("[NXBOOT]: Failed to read the TSEC firmware from Package1loader!\n");
} }
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620) { if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_700) {
tsec_fw_size = 0x3000;
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_620) {
tsec_fw_size = 0x2900; tsec_fw_size = 0x2900;
} else { } else {
tsec_fw_size = 0xF00; tsec_fw_size = 0xF00;
@ -413,7 +417,10 @@ uint32_t nxboot_main(void) {
uint8_t tsec_key[0x10] = {0}; uint8_t tsec_key[0x10] = {0};
uint8_t tsec_root_keys[0x20][0x10] = {0}; uint8_t tsec_root_keys[0x20][0x10] = {0};
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) {
/* TODO: what to do here? */ /* TODO: what else to do here? */
/* Patch TSEC firmware to exit after generating TSEC key. */
*((volatile uint16_t *)((uintptr_t)tsec_fw + 0x2DB5)) = 0x02F8;
if (tsec_get_key(tsec_key, 1, tsec_fw, tsec_fw_size) != 0) { if (tsec_get_key(tsec_key, 1, tsec_fw, tsec_fw_size) != 0) {
fatal_error("[NXBOOT]: Failed to get TSEC key!\n"); fatal_error("[NXBOOT]: Failed to get TSEC key!\n");
} }
@ -499,8 +506,10 @@ uint32_t nxboot_main(void) {
warmboot_memaddr = (void *)0x8000D000; warmboot_memaddr = (void *)0x8000D000;
} else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_600) { } else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_600) {
warmboot_memaddr = (void *)0x4003B000; warmboot_memaddr = (void *)0x4003B000;
} else { } else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) {
warmboot_memaddr = (void *)0x4003D800; warmboot_memaddr = (void *)0x4003D800;
} else {
warmboot_memaddr = (void *)0x4003E000;
} }
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Copying warmboot firmware...\n"); print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Copying warmboot firmware...\n");

View file

@ -214,7 +214,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */ /* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */ /* We will be compatible with all package2s released before current, but not newer ones. */
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_620_CURRENT) { if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_700_CURRENT) {
return true; return true;
} }

View file

@ -35,7 +35,8 @@
#define PACKAGE2_MAXVER_400_410 0x6 #define PACKAGE2_MAXVER_400_410 0x6
#define PACKAGE2_MAXVER_500_510 0x7 #define PACKAGE2_MAXVER_500_510 0x7
#define PACKAGE2_MAXVER_600_610 0x8 #define PACKAGE2_MAXVER_600_610 0x8
#define PACKAGE2_MAXVER_620_CURRENT 0x9 #define PACKAGE2_MAXVER_620 0x9
#define PACKAGE2_MAXVER_700_CURRENT 0xA
#define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_200 0x4
@ -44,7 +45,8 @@
#define PACKAGE2_MINVER_400_410 0x7 #define PACKAGE2_MINVER_400_410 0x7
#define PACKAGE2_MINVER_500_510 0x8 #define PACKAGE2_MINVER_500_510 0x8
#define PACKAGE2_MINVER_600_610 0x9 #define PACKAGE2_MINVER_600_610 0x9
#define PACKAGE2_MINVER_620_CURRENT 0xA #define PACKAGE2_MINVER_620 0xA
#define PACKAGE2_MINVER_700_CURRENT 0xB
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull)) #define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))