mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-22 18:26:39 +00:00
More NCA parsing changes.
This commit is contained in:
parent
b8992d1fdc
commit
37b63aee60
8 changed files with 92 additions and 41 deletions
|
@ -260,7 +260,7 @@ typedef enum {
|
||||||
} NacpRuntimeUpgrade;
|
} NacpRuntimeUpgrade;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NacpSupportingLimitedLicenses_Demo = BIT(1),
|
NacpSupportingLimitedLicenses_Demo = BIT(0),
|
||||||
NacpSupportingLimitedLicenses_Count = 1 ///< Total values supported by this enum.
|
NacpSupportingLimitedLicenses_Count = 1 ///< Total values supported by this enum.
|
||||||
} NacpSupportingLimitedLicenses;
|
} NacpSupportingLimitedLicenses;
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ typedef struct {
|
||||||
s64 device_save_data_journal_size;
|
s64 device_save_data_journal_size;
|
||||||
s64 bcat_delivery_cache_storage_size;
|
s64 bcat_delivery_cache_storage_size;
|
||||||
char application_error_code_category[0x8];
|
char application_error_code_category[0x8];
|
||||||
u64 local_communication_id[8];
|
u64 local_communication_id[0x8];
|
||||||
u8 logo_type; ///< NacpLogoType.
|
u8 logo_type; ///< NacpLogoType.
|
||||||
u8 logo_handling; ///< NacpLogoHandling.
|
u8 logo_handling; ///< NacpLogoHandling.
|
||||||
u8 runtime_add_on_content_install; ///< NacpRuntimeAddOnContentInstall.
|
u8 runtime_add_on_content_install; ///< NacpRuntimeAddOnContentInstall.
|
||||||
|
@ -390,7 +390,7 @@ typedef struct {
|
||||||
s64 cache_storage_journal_size;
|
s64 cache_storage_journal_size;
|
||||||
s64 cache_storage_data_and_journal_size_max;
|
s64 cache_storage_data_and_journal_size_max;
|
||||||
u16 cache_storage_index_max;
|
u16 cache_storage_index_max;
|
||||||
u8 reserved_1[0x1];
|
u8 reserved_1;
|
||||||
u8 runtime_upgrade; ///< NacpRuntimeUpgrade.
|
u8 runtime_upgrade; ///< NacpRuntimeUpgrade.
|
||||||
u32 supporting_limited_licenses; ///< NacpSupportingLimitedLicenses.
|
u32 supporting_limited_licenses; ///< NacpSupportingLimitedLicenses.
|
||||||
u64 play_log_queryable_application_id[0x10];
|
u64 play_log_queryable_application_id[0x10];
|
||||||
|
|
|
@ -85,7 +85,7 @@ typedef enum {
|
||||||
NcaKeyGeneration_Since910NUP = 11, ///< 9.1.0 - 12.0.3.
|
NcaKeyGeneration_Since910NUP = 11, ///< 9.1.0 - 12.0.3.
|
||||||
NcaKeyGeneration_Since1210NUP = 12, ///< 12.1.0.
|
NcaKeyGeneration_Since1210NUP = 12, ///< 12.1.0.
|
||||||
NcaKeyGeneration_Since1300NUP = 13, ///< 13.0.0 - 13.2.1.
|
NcaKeyGeneration_Since1300NUP = 13, ///< 13.0.0 - 13.2.1.
|
||||||
NcaKeyGeneration_Since1400NUP = 14, ///< 14.0.0 - 14.1.0.
|
NcaKeyGeneration_Since1400NUP = 14, ///< 14.0.0 - 14.1.2.
|
||||||
NcaKeyGeneration_Current = NcaKeyGeneration_Since1400NUP,
|
NcaKeyGeneration_Current = NcaKeyGeneration_Since1400NUP,
|
||||||
NcaKeyGeneration_Max = 32
|
NcaKeyGeneration_Max = 32
|
||||||
} NcaKeyGeneration;
|
} NcaKeyGeneration;
|
||||||
|
@ -100,7 +100,7 @@ typedef enum {
|
||||||
/// 'NcaSignatureKeyGeneration_Current' will always point to the last known key generation value.
|
/// 'NcaSignatureKeyGeneration_Current' will always point to the last known key generation value.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NcaSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1.
|
NcaSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1.
|
||||||
NcaSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.0.
|
NcaSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.2.
|
||||||
NcaSignatureKeyGeneration_Current = NcaSignatureKeyGeneration_Since900NUP,
|
NcaSignatureKeyGeneration_Current = NcaSignatureKeyGeneration_Since900NUP,
|
||||||
NcaSignatureKeyGeneration_Max = (NcaSignatureKeyGeneration_Current + 1)
|
NcaSignatureKeyGeneration_Max = (NcaSignatureKeyGeneration_Current + 1)
|
||||||
} NcaSignatureKeyGeneration;
|
} NcaSignatureKeyGeneration;
|
||||||
|
@ -167,7 +167,10 @@ typedef enum {
|
||||||
NcaHashType_Auto = 0,
|
NcaHashType_Auto = 0,
|
||||||
NcaHashType_None = 1,
|
NcaHashType_None = 1,
|
||||||
NcaHashType_HierarchicalSha256 = 2, ///< Used by NcaFsType_PartitionFs.
|
NcaHashType_HierarchicalSha256 = 2, ///< Used by NcaFsType_PartitionFs.
|
||||||
NcaHashType_HierarchicalIntegrity = 3 ///< Used by NcaFsType_RomFs.
|
NcaHashType_HierarchicalIntegrity = 3, ///< Used by NcaFsType_RomFs.
|
||||||
|
NcaHashType_AutoSha3 = 4,
|
||||||
|
NcaHashType_HierarchicalSha3256 = 5,
|
||||||
|
NcaHashType_HierarchicalIntegritySha3 = 6
|
||||||
} NcaHashType;
|
} NcaHashType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -175,7 +178,9 @@ typedef enum {
|
||||||
NcaEncryptionType_None = 1,
|
NcaEncryptionType_None = 1,
|
||||||
NcaEncryptionType_AesXts = 2,
|
NcaEncryptionType_AesXts = 2,
|
||||||
NcaEncryptionType_AesCtr = 3,
|
NcaEncryptionType_AesCtr = 3,
|
||||||
NcaEncryptionType_AesCtrEx = 4
|
NcaEncryptionType_AesCtrEx = 4,
|
||||||
|
NcaEncryptionType_AesCtrSkipLayerHash = 5,
|
||||||
|
NcaEncryptionType_AesCtrExSkipLayerHash = 6
|
||||||
} NcaEncryptionType;
|
} NcaEncryptionType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -298,9 +303,18 @@ NXDT_ASSERT(NcaSparseInfo, 0x30);
|
||||||
/// Used in NCAs with LZ4-compressed sections.
|
/// Used in NCAs with LZ4-compressed sections.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NcaBucketInfo bucket;
|
NcaBucketInfo bucket;
|
||||||
|
u8 reserved[0x8];
|
||||||
} NcaCompressionInfo;
|
} NcaCompressionInfo;
|
||||||
|
|
||||||
NXDT_ASSERT(NcaCompressionInfo, 0x20);
|
NXDT_ASSERT(NcaCompressionInfo, 0x28);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 offset;
|
||||||
|
u64 size;
|
||||||
|
u8 hash[SHA256_HASH_SIZE];
|
||||||
|
} NcaMetaDataHashDataInfo;
|
||||||
|
|
||||||
|
NXDT_ASSERT(NcaMetaDataHashDataInfo, 0x30);
|
||||||
|
|
||||||
/// Four NCA FS headers are placed right after the 0x400 byte long NCA header in NCA2 and NCA3.
|
/// Four NCA FS headers are placed right after the 0x400 byte long NCA header in NCA2 and NCA3.
|
||||||
/// NCA0 place the FS headers at the start sector from the NcaFsInfo entries.
|
/// NCA0 place the FS headers at the start sector from the NcaFsInfo entries.
|
||||||
|
@ -315,7 +329,8 @@ typedef struct {
|
||||||
NcaAesCtrUpperIv aes_ctr_upper_iv;
|
NcaAesCtrUpperIv aes_ctr_upper_iv;
|
||||||
NcaSparseInfo sparse_info;
|
NcaSparseInfo sparse_info;
|
||||||
NcaCompressionInfo compression_info;
|
NcaCompressionInfo compression_info;
|
||||||
u8 reserved_2[0x68];
|
NcaMetaDataHashDataInfo hash_data_info;
|
||||||
|
u8 reserved_2[0x30];
|
||||||
} NcaFsHeader;
|
} NcaFsHeader;
|
||||||
|
|
||||||
NXDT_ASSERT(NcaFsHeader, 0x200);
|
NXDT_ASSERT(NcaFsHeader, 0x200);
|
||||||
|
@ -340,8 +355,9 @@ typedef struct {
|
||||||
u8 section_num;
|
u8 section_num;
|
||||||
u64 section_offset;
|
u64 section_offset;
|
||||||
u64 section_size;
|
u64 section_size;
|
||||||
u8 section_type; ///< NcaFsSectionType.
|
u8 hash_type; ///< NcaHashType.
|
||||||
u8 encryption_type; ///< NcaEncryptionType.
|
u8 encryption_type; ///< NcaEncryptionType.
|
||||||
|
u8 section_type; ///< NcaFsSectionType.
|
||||||
u8 ctr[AES_BLOCK_SIZE]; ///< Used to update the AES CTR context IV based on the desired offset.
|
u8 ctr[AES_BLOCK_SIZE]; ///< Used to update the AES CTR context IV based on the desired offset.
|
||||||
Aes128CtrContext ctr_ctx;
|
Aes128CtrContext ctr_ctx;
|
||||||
Aes128XtsContext xts_decrypt_ctx;
|
Aes128XtsContext xts_decrypt_ctx;
|
||||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
||||||
/// 'NpdmSignatureKeyGeneration_Current' will always point to the last known key generation value.
|
/// 'NpdmSignatureKeyGeneration_Current' will always point to the last known key generation value.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NpdmSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1.
|
NpdmSignatureKeyGeneration_Since100NUP = 0, ///< 1.0.0 - 8.1.1.
|
||||||
NpdmSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.0.
|
NpdmSignatureKeyGeneration_Since900NUP = 1, ///< 9.0.0 - 14.1.2.
|
||||||
NpdmSignatureKeyGeneration_Current = NpdmSignatureKeyGeneration_Since900NUP,
|
NpdmSignatureKeyGeneration_Current = NpdmSignatureKeyGeneration_Since900NUP,
|
||||||
NpdmSignatureKeyGeneration_Max = (NpdmSignatureKeyGeneration_Current + 1)
|
NpdmSignatureKeyGeneration_Max = (NpdmSignatureKeyGeneration_Current + 1)
|
||||||
} NpdmSignatureKeyGeneration;
|
} NpdmSignatureKeyGeneration;
|
||||||
|
@ -92,8 +92,8 @@ NXDT_ASSERT(NpdmMetaHeader, 0x80);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NpdmMemoryRegion_Application = 0,
|
NpdmMemoryRegion_Application = 0,
|
||||||
NpdmMemoryRegion_Applet = 1,
|
NpdmMemoryRegion_Applet = 1,
|
||||||
NpdmMemoryRegion_SystemSecure = 2,
|
NpdmMemoryRegion_SecureSystem = 2,
|
||||||
NpdmMemoryRegion_SystemNonSecure = 3,
|
NpdmMemoryRegion_NonSecureSystem = 3,
|
||||||
|
|
||||||
/// Old.
|
/// Old.
|
||||||
NpdmMemoryRegion_NonSecure = NpdmMemoryRegion_Application,
|
NpdmMemoryRegion_NonSecure = NpdmMemoryRegion_Application,
|
||||||
|
@ -103,8 +103,8 @@ typedef enum {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 production : 1;
|
u32 production : 1;
|
||||||
u32 unqualified_approval : 1;
|
u32 unqualified_approval : 1;
|
||||||
u32 memory_region : 2; ///< NpdmMemoryRegion.
|
u32 memory_region : 5; ///< NpdmMemoryRegion.
|
||||||
u32 reserved : 28;
|
u32 reserved : 25;
|
||||||
} NpdmAcidFlags;
|
} NpdmAcidFlags;
|
||||||
|
|
||||||
NXDT_ASSERT(NpdmAcidFlags, 0x4);
|
NXDT_ASSERT(NpdmAcidFlags, 0x4);
|
||||||
|
|
|
@ -148,7 +148,7 @@ NX_INLINE void gamecardCloseHandle(void);
|
||||||
|
|
||||||
static bool gamecardOpenStorageArea(u8 area);
|
static bool gamecardOpenStorageArea(u8 area);
|
||||||
static bool gamecardReadStorageArea(void *out, u64 read_size, u64 offset);
|
static bool gamecardReadStorageArea(void *out, u64 read_size, u64 offset);
|
||||||
static void gamecardCloseStorageArea(void);
|
static void gamecardCloseStorageArea(bool switch_to_normal);
|
||||||
|
|
||||||
static bool gamecardGetStorageAreasSizes(void);
|
static bool gamecardGetStorageAreasSizes(void);
|
||||||
NX_INLINE u64 gamecardGetCapacityFromRomSizeValue(u8 rom_size);
|
NX_INLINE u64 gamecardGetCapacityFromRomSizeValue(u8 rom_size);
|
||||||
|
@ -864,7 +864,7 @@ static void gamecardFreeInfo(bool clear_status)
|
||||||
|
|
||||||
g_gameCardHfsCount = 0;
|
g_gameCardHfsCount = 0;
|
||||||
|
|
||||||
gamecardCloseStorageArea();
|
gamecardCloseStorageArea(true);
|
||||||
|
|
||||||
if (clear_status) g_gameCardStatus = GameCardStatus_NotInserted;
|
if (clear_status) g_gameCardStatus = GameCardStatus_NotInserted;
|
||||||
}
|
}
|
||||||
|
@ -1033,9 +1033,6 @@ static bool gamecardGetHandleAndStorage(u32 partition)
|
||||||
|
|
||||||
NX_INLINE void gamecardCloseHandle(void)
|
NX_INLINE void gamecardCloseHandle(void)
|
||||||
{
|
{
|
||||||
/* TODO: find a way to properly close a gamecard handle. */
|
|
||||||
if (!g_gameCardHandle.value) return;
|
|
||||||
svcCloseHandle(g_gameCardHandle.value);
|
|
||||||
g_gameCardHandle.value = 0;
|
g_gameCardHandle.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1048,7 @@ static bool gamecardOpenStorageArea(u8 area)
|
||||||
if (g_gameCardHandle.value && serviceIsActive(&(g_gameCardStorage.s)) && g_gameCardCurrentStorageArea == area) return true;
|
if (g_gameCardHandle.value && serviceIsActive(&(g_gameCardStorage.s)) && g_gameCardCurrentStorageArea == area) return true;
|
||||||
|
|
||||||
/* Close both gamecard handle and open storage area. */
|
/* Close both gamecard handle and open storage area. */
|
||||||
gamecardCloseStorageArea();
|
gamecardCloseStorageArea(false);
|
||||||
|
|
||||||
/* Retrieve both a new gamecard handle and a storage area handle. */
|
/* Retrieve both a new gamecard handle and a storage area handle. */
|
||||||
if (!gamecardGetHandleAndStorage(area - 1)) /* Zero-based index. */
|
if (!gamecardGetHandleAndStorage(area - 1)) /* Zero-based index. */
|
||||||
|
@ -1143,8 +1140,22 @@ end:
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gamecardCloseStorageArea(void)
|
static void gamecardCloseStorageArea(bool switch_to_normal)
|
||||||
{
|
{
|
||||||
|
if (g_gameCardCurrentStorageArea == GameCardStorageArea_None) return;
|
||||||
|
|
||||||
|
/* Workaround: try to reset the Lotus driver by switching to the normal storage area before closing all gamecard comms. */
|
||||||
|
if (switch_to_normal && g_gameCardCurrentStorageArea == GameCardStorageArea_Secure)
|
||||||
|
{
|
||||||
|
LOG_MSG("Switching to normal area before shutting down.");
|
||||||
|
if (gamecardOpenStorageArea(GameCardStorageArea_Normal))
|
||||||
|
{
|
||||||
|
/* Perform a bogus read (just one page). */
|
||||||
|
u8 bogus[GAMECARD_PAGE_SIZE] = {0};
|
||||||
|
gamecardReadStorageArea(bogus, sizeof(bogus), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (serviceIsActive(&(g_gameCardStorage.s)))
|
if (serviceIsActive(&(g_gameCardStorage.s)))
|
||||||
{
|
{
|
||||||
fsStorageClose(&g_gameCardStorage);
|
fsStorageClose(&g_gameCardStorage);
|
||||||
|
@ -1172,7 +1183,7 @@ static bool gamecardGetStorageAreasSizes(void)
|
||||||
|
|
||||||
rc = fsStorageGetSize(&g_gameCardStorage, (s64*)&area_size);
|
rc = fsStorageGetSize(&g_gameCardStorage, (s64*)&area_size);
|
||||||
|
|
||||||
gamecardCloseStorageArea();
|
gamecardCloseStorageArea(false);
|
||||||
|
|
||||||
if (R_FAILED(rc) || !area_size)
|
if (R_FAILED(rc) || !area_size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -573,14 +573,14 @@ static bool keysDeriveNcaHeaderKey(void)
|
||||||
rc = splCryptoGenerateAesKey(g_ncaKeyset.nca_header_kek_sealed, g_ncaKeyset.nca_header_key_source, g_ncaKeyset.nca_header_key);
|
rc = splCryptoGenerateAesKey(g_ncaKeyset.nca_header_kek_sealed, g_ncaKeyset.nca_header_key_source, g_ncaKeyset.nca_header_key);
|
||||||
if (R_FAILED(rc))
|
if (R_FAILED(rc))
|
||||||
{
|
{
|
||||||
LOG_MSG("splCryptoGenerateAesKey failed! (0x%08X) (nca_header_key, part 1).", rc);
|
LOG_MSG("splCryptoGenerateAesKey failed! (0x%08X) (nca_header_key) (#1).", rc);
|
||||||
return false;
|
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);
|
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))
|
if (R_FAILED(rc))
|
||||||
{
|
{
|
||||||
LOG_MSG("splCryptoGenerateAesKey failed! (0x%08X) (nca_header_key, part 2).", rc);
|
LOG_MSG("splCryptoGenerateAesKey failed! (0x%08X) (nca_header_key) (#2).", rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,26 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
/* Check if we're dealing with an invalid start offset or an empty size. */
|
/* Check if we're dealing with an invalid start offset or an empty size. */
|
||||||
if (fs_ctx->section_offset < sizeof(NcaHeader) || !fs_ctx->section_size) continue;
|
if (fs_ctx->section_offset < sizeof(NcaHeader) || !fs_ctx->section_size) continue;
|
||||||
|
|
||||||
/* Determine encryption type. */
|
/* Determine hash and encryption types. */
|
||||||
|
fs_ctx->hash_type = fs_ctx->header.hash_type;
|
||||||
|
if (fs_ctx->hash_type == NcaHashType_Auto || fs_ctx->hash_type == NcaHashType_AutoSha3)
|
||||||
|
{
|
||||||
|
switch(fs_ctx->section_num)
|
||||||
|
{
|
||||||
|
case 0: /* ExeFS Partition FS. */
|
||||||
|
fs_ctx->hash_type = (fs_ctx->hash_type == NcaHashType_Auto ? NcaHashType_HierarchicalSha256 : NcaHashType_HierarchicalSha3256);
|
||||||
|
break;
|
||||||
|
case 1: /* RomFS. */
|
||||||
|
fs_ctx->hash_type = (fs_ctx->hash_type == NcaHashType_Auto ? NcaHashType_HierarchicalIntegrity : NcaHashType_HierarchicalIntegritySha3);
|
||||||
|
break;
|
||||||
|
case 2: /* Logo Partition FS. */
|
||||||
|
fs_ctx->hash_type = NcaHashType_None;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fs_ctx->encryption_type = (out->format_version == NcaVersion_Nca0 ? NcaEncryptionType_AesXts : fs_ctx->header.encryption_type);
|
fs_ctx->encryption_type = (out->format_version == NcaVersion_Nca0 ? NcaEncryptionType_AesXts : fs_ctx->header.encryption_type);
|
||||||
if (fs_ctx->encryption_type == NcaEncryptionType_Auto)
|
if (fs_ctx->encryption_type == NcaEncryptionType_Auto)
|
||||||
{
|
{
|
||||||
|
@ -212,19 +231,21 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we're dealing with an invalid encryption type value. */
|
/* Check if we're dealing with invalid hash/encryption type values. */
|
||||||
if (fs_ctx->encryption_type == NcaEncryptionType_Auto || fs_ctx->encryption_type > NcaEncryptionType_AesCtrEx) continue;
|
if (fs_ctx->hash_type == NcaHashType_Auto || fs_ctx->hash_type == NcaHashType_AutoSha3 || fs_ctx->hash_type > NcaHashType_HierarchicalIntegritySha3 || \
|
||||||
|
fs_ctx->encryption_type == NcaEncryptionType_Auto || fs_ctx->encryption_type > NcaEncryptionType_AesCtrExSkipLayerHash) continue;
|
||||||
|
|
||||||
/* Determine FS section type. */
|
/* Determine FS section type. */
|
||||||
if (fs_ctx->header.fs_type == NcaFsType_PartitionFs && fs_ctx->header.hash_type == NcaHashType_HierarchicalSha256)
|
if (fs_ctx->header.fs_type == NcaFsType_PartitionFs && (fs_ctx->hash_type == NcaHashType_HierarchicalSha256 || fs_ctx->hash_type == NcaHashType_HierarchicalSha3256))
|
||||||
{
|
{
|
||||||
fs_ctx->section_type = NcaFsSectionType_PartitionFs;
|
fs_ctx->section_type = NcaFsSectionType_PartitionFs;
|
||||||
} else
|
} else
|
||||||
if (fs_ctx->header.fs_type == NcaFsType_RomFs && fs_ctx->header.hash_type == NcaHashType_HierarchicalIntegrity)
|
if (fs_ctx->header.fs_type == NcaFsType_RomFs && (fs_ctx->hash_type == NcaHashType_HierarchicalIntegrity || fs_ctx->hash_type == NcaHashType_HierarchicalIntegritySha3))
|
||||||
{
|
{
|
||||||
fs_ctx->section_type = (fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx ? NcaFsSectionType_PatchRomFs : NcaFsSectionType_RomFs);
|
fs_ctx->section_type = ((fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx || fs_ctx->encryption_type == NcaEncryptionType_AesCtrExSkipLayerHash) ? \
|
||||||
|
NcaFsSectionType_PatchRomFs : NcaFsSectionType_RomFs);
|
||||||
} else
|
} else
|
||||||
if (fs_ctx->header.fs_type == NcaFsType_RomFs && fs_ctx->header.hash_type == NcaHashType_HierarchicalSha256 && out->format_version == NcaVersion_Nca0)
|
if (fs_ctx->header.fs_type == NcaFsType_RomFs && fs_ctx->hash_type == NcaHashType_HierarchicalSha256 && out->format_version == NcaVersion_Nca0)
|
||||||
{
|
{
|
||||||
fs_ctx->section_type = NcaFsSectionType_Nca0RomFs;
|
fs_ctx->section_type = NcaFsSectionType_Nca0RomFs;
|
||||||
}
|
}
|
||||||
|
@ -753,7 +774,7 @@ static bool ncaEncryptKeyArea(NcaContext *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear encrypted key area. */
|
/* Clear encrypted key area. */
|
||||||
memset(&(ctx->header.encrypted_key_area), 0, NCA_USED_KEY_AREA_SIZE);
|
memset(&(ctx->header.encrypted_key_area), 0, sizeof(NcaEncryptedKeyArea));
|
||||||
|
|
||||||
/* Initialize AES-128-ECB encryption context using the retrieved KAEK. */
|
/* Initialize AES-128-ECB encryption context using the retrieved KAEK. */
|
||||||
aes128ContextCreate(&key_area_ctx, kaek, true);
|
aes128ContextCreate(&key_area_ctx, kaek, true);
|
||||||
|
|
|
@ -341,7 +341,7 @@ static u32 save_journal_storage_read(journal_storage_ctx_t *ctx, remap_storage_c
|
||||||
|
|
||||||
static bool save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *ctx, u64 master_hash_offset, ivfc_save_hdr_t *ivfc)
|
static bool save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *ctx, u64 master_hash_offset, ivfc_save_hdr_t *ivfc)
|
||||||
{
|
{
|
||||||
if (!ctx || !ctx->levels || !ivfc || !ivfc->num_levels)
|
if (!ctx || !ivfc || !ivfc->num_levels)
|
||||||
{
|
{
|
||||||
LOG_MSG("Invalid parameters!");
|
LOG_MSG("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -238,6 +238,7 @@ static const TitleSystemEntry g_systemTitles[] = {
|
||||||
{ 0x0100000000001014, "PlayReport" },
|
{ 0x0100000000001014, "PlayReport" },
|
||||||
{ 0x0100000000001015, "MaintenanceMenu" },
|
{ 0x0100000000001015, "MaintenanceMenu" },
|
||||||
{ 0x0100000000001016, "application_install" }, ///< Placeholder.
|
{ 0x0100000000001016, "application_install" }, ///< Placeholder.
|
||||||
|
{ 0x0100000000001017, "nn.am.SystemReportTask" }, ///< Placeholder.
|
||||||
{ 0x0100000000001018, "systemupdate_dl_throughput" }, ///< Placeholder.
|
{ 0x0100000000001018, "systemupdate_dl_throughput" }, ///< Placeholder.
|
||||||
{ 0x0100000000001019, "volume_update"}, ///< Placeholder.
|
{ 0x0100000000001019, "volume_update"}, ///< Placeholder.
|
||||||
{ 0x010000000000101A, "gift" },
|
{ 0x010000000000101A, "gift" },
|
||||||
|
@ -256,6 +257,7 @@ static const TitleSystemEntry g_systemTitles[] = {
|
||||||
{ 0x0100000000001028, "ns_unknown_1" }, ///< Placeholder.
|
{ 0x0100000000001028, "ns_unknown_1" }, ///< Placeholder.
|
||||||
{ 0x010000000000102A, "am_unknown_2" }, ///< Placeholder.
|
{ 0x010000000000102A, "am_unknown_2" }, ///< Placeholder.
|
||||||
{ 0x010000000000102B, "glue_unknown_1" }, ///< Placeholder.
|
{ 0x010000000000102B, "glue_unknown_1" }, ///< Placeholder.
|
||||||
|
{ 0x010000000000102C, "am_unknown_3" }, ///< Placeholder.
|
||||||
{ 0x010000000000102E, "blacklist" },
|
{ 0x010000000000102E, "blacklist" },
|
||||||
{ 0x010000000000102F, "content_delivery" },
|
{ 0x010000000000102F, "content_delivery" },
|
||||||
{ 0x0100000000001031, "ns_unknown_2" }, ///< Placeholder.
|
{ 0x0100000000001031, "ns_unknown_2" }, ///< Placeholder.
|
||||||
|
@ -264,6 +266,7 @@ static const TitleSystemEntry g_systemTitles[] = {
|
||||||
{ 0x0100000000001034, "ngct_unknown" }, ///< Placeholder.
|
{ 0x0100000000001034, "ngct_unknown" }, ///< Placeholder.
|
||||||
{ 0x0100000000001037, "nim_unknown" }, ///< Placeholder.
|
{ 0x0100000000001037, "nim_unknown" }, ///< Placeholder.
|
||||||
{ 0x0100000000001038, "sample" },
|
{ 0x0100000000001038, "sample" },
|
||||||
|
{ 0x010000000000103C, "mnpp" }, ///< Placeholder.
|
||||||
{ 0x0100000000001FFF, "EndOceanProgramId" },
|
{ 0x0100000000001FFF, "EndOceanProgramId" },
|
||||||
|
|
||||||
/* Development system applets. */
|
/* Development system applets. */
|
||||||
|
|
Loading…
Reference in a new issue