From bd2bf2c8f4550fc340427fefbd9d6e5085d4050a Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Fri, 24 Jun 2022 03:38:58 +0200 Subject: [PATCH] Fix NCA context initialization for NCAs that hold a single sparse FS section. --- include/core/nca.h | 12 ++++++------ source/core/nca.c | 13 +++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/core/nca.h b/include/core/nca.h index db06e0a..4eedf38 100644 --- a/include/core/nca.h +++ b/include/core/nca.h @@ -169,8 +169,8 @@ typedef enum { NcaHashType_HierarchicalSha256 = 2, ///< Used by NcaFsType_PartitionFs. NcaHashType_HierarchicalIntegrity = 3, ///< Used by NcaFsType_RomFs. NcaHashType_AutoSha3 = 4, - NcaHashType_HierarchicalSha3256 = 5, - NcaHashType_HierarchicalIntegritySha3 = 6 + NcaHashType_HierarchicalSha3256 = 5, ///< Used by NcaFsType_PartitionFs. + NcaHashType_HierarchicalIntegritySha3 = 6 ///< Used by NcaFsType_RomFs. } NcaHashType; typedef enum { @@ -336,10 +336,10 @@ typedef struct { NXDT_ASSERT(NcaFsHeader, 0x200); typedef enum { - NcaFsSectionType_PartitionFs = 0, ///< NcaFsType_PartitionFs + NcaHashType_HierarchicalSha256. - NcaFsSectionType_RomFs = 1, ///< NcaFsType_RomFs + NcaHashType_HierarchicalIntegrity. - NcaFsSectionType_PatchRomFs = 2, ///< NcaFsType_RomFs + NcaHashType_HierarchicalIntegrity + NcaEncryptionType_AesCtrEx. - NcaFsSectionType_Nca0RomFs = 3, ///< NcaFsType_RomFs + NcaHashType_HierarchicalSha256 + NcaVersion_Nca0. + NcaFsSectionType_PartitionFs = 0, ///< NcaFsType_PartitionFs + NcaHashType_HierarchicalSha256 OR NcaHashType_HierarchicalSha3256 + NcaEncryptionType_AesCtr OR NcaEncryptionType_AesCtrSkipLayerHash. + NcaFsSectionType_RomFs = 1, ///< NcaFsType_RomFs + NcaHashType_HierarchicalIntegrity OR NcaHashType_HierarchicalIntegritySha3 + NcaEncryptionType_AesCtr OR NcaEncryptionType_AesCtrSkipLayerHash. + NcaFsSectionType_PatchRomFs = 2, ///< NcaFsType_RomFs + NcaHashType_HierarchicalIntegrity OR NcaHashType_HierarchicalIntegritySha3 + NcaEncryptionType_AesCtrEx OR NcaEncryptionType_AesCtrExSkipLayerHash. + NcaFsSectionType_Nca0RomFs = 3, ///< NcaVersion_Nca0 + NcaFsType_RomFs + NcaHashType_HierarchicalSha256 + NcaEncryptionType_AesXts. NcaFsSectionType_Invalid = 4 } NcaFsSectionType; diff --git a/source/core/nca.c b/source/core/nca.c index e2d22c3..5340952 100644 --- a/source/core/nca.c +++ b/source/core/nca.c @@ -201,14 +201,12 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, switch(fs_ctx->section_num) { case 0: /* ExeFS Partition FS. */ + case 2: /* Logo 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; } @@ -261,7 +259,14 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, u64 raw_storage_size = (sparse_bucket->offset + sparse_bucket->size); if (__builtin_bswap32(sparse_bucket->header.magic) != NCA_BKTR_MAGIC || sparse_bucket->header.version != NCA_BKTR_VERSION || raw_storage_offset < sizeof(NcaHeader) || \ - !raw_storage_size || ((raw_storage_offset + raw_storage_size) > out->content_size) || !sparse_bucket->header.entry_count) continue; + ((raw_storage_offset + raw_storage_size) > out->content_size)) continue; + + if (!raw_storage_size || !sparse_bucket->header.entry_count) + { + /* Increase valid FS section count but don't set this FS section as enabled, since we can't use it. */ + valid_fs_section_cnt++; + continue; + } /* Set sparse table properties. */ fs_ctx->sparse_table_offset = (sparse_info->physical_offset + sparse_bucket->offset);