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);