diff --git a/.gitignore b/.gitignore index 8b2f17d..2c5357a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,6 @@ host/nxdumptool *.exe *.code-workspace -# TODO: remove these entries when we're done using PoCs. +# TODO: remove this after the PoC builds are no longer needed. main.cpp /code_templates/tmp/* diff --git a/include/core/cnmt.h b/include/core/cnmt.h index 3eca57d..87bbf0e 100644 --- a/include/core/cnmt.h +++ b/include/core/cnmt.h @@ -41,7 +41,8 @@ typedef enum { } ContentMetaAttribute; typedef enum { - ContentMetaInstallState_Committed = BIT(0) + ContentMetaInstallState_Committed = BIT(0), + ContentMetaInstallState_Count = 1 ///< Total values supported by this enum. } ContentMetaInstallState; /// Extended variation of NcmContentMetaHeader. This is essentially the start of every CNMT file. @@ -96,12 +97,17 @@ typedef struct { NXDT_ASSERT(ContentMetaPatchMetaExtendedHeader, 0x18); +typedef enum { + ContentMetaContentAccessibility_Individual = BIT(0), + ContentMetaContentAccessibility_Count = 1 ///< Total values supported by this enum. +} ContentMetaContentAccessibility; + /// Extended header for AddOnContent tiles (15.0.0+). /// Equivalent to NcmAddOnContentMetaExtendedHeader, but using a Version struct. typedef struct { u64 application_id; Version required_application_version; - u8 content_accessibilities; /// TODO: find out purpose / how to use? + u8 content_accessibility; ///< ContentMetaContentAccessibility. u8 reserved[0x3]; u64 data_patch_id; } ContentMetaAddOnContentMetaExtendedHeader; diff --git a/include/core/nacp.h b/include/core/nacp.h index 8e00093..4a4e8ea 100644 --- a/include/core/nacp.h +++ b/include/core/nacp.h @@ -260,9 +260,9 @@ typedef enum { } NacpRuntimeUpgrade; typedef enum { - NacpSupportingLimitedLicenses_Demo = BIT(0), - NacpSupportingLimitedLicenses_Count = 1 ///< Total values supported by this enum. -} NacpSupportingLimitedLicenses; + NacpSupportingLimitedApplicationLicenses_Demo = BIT(0), + NacpSupportingLimitedApplicationLicenses_Count = 1 ///< Total values supported by this enum. +} NacpSupportingLimitedApplicationLicenses; typedef enum { NacpPlayLogQueryCapability_None = 0, @@ -392,7 +392,7 @@ typedef struct { u16 cache_storage_index_max; u8 reserved_1; u8 runtime_upgrade; ///< NacpRuntimeUpgrade. - u32 supporting_limited_licenses; ///< NacpSupportingLimitedLicenses. + u32 supporting_limited_application_licenses; ///< NacpSupportingLimitedApplicationLicenses. u64 play_log_queryable_application_id[0x10]; u8 play_log_query_capability; ///< NacpPlayLogQueryCapability. u8 repair; ///< NacpRepair. diff --git a/include/core/nca.h b/include/core/nca.h index 1850276..2828f7a 100644 --- a/include/core/nca.h +++ b/include/core/nca.h @@ -92,7 +92,8 @@ typedef enum { NcaKeyGeneration_Since1300NUP = 13, ///< 13.0.0 - 13.2.1. NcaKeyGeneration_Since1400NUP = 14, ///< 14.0.0 - 14.1.2. NcaKeyGeneration_Since1500NUP = 15, ///< 15.0.0 - 15.0.1. - NcaKeyGeneration_Current = NcaKeyGeneration_Since1500NUP, + NcaKeyGeneration_Since1600NUP = 16, ///< 16.0.0 - 16.0.1. + NcaKeyGeneration_Current = NcaKeyGeneration_Since1600NUP, NcaKeyGeneration_Max = 32 } NcaKeyGeneration; @@ -107,7 +108,7 @@ typedef enum { /// TODO: update on signature keygen changes. typedef enum { NcaSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1. - NcaSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.2. + NcaSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 16.0.1. NcaSignatureKeyGeneration_Current = NcaSignatureKeyGeneration_Since900NUP, NcaSignatureKeyGeneration_Max = (NcaSignatureKeyGeneration_Current + 1) } NcaSignatureKeyGeneration; @@ -176,7 +177,7 @@ typedef enum { typedef enum { NcaHashType_Auto = 0, - NcaHashType_None = 1, + NcaHashType_None = 1, ///< Possibly used by all filesystem types. NcaHashType_HierarchicalSha256 = 2, ///< Used by NcaFsType_PartitionFs. NcaHashType_HierarchicalIntegrity = 3, ///< Used by NcaFsType_RomFs. NcaHashType_AutoSha3 = 4, diff --git a/include/core/npdm.h b/include/core/npdm.h index 5f89ac1..052288f 100644 --- a/include/core/npdm.h +++ b/include/core/npdm.h @@ -43,7 +43,7 @@ extern "C" { /// TODO: update on signature keygen changes. typedef enum { NpdmSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1. - NpdmSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.2. + NpdmSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 16.0.1. NpdmSignatureKeyGeneration_Current = NpdmSignatureKeyGeneration_Since900NUP, NpdmSignatureKeyGeneration_Max = (NpdmSignatureKeyGeneration_Current + 1) } NpdmSignatureKeyGeneration; diff --git a/romfs/i18n/en-US/about_tab.json b/romfs/i18n/en-US/about_tab.json index a9df19d..f75d349 100644 --- a/romfs/i18n/en-US/about_tab.json +++ b/romfs/i18n/en-US/about_tab.json @@ -20,7 +20,7 @@ "line_03": "\uE016 Adubbz, for Tinfoil and its ES service bindings.", "line_04": "\uE016 RattletraPM, for the awesome icon.", "line_05": "\uE016 Whovian9369, for being a key piece throughout the whole development by providing lots of testing and cool ideas.", - "line_06": "\uE016 0Liam, Shadów and SimonTime, for their tremendous help in understanding Nintendo Switch file and data formats.", + "line_06": "\uE016 liamadvance, Shadów and SimonTime, for their tremendous help in understanding Nintendo Switch file and data formats.", "line_07": "\uE016 The folks from NSWDB.COM and No-Intro.org, for being kind enough to put up public APIs to perform online checksum lookups.", "line_08": "\uE016 The folks at the nxdumptool Discord server.", "line_09": "\uE016 The Comfy Boyes, for always being awesome and supportive. You know who you are.", diff --git a/romfs/i18n/en-US/options_tab.json b/romfs/i18n/en-US/options_tab.json index 38b3988..4460c54 100644 --- a/romfs/i18n/en-US/options_tab.json +++ b/romfs/i18n/en-US/options_tab.json @@ -3,7 +3,7 @@ "overclock": { "label": "Overclock", - "description": "Overclocks both CPU and MEM to 1785 MHz and 1600 MHz, respectively, in order to speed up dump operations. This is considered a relatively safe action.\n\nIf the application is running under title override mode, and sys-clk is active, and a clock profile has been created for the overridden title, this setting has no effect at all." + "description": "Overclocks both CPU and MEM exclusively while a dump operation is running, in order to speed it up. This is considered a relatively safe action.\n\nIf the application is running under title override mode, and sys-clk is active, and a clock profile has been created for the overridden title, this setting has no effect at all." }, "naming_convention": { diff --git a/source/core/cnmt.c b/source/core/cnmt.c index 028eada..09b1a20 100644 --- a/source/core/cnmt.c +++ b/source/core/cnmt.c @@ -192,7 +192,7 @@ bool cnmtInitializeContext(ContentMetaContext *out, NcaContext *nca_ctx) case NcmContentMetaType_DataPatch: invalid_ext_header_size = (out->packaged_header->extended_header_size != (u16)sizeof(ContentMetaDataPatchMetaExtendedHeader)); out->extended_data_size = (!invalid_ext_header_size ? ((ContentMetaDataPatchMetaExtendedHeader*)out->extended_header)->extended_data_size : 0); - invalid_ext_data_size = (out->extended_data_size <= sizeof(ContentMetaPatchMetaExtendedDataHeader)); // TODO: check if this is right. + invalid_ext_data_size = (out->extended_data_size <= sizeof(ContentMetaPatchMetaExtendedDataHeader)); break; default: invalid_ext_header_size = (out->packaged_header->extended_header_size != 0); diff --git a/source/core/keys.c b/source/core/keys.c index da2fa65..06e124f 100644 --- a/source/core/keys.c +++ b/source/core/keys.c @@ -51,8 +51,7 @@ typedef struct { ///< AES-128-XTS key needed to handle NCA header crypto. u8 nca_header_kek_source[AES_128_KEY_SIZE]; ///< Retrieved from the .rodata segment in the FS sysmodule. u8 nca_header_key_source[AES_128_KEY_SIZE * 2]; ///< Retrieved from the .data segment in the FS sysmodule. - u8 nca_header_kek_sealed[AES_128_KEY_SIZE]; ///< Generated from nca_header_kek_source. Sealed by the SMC AES engine. - u8 nca_header_key[AES_128_KEY_SIZE * 2]; ///< Generated from nca_header_kek_sealed and nca_header_key_source. + u8 nca_header_key[AES_128_KEY_SIZE * 2]; ///< Generated from nca_header_kek (sealed by the SMC AES engine) and nca_header_key_source. ///< RSA-2048-PSS moduli used to verify the main signature from NCA headers. u8 nca_main_signature_moduli_prod[NcaSignatureKeyGeneration_Max][RSA2048_PUBKEY_SIZE]; ///< Moduli used in retail units. Retrieved from the .rodata segment in the FS sysmodule. @@ -92,10 +91,8 @@ typedef struct { const u8 gc_cardinfo_kek_source[AES_128_KEY_SIZE]; ///< Randomly generated KEK source to decrypt official CardInfo area keys. const u8 gc_cardinfo_key_prod_source[AES_128_KEY_SIZE]; ///< CardInfo area key used in retail units. Obfuscated using the above KEK source and SMC AES engine keydata. const u8 gc_cardinfo_key_dev_source[AES_128_KEY_SIZE]; ///< CardInfo area key used in development units. Obfuscated using the above KEK source and SMC AES engine keydata. - - u8 gc_cardinfo_kek_sealed[AES_128_KEY_SIZE]; ///< Generated from gc_cardinfo_kek_source. Sealed by the SMC AES engine. - u8 gc_cardinfo_key_prod[AES_128_KEY_SIZE]; ///< Generated from gc_cardinfo_kek_sealed and gc_cardinfo_key_prod_source. - u8 gc_cardinfo_key_dev[AES_128_KEY_SIZE]; ///< Generated from gc_cardinfo_kek_sealed and gc_cardinfo_key_dev_source. + u8 gc_cardinfo_key_prod[AES_128_KEY_SIZE]; ///< Generated from gc_cardinfo_kek (sealed by the SMC AES engine) and gc_cardinfo_key_prod_source. + u8 gc_cardinfo_key_dev[AES_128_KEY_SIZE]; ///< Generated from gc_cardinfo_kek (sealed by the SMC AES engine) and gc_cardinfo_key_dev_source. } KeysGameCardKeyset; /* Function prototypes. */ @@ -123,6 +120,8 @@ static bool keysTestEticketRsaDeviceKey(const void *e, const void *d, const void static bool keysDeriveGameCardKeys(void); +static bool keysGenerateAesKey(const u8 *kek_source, const u8 *key_source, u32 key_generation, u32 option, u8 *out_key); + /* Global variables. */ static bool g_keysetLoaded = false; @@ -136,36 +135,36 @@ static const u8 g_ncaKaekBlockHashes[2][NcaKeyAreaEncryptionKeyIndex_Count][SHA2 { /* Application. */ { - 0xBD, 0x19, 0x22, 0x4B, 0xC4, 0x72, 0x0E, 0xAD, 0x9D, 0x5D, 0x99, 0x69, 0xEF, 0xF4, 0x91, 0x34, - 0x27, 0x73, 0xD6, 0x74, 0x62, 0xA3, 0xF9, 0x2D, 0x07, 0xB2, 0xAE, 0x6B, 0x19, 0xA9, 0xE2, 0x85 + 0xAE, 0x82, 0xD8, 0xE5, 0x1A, 0xC3, 0x5F, 0xC0, 0xBF, 0xE1, 0xC0, 0x88, 0x69, 0xB9, 0x69, 0xCE, + 0x56, 0xD4, 0x99, 0xE6, 0x97, 0x80, 0xFE, 0x1C, 0x3D, 0xB7, 0xEA, 0x9C, 0xD8, 0xD7, 0xF2, 0x12 }, /* Ocean. */ { - 0xC7, 0xC7, 0x5B, 0xB0, 0x9D, 0x4D, 0x46, 0xAA, 0xE8, 0xDB, 0xF6, 0x6D, 0x24, 0xEA, 0x41, 0x61, - 0x9F, 0x6D, 0x19, 0x2B, 0x3B, 0x79, 0x3F, 0x1B, 0x49, 0x60, 0x3D, 0xA9, 0x69, 0x84, 0xE5, 0x4D + 0x6F, 0xE0, 0x38, 0xC2, 0xAF, 0xB8, 0xF7, 0xDC, 0xC4, 0x97, 0x0A, 0x19, 0xCC, 0xE7, 0xD3, 0x10, + 0x03, 0x70, 0x2C, 0xF5, 0x51, 0xF1, 0x01, 0xDE, 0x88, 0x4E, 0x47, 0xD3, 0x8D, 0xC2, 0xFD, 0x8A }, /* System. */ { - 0xFE, 0x02, 0x86, 0x80, 0x8F, 0x88, 0x86, 0x3D, 0x64, 0x53, 0xFB, 0x64, 0xED, 0x2B, 0x51, 0xDA, - 0x5A, 0xE2, 0x22, 0x44, 0x00, 0x15, 0x33, 0xBA, 0xD1, 0xA4, 0xBE, 0xA2, 0xC0, 0x5E, 0x38, 0xF5 + 0x2F, 0xEB, 0xA2, 0x09, 0x42, 0x51, 0xB5, 0x88, 0x3D, 0x52, 0x3E, 0xE6, 0x47, 0x7F, 0xDD, 0xFD, + 0x3F, 0xB2, 0x7B, 0xED, 0xBA, 0x8C, 0x98, 0x34, 0xA2, 0xF9, 0xA9, 0x5A, 0x81, 0x1A, 0x7E, 0xA9 } }, /* Development. */ { /* Application. */ { - 0x6B, 0xD0, 0x5E, 0x57, 0x62, 0xD8, 0xD6, 0xBB, 0x00, 0xAD, 0xC0, 0xD7, 0x00, 0x94, 0x9F, 0xFF, - 0xF9, 0x03, 0x45, 0xA3, 0x07, 0x93, 0xCB, 0xF3, 0x7B, 0xF1, 0x9E, 0xC3, 0x4B, 0xA2, 0x52, 0xAE + 0xD5, 0x28, 0x5F, 0xDB, 0x38, 0x6D, 0x0E, 0x3C, 0xA1, 0x14, 0x6F, 0x4D, 0x32, 0xA6, 0x22, 0x23, + 0x8D, 0xD7, 0x81, 0xAF, 0x68, 0x71, 0x76, 0x06, 0x8B, 0x71, 0xC3, 0x87, 0x83, 0x4B, 0x86, 0xC8 }, /* Ocean. */ { - 0x56, 0x00, 0xAD, 0x5E, 0x8F, 0xEA, 0xD3, 0x24, 0x23, 0xDC, 0x81, 0xDB, 0x0F, 0xF9, 0xDF, 0x18, - 0xD8, 0x8E, 0xC4, 0xC9, 0x0B, 0x3F, 0x42, 0x64, 0xD2, 0xD4, 0x3D, 0xE0, 0x38, 0xFD, 0x53, 0xC1 + 0x76, 0xD4, 0xD7, 0x1C, 0xAA, 0x19, 0x97, 0x5B, 0x74, 0xAE, 0xFF, 0x2D, 0xEA, 0x27, 0x1B, 0xC6, + 0xED, 0xF7, 0xB5, 0xD0, 0xA3, 0xFF, 0xE7, 0xEA, 0x1A, 0x99, 0xB3, 0x8C, 0xDD, 0x4F, 0xAB, 0x5C }, /* System. */ { - 0x7B, 0x00, 0x0F, 0x31, 0x59, 0x36, 0x3A, 0x0E, 0xC5, 0x28, 0x4F, 0xE8, 0x73, 0x04, 0x4E, 0x7F, - 0xDC, 0x8C, 0xA4, 0x30, 0x88, 0xFF, 0x1F, 0xDB, 0x6B, 0x58, 0x71, 0xDA, 0xF8, 0xF0, 0x0B, 0xD6 + 0x46, 0x5E, 0xB1, 0x43, 0x37, 0x83, 0x52, 0x84, 0x73, 0x08, 0xCA, 0x9D, 0xDE, 0x64, 0x8C, 0x76, + 0x58, 0xB3, 0x9A, 0x42, 0xF1, 0xC5, 0xA9, 0x60, 0xA6, 0xED, 0xF3, 0xB8, 0xAA, 0x44, 0xEF, 0x41 } } }; @@ -174,13 +173,13 @@ static const u8 g_ncaKaekBlockHashes[2][NcaKeyAreaEncryptionKeyIndex_Count][SHA2 static const u8 g_ticketCommonKeysBlockHashes[2][SHA256_HASH_SIZE] = { /* Production. */ { - 0xF3, 0x0D, 0x51, 0x85, 0x9F, 0x70, 0x66, 0x75, 0x79, 0x53, 0x6B, 0x2B, 0xFD, 0x29, 0x53, 0xEC, - 0x7A, 0x25, 0xF7, 0x41, 0x92, 0xE4, 0xC7, 0x21, 0x82, 0x73, 0x46, 0x74, 0x82, 0xB3, 0x48, 0x07 + 0x6F, 0x42, 0x8A, 0x53, 0x51, 0x61, 0xC7, 0x69, 0x90, 0x21, 0xC5, 0x71, 0xC6, 0x89, 0x2B, 0x33, + 0xBB, 0x1D, 0xF6, 0xA8, 0x26, 0x12, 0x21, 0x7D, 0x81, 0x9B, 0xCC, 0x78, 0x3A, 0x2D, 0xD7, 0x6C }, /* Development. */ { - 0x0A, 0x94, 0x77, 0x9F, 0xE2, 0x86, 0x33, 0xF4, 0x91, 0x84, 0xE9, 0x88, 0x56, 0xAA, 0xA4, 0x6C, - 0x12, 0x55, 0x62, 0x64, 0x21, 0x2E, 0xAD, 0x41, 0x36, 0x22, 0xDC, 0x3A, 0xA7, 0x22, 0xFC, 0x3C + 0x88, 0x61, 0x4D, 0x1E, 0xC3, 0xF0, 0x51, 0x94, 0xB7, 0x35, 0xAA, 0x2E, 0xFC, 0x4D, 0x7A, 0x7C, + 0xFB, 0x25, 0x8A, 0x0C, 0x60, 0x68, 0x89, 0x04, 0x68, 0xAB, 0x21, 0xA0, 0x34, 0x29, 0x02, 0xE9 } }; @@ -304,7 +303,6 @@ static KeysGameCardKeyset g_gameCardKeyset = { .gc_cardinfo_kek_source = { 0xDE, 0xC6, 0x3F, 0x6A, 0xBF, 0x37, 0x72, 0x0B, 0x7E, 0x54, 0x67, 0x6A, 0x2D, 0xEF, 0xDD, 0x97 }, .gc_cardinfo_key_prod_source = { 0xF4, 0x92, 0x06, 0x52, 0xD6, 0x37, 0x70, 0xAF, 0xB1, 0x9C, 0x6F, 0x63, 0x09, 0x01, 0xF6, 0x29 }, .gc_cardinfo_key_dev_source = { 0x0B, 0x7D, 0xBB, 0x2C, 0xCF, 0x64, 0x1A, 0xF4, 0xD7, 0x38, 0x81, 0x3F, 0x0C, 0x33, 0xF4, 0x1C }, - .gc_cardinfo_kek_sealed = {0}, .gc_cardinfo_key_prod = {0}, .gc_cardinfo_key_dev = {0} }; @@ -618,28 +616,17 @@ end: static bool keysDeriveNcaHeaderKey(void) { - Result rc = 0; - - /* Derive nca_header_kek_sealed from nca_header_kek_source. */ - rc = splCryptoGenerateAesKek(g_ncaKeyset.nca_header_kek_source, 0, 0, g_ncaKeyset.nca_header_kek_sealed); - if (R_FAILED(rc)) + /* Derive nca_header_key (first half) from nca_header_kek_source and nca_header_key_source. */ + if (!keysGenerateAesKey(g_ncaKeyset.nca_header_kek_source, g_ncaKeyset.nca_header_key_source, 0, 0, g_ncaKeyset.nca_header_key)) { - LOG_MSG_ERROR("splCryptoGenerateAesKek failed! (0x%X) (nca_header_kek_sealed).", rc); + LOG_MSG_ERROR("keysGenerateAesKey failed! (#1)."); return false; } - /* Derive nca_header_key from nca_header_kek_sealed and nca_header_key_source. */ - rc = splCryptoGenerateAesKey(g_ncaKeyset.nca_header_kek_sealed, g_ncaKeyset.nca_header_key_source, g_ncaKeyset.nca_header_key); - if (R_FAILED(rc)) + /* Derive nca_header_key (second half) from nca_header_kek_source and nca_header_key_source. */ + if (!keysGenerateAesKey(g_ncaKeyset.nca_header_kek_source, g_ncaKeyset.nca_header_key_source + AES_128_KEY_SIZE, 0, 0, g_ncaKeyset.nca_header_key + AES_128_KEY_SIZE)) { - LOG_MSG_ERROR("splCryptoGenerateAesKey failed! (0x%X) (nca_header_key) (#1).", rc); - return false; - } - - rc = splCryptoGenerateAesKey(g_ncaKeyset.nca_header_kek_sealed, g_ncaKeyset.nca_header_key_source + AES_128_KEY_SIZE, g_ncaKeyset.nca_header_key + AES_128_KEY_SIZE); - if (R_FAILED(rc)) - { - LOG_MSG_ERROR("splCryptoGenerateAesKey failed! (0x%X) (nca_header_key) (#2).", rc); + LOG_MSG_ERROR("keysGenerateAesKey failed! (#2)."); return false; } @@ -1146,29 +1133,48 @@ static bool keysTestEticketRsaDeviceKey(const void *e, const void *d, const void static bool keysDeriveGameCardKeys(void) { - Result rc = 0; - - /* Derive gc_cardinfo_kek_sealed from gc_cardinfo_kek_source. */ - rc = splCryptoGenerateAesKek(g_gameCardKeyset.gc_cardinfo_kek_source, 0, 0, g_gameCardKeyset.gc_cardinfo_kek_sealed); - if (R_FAILED(rc)) + /* Derive gc_cardinfo_key_prod from gc_cardinfo_kek_source and gc_cardinfo_key_prod_source. */ + if (!keysGenerateAesKey(g_gameCardKeyset.gc_cardinfo_kek_source, g_gameCardKeyset.gc_cardinfo_key_prod_source, 0, 0, g_gameCardKeyset.gc_cardinfo_key_prod)) { - LOG_MSG_ERROR("splCryptoGenerateAesKek failed! (0x%X) (gc_cardinfo_kek_sealed).", rc); + LOG_MSG_ERROR("keysGenerateAesKey failed! (prod)."); return false; } - /* Derive gc_cardinfo_key_prod from gc_cardinfo_kek_sealed and gc_cardinfo_key_prod_source. */ - rc = splCryptoGenerateAesKey(g_gameCardKeyset.gc_cardinfo_kek_sealed, g_gameCardKeyset.gc_cardinfo_key_prod_source, g_gameCardKeyset.gc_cardinfo_key_prod); - if (R_FAILED(rc)) + /* Derive gc_cardinfo_key_dev from gc_cardinfo_kek_source and gc_cardinfo_key_dev_source. */ + if (!keysGenerateAesKey(g_gameCardKeyset.gc_cardinfo_kek_source, g_gameCardKeyset.gc_cardinfo_key_dev_source, 0, 0, g_gameCardKeyset.gc_cardinfo_key_dev)) { - LOG_MSG_ERROR("splCryptoGenerateAesKey failed! (0x%X) (gc_cardinfo_key_prod).", rc); - return false; - } - - /* Derive gc_cardinfo_key_dev from gc_cardinfo_kek_sealed and gc_cardinfo_key_dev_source. */ - rc = splCryptoGenerateAesKey(g_gameCardKeyset.gc_cardinfo_kek_sealed, g_gameCardKeyset.gc_cardinfo_key_dev_source, g_gameCardKeyset.gc_cardinfo_key_dev); - if (R_FAILED(rc)) - { - LOG_MSG_ERROR("splCryptoGenerateAesKey failed! (0x%X) (gc_cardinfo_key_dev).", rc); + LOG_MSG_ERROR("keysGenerateAesKey failed! (dev)."); + return false; + } + + return true; +} + +/* Wrapper for GenerateAesKek + GenerateAesKey SMC AES engine calls. */ +static bool keysGenerateAesKey(const u8 *kek_source, const u8 *key_source, u32 key_generation, u32 option, u8 *out_key) +{ + if (!kek_source || !key_source || key_generation >= NcaKeyGeneration_Max || !out_key) + { + LOG_MSG_ERROR("Invalid parameters!"); + return false; + } + + Result rc = 0; + u8 sealed_kek[AES_128_KEY_SIZE] = {0}; + + /* Derive sealed_kek from kek_source. */ + rc = splCryptoGenerateAesKek(kek_source, key_generation, option, sealed_kek); + if (R_FAILED(rc)) + { + LOG_MSG_ERROR("splCryptoGenerateAesKek failed! (0x%X).", rc); + return false; + } + + /* Derive out_key from sealed_kek and key_source. */ + rc = splCryptoGenerateAesKey(sealed_kek, key_source, out_key); + if (R_FAILED(rc)) + { + LOG_MSG_ERROR("splCryptoGenerateAesKey failed! (0x%X).", rc); return false; } diff --git a/source/core/nacp.c b/source/core/nacp.c index 69e8263..1d67a12 100644 --- a/source/core/nacp.c +++ b/source/core/nacp.c @@ -507,7 +507,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir /* StartupUserAccountOption. */ if (!NACP_ADD_BITFLAG("StartupUserAccountOption", &(nacp->startup_user_account_option), sizeof(nacp->startup_user_account_option), NacpStartupUserAccountOption_Count, \ - nacpGetStartupUserAccountOptionString, true)) goto end; + nacpGetStartupUserAccountOptionString, false)) goto end; /* UserAccountSwitchLock. */ if (!NACP_ADD_ENUM("UserAccountSwitchLock", nacp->user_account_switch_lock, nacpGetUserAccountSwitchLockString)) goto end; @@ -838,7 +838,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir if (!NACP_ADD_ENUM("UndecidedParameter75b8b", nacp->undecided_parameter_75b8b, nacpGetUndecidedParameter75b8bString)) goto end; /* ApplicationId. */ - if (!NACP_ADD_U64("ApplicationId", nacp_ctx->nca_ctx->header.program_id, true, true)) goto end; + //if (!NACP_ADD_U64("ApplicationId", nacp_ctx->nca_ctx->header.program_id, true, true)) goto end; /* FilterDescriptionFilePath and CompressionFileConfigurationFilePath. */ /*if (!NACP_ADD_FMT_STR_T1(" \n" \ @@ -847,15 +847,15 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir /* ContentsAvailabilityTransitionPolicy. */ if (!NACP_ADD_ENUM("ContentsAvailabilityTransitionPolicy", nacp->contents_availability_transition_policy, nacpGetContentsAvailabilityTransitionPolicyString)) goto end; - /* LimitedLicenseSettings. */ - if (!NACP_ADD_FMT_STR_T1(" \n" \ + /* LimitedApplicationLicenseSettings. */ + if (!NACP_ADD_FMT_STR_T1(" \n" \ " %s\n" \ - " \n" \ - " %s\n" \ - " \n" \ - " \n", \ + " \n" \ + " %s\n" \ + " \n" \ + " \n", \ nacpGetRuntimeUpgradeString(nacp->runtime_upgrade), \ - (nacp->supporting_limited_licenses & NacpSupportingLimitedLicenses_Demo) ? "Demo" : "None")) goto end; + (nacp->supporting_limited_application_licenses & NacpSupportingLimitedApplicationLicenses_Demo) ? "Demo" : "None")) goto end; if (!(success = NACP_ADD_FMT_STR_T1(""))) goto end; diff --git a/source/core/nca.c b/source/core/nca.c index 07d0256..d22ac8f 100644 --- a/source/core/nca.c +++ b/source/core/nca.c @@ -870,12 +870,12 @@ static bool ncaInitializeFsSectionContext(NcaContext *nca_ctx, u32 section_idx) } /* Determine FS section type. */ - /* TODO: should NcaHashType_None be handled here as well? */ switch(fs_ctx->header.fs_type) { case NcaFsType_PartitionFs: - if ((fs_ctx->hash_type == NcaHashType_HierarchicalSha256 || fs_ctx->hash_type == NcaHashType_HierarchicalSha3256) && \ - (fs_ctx->encryption_type < NcaEncryptionType_AesCtrEx || fs_ctx->encryption_type == NcaEncryptionType_AesCtrSkipLayerHash)) + if ((fs_ctx->hash_type == NcaHashType_None && fs_ctx->encryption_type < NcaEncryptionType_AesCtrEx) || \ + ((fs_ctx->hash_type == NcaHashType_HierarchicalSha256 || fs_ctx->hash_type == NcaHashType_HierarchicalSha3256) && \ + (fs_ctx->encryption_type < NcaEncryptionType_AesCtrEx || fs_ctx->encryption_type == NcaEncryptionType_AesCtrSkipLayerHash))) { /* Partition FS with None, XTS or CTR encryption. */ fs_ctx->section_type = NcaFsSectionType_PartitionFs; @@ -883,24 +883,24 @@ static bool ncaInitializeFsSectionContext(NcaContext *nca_ctx, u32 section_idx) break; case NcaFsType_RomFs: - if (fs_ctx->hash_type == NcaHashType_HierarchicalIntegrity || fs_ctx->hash_type == NcaHashType_HierarchicalIntegritySha3) + if (fs_ctx->hash_type == NcaHashType_None || fs_ctx->hash_type == NcaHashType_HierarchicalIntegrity || fs_ctx->hash_type == NcaHashType_HierarchicalIntegritySha3) { if (fs_ctx->has_patch_indirect_layer && fs_ctx->has_patch_aes_ctr_ex_layer && \ (fs_ctx->encryption_type == NcaEncryptionType_None || fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx || \ - fs_ctx->encryption_type == NcaEncryptionType_AesCtrExSkipLayerHash)) + (fs_ctx->encryption_type == NcaEncryptionType_AesCtrExSkipLayerHash && fs_ctx->hash_type != NcaHashType_None))) { /* Patch RomFS. */ fs_ctx->section_type = NcaFsSectionType_PatchRomFs; } else if (!fs_ctx->has_patch_indirect_layer && !fs_ctx->has_patch_aes_ctr_ex_layer && \ ((fs_ctx->encryption_type >= NcaEncryptionType_None && fs_ctx->encryption_type <= NcaEncryptionType_AesCtr) || \ - fs_ctx->encryption_type == NcaEncryptionType_AesCtrSkipLayerHash)) + (fs_ctx->encryption_type == NcaEncryptionType_AesCtrSkipLayerHash && fs_ctx->hash_type != NcaHashType_None))) { /* Regular RomFS. */ fs_ctx->section_type = NcaFsSectionType_RomFs; } } else - if (nca_ctx->format_version == NcaVersion_Nca0 && fs_ctx->hash_type == NcaHashType_HierarchicalSha256) + if (fs_ctx->hash_type == NcaHashType_HierarchicalSha256 && nca_ctx->format_version == NcaVersion_Nca0) { /* NCA0 RomFS with XTS encryption. */ fs_ctx->section_type = NcaFsSectionType_Nca0RomFs; diff --git a/source/core/title.c b/source/core/title.c index 4516415..7fd86ab 100644 --- a/source/core/title.c +++ b/source/core/title.c @@ -119,7 +119,7 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x0100000000000007, "htc" }, { 0x0100000000000008, "boot2" }, { 0x0100000000000009, "settings" }, - { 0x010000000000000A, "bus" }, + { 0x010000000000000A, "Bus" }, { 0x010000000000000B, "bluetooth" }, { 0x010000000000000C, "bcat" }, { 0x010000000000000D, "dmnt" }, @@ -176,8 +176,20 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x0100000000000040, "nd" }, { 0x0100000000000041, "ngct" }, { 0x0100000000000042, "pgl" }, + { 0x0100000000000043, "sys_applet_unknown_00" }, ///< Placeholder. + { 0x0100000000000044, "sys_applet_unknown_01" }, ///< Placeholder. { 0x0100000000000045, "omm" }, { 0x0100000000000046, "eth" }, + { 0x0100000000000047, "sys_applet_unknown_02" }, ///< Placeholder. + { 0x0100000000000048, "sys_applet_unknown_03" }, ///< Placeholder. + { 0x0100000000000049, "sys_applet_unknown_04" }, ///< Placeholder. + { 0x010000000000004A, "sys_applet_unknown_05" }, ///< Placeholder. + { 0x010000000000004B, "sys_applet_unknown_06" }, ///< Placeholder. + { 0x010000000000004C, "sys_applet_unknown_07" }, ///< Placeholder. + { 0x010000000000004D, "sys_applet_unknown_08" }, ///< Placeholder. + { 0x010000000000004E, "sys_applet_unknown_09" }, ///< Placeholder. + { 0x010000000000004F, "sys_applet_unknown_0a" }, ///< Placeholder. + { 0x0100000000000050, "ngc" }, /* System data archives. */ /* Meta + Data NCAs. */ @@ -225,6 +237,7 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x0100000000000830, "NgWordT" }, { 0x0100000000000831, "PlatformConfigAula" }, { 0x0100000000000832, "CradleFirmwareAula" }, ///< Placeholder. + { 0x0100000000000835, "NewErrorMessage" }, ///< Placeholder. /* System applets. */ /* Meta + Program NCAs. */ @@ -249,7 +262,7 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x0100000000001012, "starter" }, { 0x0100000000001013, "myPage" }, { 0x0100000000001014, "PlayReport" }, - { 0x0100000000001015, "MaintenanceMenu" }, + { 0x0100000000001015, "maintenance" }, { 0x0100000000001016, "application_install" }, ///< Placeholder. { 0x0100000000001017, "nn.am.SystemReportTask" }, ///< Placeholder. { 0x0100000000001018, "systemupdate_dl_throughput" }, ///< Placeholder. @@ -258,28 +271,34 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x010000000000101B, "DummyECApplet" }, { 0x010000000000101C, "userMigration" }, { 0x010000000000101D, "EncounterSys" }, - { 0x010000000000101E, "pearljam" }, ///< Placeholder. - { 0x010000000000101F, "nim_glue_unknown" }, ///< Placeholder. + { 0x010000000000101E, "nim_unknown_00" }, ///< Placeholder. + { 0x010000000000101F, "nim_glue_unknown_00" }, ///< Placeholder. { 0x0100000000001020, "story" }, { 0x0100000000001021, "systemupdate_pass" }, ///< Placeholder. - { 0x0100000000001023, "statistics" }, - { 0x0100000000001024, "syslog" }, - { 0x0100000000001025, "am_unknown_1" }, ///< Placeholder. - { 0x0100000000001026, "olsc_unknown" }, ///< Placeholder. - { 0x0100000000001027, "account_unknown" }, ///< Placeholder. - { 0x0100000000001028, "ns_unknown_1" }, ///< Placeholder. - { 0x010000000000102A, "am_unknown_2" }, ///< Placeholder. - { 0x010000000000102B, "glue_unknown_1" }, ///< Placeholder. - { 0x010000000000102C, "am_unknown_3" }, ///< Placeholder. - { 0x010000000000102E, "blacklist" }, - { 0x010000000000102F, "content_delivery" }, - { 0x0100000000001031, "ns_unknown_2" }, ///< Placeholder. - { 0x0100000000001032, "glue_unknown_2" }, ///< Placeholder. - { 0x0100000000001033, "promotion" }, - { 0x0100000000001034, "ngct_unknown" }, ///< Placeholder. - { 0x0100000000001037, "nim_unknown" }, ///< Placeholder. + { 0x0100000000001023, "statistics" }, ///< Placeholder. + { 0x0100000000001024, "syslog" }, ///< Placeholder. + { 0x0100000000001025, "am_unknown_00" }, ///< Placeholder. + { 0x0100000000001026, "olsc_unknown_00" }, ///< Placeholder. + { 0x0100000000001027, "account_unknown_00" }, ///< Placeholder. + { 0x0100000000001028, "ns_unknown_00" }, ///< Placeholder. + { 0x0100000000001029, "request_count" }, ///< Placeholder. + { 0x010000000000102A, "am_unknown_01" }, ///< Placeholder. + { 0x010000000000102B, "glue_unknown_00" }, ///< Placeholder. + { 0x010000000000102C, "am_unknown_02" }, ///< Placeholder. + { 0x010000000000102E, "blacklist" }, ///< Placeholder. + { 0x010000000000102F, "content_delivery" }, ///< Placeholder. + { 0x0100000000001030, "npns_create_token" }, ///< Placeholder. + { 0x0100000000001031, "ns_unknown_01" }, ///< Placeholder. + { 0x0100000000001032, "glue_unknown_01" }, ///< Placeholder. + { 0x0100000000001033, "promotion" }, ///< Placeholder. + { 0x0100000000001034, "ngct_bcat_unknown_00" }, ///< Placeholder. + { 0x0100000000001037, "nim_unknown_01" }, ///< Placeholder. { 0x0100000000001038, "sample" }, { 0x010000000000103C, "mnpp" }, ///< Placeholder. + { 0x010000000000103D, "bsdsocket_setting" }, ///< Placeholder. + { 0x010000000000103E, "ntf_mission_completed" }, ///< Placeholder. + { 0x0100000000001042, "am_unknown_03" }, ///< Placeholder. + { 0x0100000000001043, "am_unknown_04" }, ///< Placeholder. { 0x0100000000001FFF, "EndOceanProgramId" }, /* Development system applets. */ @@ -361,6 +380,8 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x010000000000211A, "PreinstallAppWriter" }, { 0x010000000000211C, "ControllerSerialFlashTool" }, { 0x010000000000211D, "ControllerFlashWriter" }, + { 0x010000000000211E, "Handling" }, + { 0x010000000000211F, "Hid" }, { 0x0100000000002120, "ControllerTestApp" }, { 0x0100000000002121, "HidInspectionTool" }, { 0x0100000000002124, "BatteryCyclesEditor" }, @@ -375,6 +396,10 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x0100000000002134, "AnalogStickEvaluationTool" }, { 0x010000000000216D, "ExhibitionSaveDataSnapshot" }, ///< Placeholder. { 0x0100000000002178, "SecureStartupSettings" }, ///< Placeholder. + { 0x010000000000217D, "CradleFirmwareUpdater" }, + { 0x0100000000002184, "HttpInstallSettings" }, ///< Placeholder. + { 0x0100000000002187, "ExhibitionMovieAssetData" }, ///< Placeholder. + { 0x0100000000002191, "ExhibitionPlayData" }, ///< Placeholder. /* Debug system modules. */ { 0x0100000000003002, "DummyProcess" }, @@ -383,6 +408,7 @@ static const TitleSystemEntry g_systemTitles[] = { /* Development system modules. */ { 0x010000000000B120, "nvdbgsvc" }, + { 0x010000000000B123, "acc:CORNX" }, { 0x010000000000B14A, "manu" }, { 0x010000000000B14B, "ManuUsbLoopBack" }, { 0x010000000000B1B8, "DevFwdbgHbPackage" }, @@ -398,23 +424,25 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x010000000000C602, "BdkSample03" }, { 0x010000000000C603, "BdkSample04" }, - /* Micro system modules. */ + /* New development system modules. */ { 0x010000000000D609, "dmnt.gen2" }, - { 0x010000000000D60A, "msm_unknown_1" }, ///< Placeholder. - { 0x010000000000D60B, "msm_unknown_3" }, ///< Placeholder. - { 0x010000000000D60C, "msm_unknown_3" }, ///< Placeholder. - { 0x010000000000D60D, "msm_unknown_4" }, ///< Placeholder. - { 0x010000000000D60E, "msm_unknown_5" }, ///< Placeholder. - { 0x010000000000D610, "msm_unknown_6" }, ///< Placeholder. - { 0x010000000000D611, "msm_unknown_7" }, ///< Placeholder. - { 0x010000000000D612, "msm_unknown_8" }, ///< Placeholder. - { 0x010000000000D613, "msm_unknown_9" }, ///< Placeholder. - { 0x010000000000D614, "msm_unknown_10" }, ///< Placeholder. - { 0x010000000000D615, "msm_unknown_11" }, ///< Placeholder. - { 0x010000000000D616, "msm_unknown_12" }, ///< Placeholder. - { 0x010000000000D617, "msm_unknown_13" }, ///< Placeholder. - { 0x010000000000D619, "msm_unknown_14" }, ///< Placeholder. + { 0x010000000000D60A, "msm_unknown_00" }, ///< Placeholder. + { 0x010000000000D60B, "msm_unknown_01" }, ///< Placeholder. + { 0x010000000000D60C, "msm_unknown_02" }, ///< Placeholder. + { 0x010000000000D60D, "msm_unknown_03" }, ///< Placeholder. + { 0x010000000000D60E, "msm_unknown_04" }, ///< Placeholder. + { 0x010000000000D610, "msm_unknown_05" }, ///< Placeholder. + { 0x010000000000D611, "msm_unknown_06" }, ///< Placeholder. + { 0x010000000000D612, "msm_unknown_07" }, ///< Placeholder. + { 0x010000000000D613, "msm_unknown_08" }, ///< Placeholder. + { 0x010000000000D614, "msm_unknown_09" }, ///< Placeholder. + { 0x010000000000D615, "msm_unknown_0a" }, ///< Placeholder. + { 0x010000000000D616, "msm_unknown_0b" }, ///< Placeholder. + { 0x010000000000D617, "msm_unknown_0c" }, ///< Placeholder. + { 0x010000000000D619, "msm_unknown_0d" }, ///< Placeholder. { 0x010000000000D623, "DevServer" }, + { 0x010000000000D633, "msm_unknown_0e" }, ///< Placeholder. + { 0x010000000000D640, "htcnet" }, /* System applications. */ { 0x01008BB00013C000, "flog" }, @@ -440,6 +468,8 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x010086000E49C000, "EncounterUsrDummy" }, { 0x0100810002D5A000, "ShopMonitaringTool" }, { 0x010023D002B98000, "DeltaStress" }, + { 0x010099F00D810000, "sysapp_unknown_00" }, ///< Placeholder. + { 0x0100E6C01163C000, "sysapp_unknown_01" }, ///< Placeholder. /* Pre-release system applets. */ { 0x1000000000000001, "SystemInitializer" }, @@ -463,7 +493,7 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x100000000000020B, "nifm" }, { 0x100000000000020C, "ptm" }, { 0x100000000000020D, "shell" }, - { 0x100000000000020E, "bsdsockets" }, + { 0x100000000000020E, "bsdsocket" }, { 0x100000000000020F, "hid" }, { 0x1000000000000210, "audio" }, { 0x1000000000000212, "LogManager" }, @@ -482,7 +512,8 @@ static const TitleSystemEntry g_systemTitles[] = { { 0x1000000000000220, "psc" }, { 0x1000000000000221, "capsrv" }, { 0x1000000000000222, "am" }, - { 0x1000000000000223, "ssl" } + { 0x1000000000000223, "ssl" }, + { 0x1000000000000224, "nim" } }; static const u32 g_systemTitlesCount = MAX_ELEMENTS(g_systemTitles);