diff --git a/exosphere/src/bootconfig.c b/exosphere/src/bootconfig.c index 476d6643d..c74f81c1b 100644 --- a/exosphere/src/bootconfig.c +++ b/exosphere/src/bootconfig.c @@ -59,6 +59,10 @@ bool bootconfig_is_package2_unsigned(void) { return (LOADED_BOOTCONFIG->signed_config.package2_config & 2) != 0; } +void bootconfig_set_package2_plaintext_and_unsigned(void) { + LOADED_BOOTCONFIG->signed_config.package2_config |= 3; +} + bool bootconfig_disable_program_verification(void) { return LOADED_BOOTCONFIG->signed_config.disable_program_verification != 0; } diff --git a/exosphere/src/bootconfig.h b/exosphere/src/bootconfig.h index c027c140a..1a69a0c68 100644 --- a/exosphere/src/bootconfig.h +++ b/exosphere/src/bootconfig.h @@ -53,6 +53,7 @@ void bootconfig_get_package2_hash_for_recovery(uint64_t *out_hash); /* Actual configuration getters. */ bool bootconfig_is_package2_plaintext(void); bool bootconfig_is_package2_unsigned(void); +void bootconfig_set_package2_plaintext_and_unsigned(void); bool bootconfig_disable_program_verification(void); bool bootconfig_is_debug_mode(void); diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index 6e202a184..17bfb8090 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -267,7 +267,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) { /* 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_400_CURRENT) { + if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_500_CURRENT) { return true; } @@ -297,6 +297,8 @@ static uint32_t decrypt_and_validate_header(package2_header_t *header) { if (mkey_rev > mkey_get_revision()) { panic(0xFAF00003); } + } else if (!validate_package2_metadata(&header->metadata)) { + panic(0xFAF0003); } return 0; } @@ -445,6 +447,11 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { flush_dcache_range((uint8_t *)&header, (uint8_t *)&header + sizeof(header)); /* Perform signature checks. */ + /* Special exosphere patching enable: All-zeroes signature + decrypted header implies unsigned and decrypted package2. */ + if (header.signature[0] == 0 && memcmp(header.signature, header.signature + 1, sizeof(header.signature) - 1) == 0 && header.metadata.magic == MAGIC_PK21) { + bootconfig_set_package2_plaintext_and_unsigned(); + } + verify_header_signature(&header); /* Decrypt header, get key revision required. */ diff --git a/exosphere/src/package2.h b/exosphere/src/package2.h index 80e6ef6cc..d72e7214a 100644 --- a/exosphere/src/package2.h +++ b/exosphere/src/package2.h @@ -48,13 +48,15 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(void) { #define PACKAGE2_MAXVER_200 0x3 #define PACKAGE2_MAXVER_300 0x4 #define PACKAGE2_MAXVER_302 0x5 -#define PACKAGE2_MAXVER_400_CURRENT 0x6 +#define PACKAGE2_MAXVER_400_410 0x6 +#define PACKAGE2_MAXVER_500_CURRENT 0x7 #define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_300 0x5 #define PACKAGE2_MINVER_302 0x6 -#define PACKAGE2_MINVER_400_CURRENT 0x7 +#define PACKAGE2_MINVER_400_410 0x7 +#define PACKAGE2_MINVER_500_CURRENT 0x8 typedef struct { union {