mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
sept: update to support 8.1.0
This commit is contained in:
parent
c96ae0148e
commit
befd912a88
20 changed files with 218 additions and 140 deletions
|
@ -26,11 +26,12 @@
|
|||
#define ATMOSPHERE_TARGET_FIRMWARE_620 7
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_700 8
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_800 9
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_810 10
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_800
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_810
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_800
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_810
|
||||
|
||||
/* TODO: What should this be, for release? */
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||
|
|
|
@ -57,7 +57,7 @@ unsigned int exosphere_should_perform_620_keygen(void) {
|
|||
generic_panic();
|
||||
}
|
||||
|
||||
return g_exosphere_cfg.target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620 && EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_PERFORM_620_KEYGEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int exosphere_should_override_debugmode_priv(void) {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
/* Exosphere config in DRAM shares physical/virtual mapping. */
|
||||
#define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG
|
||||
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN_DEPRECATED (1 << 0u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
||||
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
||||
|
|
|
@ -99,7 +99,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|||
KIPFILES := loader.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
||||
exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp \
|
||||
sept-primary.bin sept-secondary.enc emummc.kip \
|
||||
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
|
||||
$(KIPFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
@ -204,7 +204,12 @@ sept_primary.bin.o sept_primary_bin.h: sept-primary.bin
|
|||
@echo $(notdir $<)
|
||||
@$(_bin2o)
|
||||
|
||||
sept_secondary.enc.o sept_secondary_enc.h: sept-secondary.enc
|
||||
sept_secondary_00.enc.o sept_secondary_00.h: sept-secondary_00.enc
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(_bin2o)
|
||||
|
||||
sept_secondary_01.enc.o sept_secondary_01_enc.h: sept-secondary_01.enc
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(_bin2o)
|
||||
|
|
|
@ -236,8 +236,10 @@ SECTIONS
|
|||
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
|
||||
PROVIDE(__sept_primary_bin_start__ = sept_primary_bin - __start__);
|
||||
PROVIDE(__sept_primary_bin_size__ = sept_primary_bin_end - sept_primary_bin);
|
||||
PROVIDE(__sept_secondary_enc_start__ = sept_secondary_enc - __start__);
|
||||
PROVIDE(__sept_secondary_enc_size__ = sept_secondary_enc_end - sept_secondary_enc);
|
||||
PROVIDE(__sept_secondary_00_enc_start__ = sept_secondary_00_enc - __start__);
|
||||
PROVIDE(__sept_secondary_00_enc_size__ = sept_secondary_00_enc_end - sept_secondary_00_enc);
|
||||
PROVIDE(__sept_secondary_01_enc_start__ = sept_secondary_01_enc - __start__);
|
||||
PROVIDE(__sept_secondary_01_enc_size__ = sept_secondary_01_enc_end - sept_secondary_01_enc);
|
||||
PROVIDE(__sm_kip_start__ = sm_kip - __start__);
|
||||
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
|
||||
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
|
||||
|
|
|
@ -54,7 +54,8 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
|
|||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||
};
|
||||
|
||||
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_600_610][0x10] = {
|
||||
/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
|
||||
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
|
||||
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* MasterKek seed 06. */
|
||||
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */
|
||||
};
|
||||
|
@ -150,7 +151,10 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
|||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||
desired_keyblob = MASTERKEY_REVISION_700_CURRENT;
|
||||
desired_keyblob = MASTERKEY_REVISION_700_800;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
desired_keyblob = MASTERKEY_REVISION_810_CURRENT;
|
||||
break;
|
||||
default:
|
||||
fatal_error("Unknown target firmware: %02x!", target_firmware);
|
||||
|
@ -225,6 +229,7 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui
|
|||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
||||
decrypt_data_into_keyslot(0xE, 0xC, masterkey_4x_seed, 0x10);
|
||||
|
|
|
@ -39,6 +39,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
|
|||
{0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC}, /* Master key 04 encrypted with Master key 05. */
|
||||
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
|
||||
{0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 07 encrypted with Master key 08. */
|
||||
};
|
||||
|
||||
/* Retail unit keys. */
|
||||
|
@ -52,6 +53,7 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
|
|||
{0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
|
||||
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
|
||||
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
|
||||
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
|
||||
};
|
||||
|
||||
static bool check_mkey_revision(unsigned int revision, bool is_retail) {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
/* This is glue code to enable master key support across versions. */
|
||||
|
||||
/* TODO: Update to 0x8 on release of new master key. */
|
||||
#define MASTERKEY_REVISION_MAX 0x8
|
||||
/* TODO: Update to 0xA on release of new master key. */
|
||||
#define MASTERKEY_REVISION_MAX 0x9
|
||||
|
||||
#define MASTERKEY_REVISION_100_230 0x00
|
||||
#define MASTERKEY_REVISION_300 0x01
|
||||
|
@ -29,7 +29,8 @@
|
|||
#define MASTERKEY_REVISION_500_510 0x04
|
||||
#define MASTERKEY_REVISION_600_610 0x05
|
||||
#define MASTERKEY_REVISION_620 0x06
|
||||
#define MASTERKEY_REVISION_700_CURRENT 0x07
|
||||
#define MASTERKEY_REVISION_700_800 0x07
|
||||
#define MASTERKEY_REVISION_810_CURRENT 0x08
|
||||
|
||||
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
#define u8 uint8_t
|
||||
#define u32 uint32_t
|
||||
#include "exosphere_bin.h"
|
||||
#include "sept_secondary_enc.h"
|
||||
#include "sept_secondary_00_enc.h"
|
||||
#include "sept_secondary_01_enc.h"
|
||||
#include "lp0fw_bin.h"
|
||||
#include "emummc_kip.h"
|
||||
#include "lib/log.h"
|
||||
|
@ -207,8 +208,15 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
|||
}
|
||||
case 0x0F: /* 7.0.0 - 7.0.1 */
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_700;
|
||||
case 0x10: /* 8.0.0 */
|
||||
case 0x10: { /* 8.0.0 - 8.1.0 */
|
||||
if (memcmp(package1loader_header->build_timestamp, "20190314", 8) == 0) {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_800;
|
||||
} else if (memcmp(package1loader_header->build_timestamp, "20190531", 8) == 0) {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_810;
|
||||
} else {
|
||||
fatal_error("[NXBOOT] Unable to identify package1!\n");
|
||||
}
|
||||
}
|
||||
default:
|
||||
fatal_error("[NXBOOT] Unable to identify package1!\n");
|
||||
}
|
||||
|
@ -459,6 +467,8 @@ uint32_t nxboot_main(void) {
|
|||
size_t package2_size;
|
||||
void *tsec_fw;
|
||||
size_t tsec_fw_size;
|
||||
const void *sept_secondary_enc = NULL;
|
||||
size_t sept_secondary_enc_size = 0;
|
||||
void *warmboot_fw;
|
||||
size_t warmboot_fw_size;
|
||||
void *warmboot_memaddr;
|
||||
|
@ -561,7 +571,7 @@ uint32_t nxboot_main(void) {
|
|||
/* Read the TSEC firmware from a file, otherwise from PK1L. */
|
||||
if (loader_ctx->tsecfw_path[0] != '\0') {
|
||||
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
|
||||
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000)) {
|
||||
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000 && tsec_fw_size != 0x3300)) {
|
||||
fatal_error("[NXBOOT] TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
|
||||
} else if (tsec_fw_size == 0) {
|
||||
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
|
||||
|
@ -576,11 +586,27 @@ uint32_t nxboot_main(void) {
|
|||
if (read_from_file(tsec_fw, tsec_fw_size, loader_ctx->tsecfw_path) != tsec_fw_size) {
|
||||
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
|
||||
}
|
||||
|
||||
if (tsec_fw_size == 0x3000) {
|
||||
sept_secondary_enc = sept_secondary_00_enc;
|
||||
sept_secondary_enc_size = sept_secondary_00_enc_size;
|
||||
} else if (tsec_fw_size == 0x3300) {
|
||||
sept_secondary_enc = sept_secondary_01_enc;
|
||||
sept_secondary_enc_size = sept_secondary_01_enc_size;
|
||||
} else {
|
||||
fatal_error("[NXBOOT] Unable to identify sept revision to run.");
|
||||
}
|
||||
} else {
|
||||
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
|
||||
fatal_error("[NXBOOT] Failed to read the TSEC firmware from Package1loader!\n");
|
||||
}
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) {
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_810) {
|
||||
sept_secondary_enc = sept_secondary_01_enc;
|
||||
sept_secondary_enc_size = sept_secondary_01_enc_size;
|
||||
tsec_fw_size = 0x3300;
|
||||
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) {
|
||||
sept_secondary_enc = sept_secondary_00_enc;
|
||||
sept_secondary_enc_size = sept_secondary_00_enc_size;
|
||||
tsec_fw_size = 0x3000;
|
||||
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
tsec_fw_size = 0x2900;
|
||||
|
|
|
@ -232,7 +232,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
|
|||
|
||||
/* Perform version checks. */
|
||||
/* 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_700_CURRENT) {
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_810_CURRENT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#define PACKAGE2_MAXVER_500_510 0x7
|
||||
#define PACKAGE2_MAXVER_600_610 0x8
|
||||
#define PACKAGE2_MAXVER_620 0x9
|
||||
#define PACKAGE2_MAXVER_700_CURRENT 0xA
|
||||
#define PACKAGE2_MAXVER_700_800 0xA
|
||||
#define PACKAGE2_MAXVER_810_CURRENT 0xB
|
||||
|
||||
#define PACKAGE2_MINVER_100 0x3
|
||||
#define PACKAGE2_MINVER_200 0x4
|
||||
|
@ -46,7 +47,8 @@
|
|||
#define PACKAGE2_MINVER_500_510 0x8
|
||||
#define PACKAGE2_MINVER_600_610 0x9
|
||||
#define PACKAGE2_MINVER_620 0xA
|
||||
#define PACKAGE2_MINVER_700_CURRENT 0xB
|
||||
#define PACKAGE2_MINVER_700_800 0xB
|
||||
#define PACKAGE2_MINVER_810_CURRENT 0xC
|
||||
|
||||
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))
|
||||
|
||||
|
|
|
@ -168,12 +168,20 @@ _content_headers:
|
|||
.asciz "sept_primary"
|
||||
.align 5
|
||||
|
||||
/* sept_secondary content header */
|
||||
.word __sept_secondary_enc_start__
|
||||
.word __sept_secondary_enc_size__
|
||||
/* sept_secondary 00 content header */
|
||||
.word __sept_secondary_00_enc_start__
|
||||
.word __sept_secondary_00_enc_size__
|
||||
.word CONTENT_TYPE_SP2
|
||||
.word 0xCCCCCCCC
|
||||
.asciz "sept_secondary"
|
||||
.asciz "sept_secondary_00"
|
||||
.align 5
|
||||
|
||||
/* sept_secondary 01 content header */
|
||||
.word __sept_secondary_01_enc_start__
|
||||
.word __sept_secondary_01_enc_size__
|
||||
.word CONTENT_TYPE_SP2
|
||||
.word 0xCCCCCCCC
|
||||
.asciz "sept_secondary_01"
|
||||
.align 5
|
||||
|
||||
/* sm content header */
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
HOVI_ENC_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
|
||||
HOVI_ENC_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
|
||||
HOVI_SIG_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
|
||||
HOVI_SIG_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
|
||||
HOVI_KEK_KEY_PRD = bytearray.fromhex('00000000000000000000000000000000')
|
||||
HOVI_KEK_KEY_DEV = bytearray.fromhex('00000000000000000000000000000000')
|
||||
IV = bytearray.fromhex('00000000000000000000000000000000')
|
||||
NUM_KEYS = 2
|
||||
|
||||
HOVI_ENC_KEY_PRD = [
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
]
|
||||
HOVI_SIG_KEY_PRD = [
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
]
|
||||
|
||||
IV = [
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
bytearray.fromhex('00000000000000000000000000000000'),
|
||||
]
|
||||
|
||||
assert len(HOVI_ENC_KEY_PRD) == NUM_KEYS
|
||||
assert len(HOVI_SIG_KEY_PRD) == NUM_KEYS
|
||||
assert len(IV) == NUM_KEYS
|
|
@ -137,12 +137,12 @@ clean:
|
|||
@echo clean ...
|
||||
@$(MAKE) -C $(AMS)/exosphere/rebootstub clean
|
||||
@$(MAKE) -C key_derivation clean
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).enc $(TARGET).elf
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET)_*.enc $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
.PHONY: all $(OUTPUT).bin
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#define AL16 __attribute__((aligned(16)))
|
||||
|
||||
#define DERIVATION_ID_MAX 1
|
||||
#define DERIVATION_ID_MAX 2
|
||||
|
||||
static const uint8_t AL16 keyblob_seed_00[0x10] = {
|
||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||
|
@ -44,10 +44,12 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
|
|||
|
||||
static const uint8_t AL16 master_kek_seeds[DERIVATION_ID_MAX][0x10] = {
|
||||
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C},
|
||||
{0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41},
|
||||
};
|
||||
|
||||
static const uint8_t AL16 master_devkey_seeds[DERIVATION_ID_MAX][0x10] = {
|
||||
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D},
|
||||
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE},
|
||||
};
|
||||
|
||||
void derive_keys(void) {
|
||||
|
@ -101,7 +103,7 @@ void derive_keys(void) {
|
|||
}
|
||||
|
||||
/* Derive master kek. */
|
||||
decrypt_data_into_keyslot(0xE, 0xE, master_kek_seeds[0], 0x10);
|
||||
decrypt_data_into_keyslot(0xE, 0xE, master_kek_seeds[derivation_id], 0x10);
|
||||
|
||||
/* Derive master key, device master key. */
|
||||
decrypt_data_into_keyslot(0xC, 0xE, masterkey_seed, 0x10);
|
||||
|
@ -123,7 +125,7 @@ void derive_keys(void) {
|
|||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
|
||||
|
||||
/* Derive firmware specific device key. */
|
||||
se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seeds[0], 0x10);
|
||||
se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seeds[derivation_id], 0x10);
|
||||
decrypt_data_into_keyslot(0xE, 0xE, work_buffer, 0x10);
|
||||
|
||||
/* Clear work buffer. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys, os
|
||||
from struct import pack as pk, unpack as up
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Hash import CMAC
|
||||
|
@ -41,7 +41,7 @@ def get_last_block_for_desired_mac(key, data, desired_mac):
|
|||
return last_block
|
||||
|
||||
|
||||
def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac):
|
||||
def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac, version):
|
||||
# Pad with 0x20 of zeroes.
|
||||
code = code + bytearray(0x20)
|
||||
code_len = len(code)
|
||||
|
@ -49,6 +49,9 @@ def sign_encrypt_code(code, sig_key, enc_key, iv, desired_mac):
|
|||
code_len &= ~0xFFF
|
||||
code = code + bytearray(code_len - len(code))
|
||||
|
||||
# Insert version
|
||||
code = code[:8] + pk('<I', version) + code[12:]
|
||||
|
||||
# Add empty trustzone, warmboot segments.
|
||||
code = code + bytearray(0x1FE0 - 0x10)
|
||||
pk11_hdr = b'PK11' + pk('<IIIIIII', 0x1000, 0, 0, code_len - 0x20, 0, 0x1000, 0)
|
||||
|
@ -69,8 +72,10 @@ def main(argc, argv):
|
|||
if len(code) & 0xF:
|
||||
code = code + bytearray(0x10 - (len(code) & 0xF))
|
||||
# TODO: Support dev unit crypto
|
||||
with open(argv[2], 'wb') as f:
|
||||
f.write(sign_encrypt_code(code, KEYS.HOVI_SIG_KEY_PRD, KEYS.HOVI_ENC_KEY_PRD, KEYS.IV, b'THANKS_NVIDIA_<3'))
|
||||
fn, fext = os.path.splitext(argv[2])
|
||||
for key in range(KEYS.NUM_KEYS):
|
||||
with open(fn + ('_%02X' % key) + fext, 'wb') as f:
|
||||
f.write(sign_encrypt_code(code, KEYS.HOVI_SIG_KEY_PRD[key], KEYS.HOVI_ENC_KEY_PRD[key], KEYS.IV[key], b'THANKS_NVIDIA_<3', key))
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#undef u32
|
||||
|
||||
|
||||
void derive_keys(void) {
|
||||
void derive_keys(uint32_t version) {
|
||||
/* Clear mailbox. */
|
||||
volatile uint32_t *mailbox = (volatile uint32_t *)0x4003FF00;
|
||||
while (*mailbox != 0) {
|
||||
|
@ -37,7 +37,7 @@ void derive_keys(void) {
|
|||
}
|
||||
|
||||
/* Set derivation id. */
|
||||
*((volatile uint32_t *)0x4003E800) = 0x0;
|
||||
*((volatile uint32_t *)0x4003E800) = version;
|
||||
|
||||
/* Copy key derivation stub into IRAM high. */
|
||||
for (size_t i = 0; i < key_derivation_bin_size; i += sizeof(uint32_t)) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void derive_keys(void);
|
||||
void derive_keys(uint32_t version);
|
||||
void load_keys(const uint8_t *se_state);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,7 @@ static void set_has_rebooted(bool rebooted) {
|
|||
}
|
||||
|
||||
|
||||
static void exfiltrate_keys_and_reboot_if_needed(void) {
|
||||
static void exfiltrate_keys_and_reboot_if_needed(uint32_t version) {
|
||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||
uint8_t *enc_se_state = (uint8_t *)0x4003E000;
|
||||
uint8_t *dec_se_state = (uint8_t *)0x4003F000;
|
||||
|
@ -59,7 +59,7 @@ static void exfiltrate_keys_and_reboot_if_needed(void) {
|
|||
set_has_rebooted(true);
|
||||
|
||||
/* Derive keys. */
|
||||
derive_keys();
|
||||
derive_keys(version);
|
||||
|
||||
reboot_to_self();
|
||||
} else {
|
||||
|
@ -135,14 +135,14 @@ static void exit_callback(int rc) {
|
|||
relocate_and_chainload();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int sept_main(uint32_t version) {
|
||||
const char *stage2_path;
|
||||
stage2_args_t *stage2_args;
|
||||
uint32_t stage2_version = 0;
|
||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
||||
|
||||
/* Extract keys from the security engine, which TSEC FW locked down. */
|
||||
exfiltrate_keys_and_reboot_if_needed();
|
||||
exfiltrate_keys_and_reboot_if_needed(version);
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(log_level);
|
||||
|
|
|
@ -26,7 +26,12 @@
|
|||
_start:
|
||||
/* Switch to system mode, mask all interrupts, clear all flags */
|
||||
msr cpsr_cxsf, #0xDF
|
||||
b begin_relocation_loop
|
||||
_version:
|
||||
.word 0x00000000 /* Version. */
|
||||
.word 0x00000000 /* Reserved. */
|
||||
|
||||
begin_relocation_loop:
|
||||
/* Relocate ourselves if necessary */
|
||||
ldr r2, =__start__
|
||||
adr r3, _start
|
||||
|
@ -78,7 +83,9 @@ _start:
|
|||
CLEAR_GPR_REG_ITER
|
||||
.endr
|
||||
ldr lr, =__program_exit
|
||||
b main
|
||||
ldr r0, =_version
|
||||
ldr r0, [r0]
|
||||
b sept_main
|
||||
|
||||
/* No need to include this in normal programs: */
|
||||
.section .chainloader.text.start, "ax", %progbits
|
||||
|
|
Loading…
Reference in a new issue