NCA: Difference between revisions
Moosehunter (talk | contribs) |
m Undo revision 12837 by SevereResponse (talk) Tag: Undo |
||
(18 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
NCA means «Nintendo Content Archive». | |||
The entire raw NCAs are encrypted. | The entire raw NCAs are encrypted. | ||
Line 25: | Line 27: | ||
| 0x200 | | 0x200 | ||
| 0x4 | | 0x4 | ||
| | | Magic "NCA3" ("NCA2", "NCA1" or "NCA0" for pre-1.0.0 NCAs) | ||
|- | |- | ||
| 0x204 | | 0x204 | ||
| 0x1 | | 0x1 | ||
| DistributionType (0x00 = | | DistributionType (0x00 = Download, 0x01 = GameCard) | ||
|- | |- | ||
| 0x205 | | 0x205 | ||
Line 61: | Line 63: | ||
| 0x220 | | 0x220 | ||
| 0x1 | | 0x1 | ||
| KeyGeneration (0x03 = [[3.0.1]], 0x04 = [[4.0.0]], 0x05 = [[5.0.0]], 0x06 = [[6.0.0]], 0x07 = [[6.2.0]], 0x08 = [[7.0.0]], 0x09 = [[8.1.0]], 0x0A = [[9.0.0]], 0x0B = [[9.1.0]], 0xFF = Invalid) | | KeyGeneration (0x03 = [[3.0.1]], 0x04 = [[4.0.0]], 0x05 = [[5.0.0]], 0x06 = [[6.0.0]], 0x07 = [[6.2.0]], 0x08 = [[7.0.0]], 0x09 = [[8.1.0]], 0x0A = [[9.0.0]], 0x0B = [[9.1.0]], 0x0C = [[12.1.0]], 0x0D = [[13.0.0]], 0x0E = [[14.0.0]], 0x0F = [[15.0.0]], 0x10 = [[16.0.0]], 0x11 = [[17.0.0]], 0x12 = [[18.0.0]], 0xFF = Invalid) | ||
|- | |- | ||
| 0x221 | | 0x221 | ||
| 0x1 | | 0x1 | ||
| [9.0.0+] | | [9.0.0+] SignatureKeyGeneration | ||
|- | |||
| 0x222 | |||
| 0xE | |||
| Reserved | |||
|- | |- | ||
| 0x230 | | 0x230 | ||
Line 107: | Line 113: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
| StartOffset (in | | StartOffset (in blocks which are 0x200 bytes) | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x4 | | 0x4 | ||
| EndOffset (in | | EndOffset (in blocks which are 0x200 bytes) | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| | | 0x8 | ||
| Reserved | | Reserved | ||
|} | |} | ||
Line 135: | Line 137: | ||
| 0x2 | | 0x2 | ||
| 0x1 | | 0x1 | ||
| FsType (0 = | | FsType (0 = RomFS, 1 = PartitionFS) | ||
|- | |- | ||
| 0x3 | | 0x3 | ||
| 0x1 | | 0x1 | ||
| HashType (0 = Auto, 2 = | | HashType (0 = Auto, 1 = None, 2 = HierarchicalSha256Hash, 3 = HierarchicalIntegrityHash, [14.0.0+] 4 = AutoSha3, [14.0.0+] 5 = HierarchicalSha3256Hash, [14.0.0+] 6 = HierarchicalIntegritySha3Hash) | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x1 | | 0x1 | ||
| EncryptionType (0 = Auto, 1 = None, 2 = | | EncryptionType (0 = Auto, 1 = None, 2 = AesXts, 3 = AesCtr, 4 = AesCtrEx, [14.0.0+] 5 = AesCtrSkipLayerHash, [14.0.0+] 6 = AesCtrExSkipLayerHash) | ||
|- | |- | ||
| 0x5 | | 0x5 | ||
| 0x1 | | 0x1 | ||
| | | [14.0.0+] MetaDataHashType (0 = None, 1 = HierarchicalIntegrity) | ||
|- | |||
| 0x6 | |||
| 0x2 | |||
| Reserved | |||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0xF8 | | 0xF8 | ||
| [[# | | [[#HashData|HashData]] | ||
|- | |- | ||
| 0x100 | | 0x100 | ||
Line 167: | Line 173: | ||
| 0x148 | | 0x148 | ||
| 0x30 | | 0x30 | ||
| SparseInfo (only used in sections with sparse storage) | | [[#SparseInfo|SparseInfo]] (only used in sections with sparse storage) | ||
|- | |- | ||
| 0x178 | | 0x178 | ||
| | | 0x28 | ||
| [12.0.0+] [[#CompressionInfo|CompressionInfo]] | |||
|- | |||
| 0x1A0 | |||
| 0x30 | |||
| [14.0.0+] [[#MetaDataHashDataInfo|MetaDataHashDataInfo]] | |||
|- | |||
| 0x1D0 | |||
| 0x30 | |||
| Reserved | | Reserved | ||
|} | |} | ||
Line 176: | Line 190: | ||
The FsHeader for each section is at absoluteoffset+0x400+(sectionid*0x200), where sectionid corresponds to the index used with the entry/hash tables. | The FsHeader for each section is at absoluteoffset+0x400+(sectionid*0x200), where sectionid corresponds to the index used with the entry/hash tables. | ||
== | == HashData == | ||
This contains information specific to the hash type in use. | This contains information specific to the hash type in use. | ||
=== | === HierarchicalSha256Data === | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 188: | Line 202: | ||
| 0x0 | | 0x0 | ||
| 0x20 | | 0x20 | ||
| SHA256 hash over the hash-table at section-start+0 with the below hash-table size | | MasterHash (SHA256 hash over the hash-table at section-start+0 with the below hash-table size) | ||
|- | |- | ||
| 0x20 | | 0x20 | ||
| 0x4 | | 0x4 | ||
| | | BlockSize | ||
|- | |- | ||
| 0x24 | | 0x24 | ||
| 0x4 | | 0x4 | ||
| | | LayerCount (always 2) | ||
|- | |- | ||
| 0x28 | | 0x28 | ||
| | | 0x50 | ||
| | | [[#Region|LayerRegions]] (one region for the hash-table and another for PFS0 filesystem) | ||
|- | |- | ||
| | | 0x78 | ||
| | | 0x80 | ||
| Reserved | | Reserved | ||
|} | |} | ||
=== | ==== Region ==== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 228: | Line 230: | ||
| 0x0 | | 0x0 | ||
| 0x8 | | 0x8 | ||
| | | Offset | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| | | 0x8 | ||
| | | Size | ||
|} | |||
=== IntegrityMetaInfo === | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |- | ||
| | | 0x0 | ||
| 0x4 | | 0x4 | ||
| Magic | | Magic ("IVFC") | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x4 | | 0x4 | ||
| | | Version | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0x4 | | 0x4 | ||
| | | MasterHashSize | ||
|- | |- | ||
| | | 0xC | ||
| | | 0xB4 | ||
| | | [[#InfoLevelHash|InfoLevelHash]] | ||
|- | |- | ||
| | | 0xC0 | ||
| | | 0x20 | ||
| | | MasterHash | ||
|- | |- | ||
| | | 0xE0 | ||
| | | 0x18 | ||
| Reserved | | Reserved | ||
|} | |||
==== InfoLevelHash ==== | |||
{| class="wikitable" border="1" | |||
|- | |- | ||
! Offset | |||
! Size | |||
! Description | |||
|- | |- | ||
| | | 0x0 | ||
| 0x4 | | 0x4 | ||
| | | MaxLayers | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| | | 0x90 | ||
| [[#HierarchicalIntegrityVerificationLevelInformation|Levels]] | |||
|- | |- | ||
| | | 0x94 | ||
| | | 0x20 | ||
| | | SignatureSalt | ||
|} | |||
===== HierarchicalIntegrityVerificationLevelInformation ===== | |||
{| class="wikitable" border="1" | |||
|- | |- | ||
! Offset | |||
! Size | |||
! Description | |||
|- | |- | ||
| | | 0x0 | ||
| 0x8 | | 0x8 | ||
| | | LogicalOffset | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0x8 | | 0x8 | ||
| | | HashDataSize | ||
|- | |- | ||
| | | 0x10 | ||
| 0x4 | | 0x4 | ||
| | | BlockSize (in log2) | ||
|- | |- | ||
| | | 0x14 | ||
| 0x4 | | 0x4 | ||
| Reserved | | Reserved | ||
|} | |} | ||
Line 364: | Line 322: | ||
| 0x0 | | 0x0 | ||
| 0x8 | | 0x8 | ||
| | | IndirectOffset | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0x8 | | 0x8 | ||
| | | IndirectSize | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
| | | 0x10 | ||
| | | [[#BucketTreeHeader|IndirectHeader]] | ||
|- | |- | ||
| | | 0x20 | ||
| | | 0x8 | ||
| | | AesCtrExOffset | ||
|- | |- | ||
| | | 0x28 | ||
| | | 0x8 | ||
| | | AesCtrExSize | ||
|- | |- | ||
| | | 0x30 | ||
| | | 0x10 | ||
| | | [[#BucketTreeHeader|AesCtrExHeader]] | ||
| | |||
|} | |} | ||
Line 543: | Line 497: | ||
Official code assumes the relocation entries are sorted, and performs a binary search when determining where to read from. Each subsection in the Patch RomFs has its CTR calculated separately from the others based on the value in its entry (the BKTR entries use normal crypto). Thus decrypting a Patch RomFS requires decrypting and parsing the BKTR entries before anything else. | Official code assumes the relocation entries are sorted, and performs a binary search when determining where to read from. Each subsection in the Patch RomFs has its CTR calculated separately from the others based on the value in its entry (the BKTR entries use normal crypto). Thus decrypting a Patch RomFS requires decrypting and parsing the BKTR entries before anything else. | ||
== SparseInfo == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x8 | |||
| TableOffset | |||
|- | |||
| 0x8 | |||
| 0x8 | |||
| TableSize | |||
|- | |||
| 0x10 | |||
| 0x10 | |||
| [[#BucketTreeHeader|TableHeader]] | |||
|- | |||
| 0x20 | |||
| 0x8 | |||
| PhysicalOffset | |||
|- | |||
| 0x28 | |||
| 0x2 | |||
| Generation | |||
|- | |||
| 0x2A | |||
| 0x6 | |||
| Reserved | |||
|} | |||
== CompressionInfo == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x8 | |||
| TableOffset | |||
|- | |||
| 0x8 | |||
| 0x8 | |||
| TableSize | |||
|- | |||
| 0x10 | |||
| 0x10 | |||
| [[#BucketTreeHeader|TableHeader]] | |||
|- | |||
| 0x20 | |||
| 0x8 | |||
| Reserved | |||
|} | |||
== BucketTreeHeader == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x4 | |||
| Magic ("BKTR") | |||
|- | |||
| 0x4 | |||
| 0x4 | |||
| Version | |||
|- | |||
| 0x8 | |||
| 0x4 | |||
| EntryCount | |||
|- | |||
| 0xC | |||
| 0x4 | |||
| Reserved | |||
|} | |||
== MetaDataHashDataInfo == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x8 | |||
| TableOffset | |||
|- | |||
| 0x8 | |||
| 0x8 | |||
| TableSize | |||
|- | |||
| 0x10 | |||
| 0x20 | |||
| TableHash | |||
|} | |||
= Logo Section = | = Logo Section = | ||
Line 593: | Line 647: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
| | | Magic ("PFS0") | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x4 | | 0x4 | ||
| | | EntryCount | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0x4 | | 0x4 | ||
| | | StringTableSize | ||
|- | |- | ||
| 0xC | | 0xC | ||
| 0x4 | | 0x4 | ||
| | | Reserved | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
| X | | X | ||
| | | [[#PartitionEntry|PartitionEntryTable]] | ||
|- | |- | ||
| 0x10 + X | | 0x10 + X | ||
| Y | | Y | ||
| | | StringTable | ||
|- | |- | ||
| 0x10 + X + Y | | 0x10 + X + Y | ||
| Z | | Z | ||
| | | FileData | ||
|} | |} | ||
== PartitionEntry == | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 629: | Line 683: | ||
| 0x0 | | 0x0 | ||
| 0x8 | | 0x8 | ||
| Offset | | Offset | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
| 0x8 | | 0x8 | ||
| Size | | Size | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
| 0x4 | | 0x4 | ||
| | | StringOffset | ||
|- | |- | ||
| 0x14 | | 0x14 | ||
| 0x4 | | 0x4 | ||
| | | Reserved | ||
|} | |} |