Changes

6,397 bytes added ,  20:01, 1 May 2019
→‎Encryption: Just document the encryption stuff here instead of external link
Line 1: Line 1:  
[[Category:File formats]]
 
[[Category:File formats]]
The following text tries to document the structure of the NCCH container format.
+
The following text tries to document the structure of the NCCH (Nintendo Content Container Header) container format. This format is used to store the content of any installed [[Titles|title]].
    
== Overview ==
 
== Overview ==
There are two known NCCH container specialisations used on the 3DS, "executable" and "non-executable", officially known as CXI and CFA respectively.
+
There are two known NCCH container specializations used on the 3DS, "executable" and "non-executable", officially known as CXI and CFA, respectively.
   −
== CXI ==  
+
=== CXI ===
   −
The CXI (CTR Executable Image) specialisation of the NCCH container, contains executable code, which runs on a single ARM11 core. It can communicate through SVC calls with the other ARM11 core running the 'system' program code. For reasons of clarity, the ARM11 cores will sometimes be called the 'appcore' and 'syscore' respectively.
+
The CXI (CTR Executable Image) specialization of the NCCH container contains executable code, which runs on a single ARM11 core.
    
The CXI format is structured in the following order:
 
The CXI format is structured in the following order:
 
* first a NCCH header,
 
* first a NCCH header,
* followed by an extended header,
+
* followed by an [[NCCH/Extended Header|extended header]],
 
* followed by an access descriptor,
 
* followed by an access descriptor,
* followed by a plain binary region,
+
* followed by an '''optional''' plain binary region,
* followed by an embedded executable filesystem ([[ExeFS]]) - (contains ARM11 code, Home menu [[SMDH|icn]]/bnr and [[Logo|logo]]),
+
* followed by an '''optional''' executable filesystem ([[ExeFS]]) - (contains ARM11 code, Home menu [[SMDH|icn]]/bnr and [[Logo|logo]]),
* and finally followed by a read-only filesystem ([[RomFS]]) - (Used for external file storage).
+
* and finally followed by an '''optional''' read-only filesystem ([[RomFS]]) - (Used for external file storage).
    
The extended header contains additional information regarding access control.  
 
The extended header contains additional information regarding access control.  
 
The plain binary region is an area specifically stored in plaintext, mostly containing SDK library strings for identification.
 
The plain binary region is an area specifically stored in plaintext, mostly containing SDK library strings for identification.
   −
== CFA ==
+
=== CFA ===
   −
The CFA (CTR File Archive) specialisation of the NCCH container, is not executable, but are used in conjunction with CXI files. For instance the DLP Child Container and the Electronic Manual. (There is a system update NCCH which follows this format, but is used by the 3DS rather than the Application NCCH, and only works when embedded in the [[CCI]] format because the nVer is kept in the header of retail [[CCI]] files instead of the application NCCH). There are CFA files which exist alone in a title, but these are just [[Title list|System Data Archive]] titles and are found only on the NAND.
+
The CFA (CTR File Archive) specialization of the NCCH container is not executable, but is used in conjunction with CXI files, e.g. the DLP Child Container and the Electronic Manual. (There is a system update NCCH which follows this format, but is used by the 3DS rather than the Application NCCH, and only works when embedded in the [[CCI]] format because the nVer is kept in the header of retail [[CCI]] files instead of the application NCCH). There are CFA files which exist alone in a title, but these are just [[Title list|System Data Archive]] titles and are found only in the [[Flash Filesystem#CTR partition|NAND]].
    
CFA files are structured in the following order:
 
CFA files are structured in the following order:
 
* first a NCCH header,
 
* first a NCCH header,
* followed by a read-only filesystem ([[RomFS]])
+
* followed by an '''optional''' executable filesystem ([[ExeFS]]) (same as in CXI, except no ARM11 code)
 +
* followed by an '''optional''' read-only filesystem ([[RomFS]])
   −
Non-Executable NCCH file examples(Includes Decrypted [[RomFS]]):
+
== Container File Format ==
   −
[http://depositfiles.com/files/n476if4gj DLPChild Container]
+
=== Encryption ===
[http://depositfiles.com/files/gnrihkeec Electronic Manual]
+
The [[NCCH/Extended Header|extended header]], the [[ExeFS]], and the [[RomFS]] are encrypted using [https://github.com/3dshax/ctr/blob/master/ctrtool/ncch.c 128-bit AES CTR] unless the NoCrypto flag is set in ncchflag[7]. There are different sets of encryption parameters in use, as over the time new system updates introduced more sophisticated means of encryption.
   −
== NCCH Specs ==
+
All encrypted regions are grouped into two categories, each of which uses one kind of encryption scheme:
   −
The extended header, the [[ExeFS]] and the [[RomFS]] are encrypted using 128-bit AES CTR.  
+
* The "menu info" group, including the [[NCCH/Extended Header|extended header]], the [[ExeFS]] header, and the files "icon" and "banner" in [[ExeFS]], which are needed to display the game on the menu regardless whether system version supports the game, or whether the pre-downloaded eshop game is officially released.
   −
By default encrypted regions are compressed with an LZ77 variant, then encrypted. The spec allows for both unencrypted and uncompressed regions to exist. Retail SD card CXIs must have the [[ExeFS|ExeFS:/.code]] compressed. Development units use a fixed system key for system titles. On retail part of the input [[AES]] engine key is unique per NCCH, the AES engine internally generates the final-normal key.
+
* The "content" group, including the rest files (".code" and ".firm") in [[ExeFS]], and the entire [[RomFS]], which is needed for actually running the game, and which can be only decrypted on the supported system (and when the seed is officially released for eshop games).
   −
Retail CFAs use NCCH product code "CTR-P-CTAP", while retail title/gamecard CXIs use NCCH product code "CTR-P-XXXX". This product code is the NCCH [[Serials|serial code]]. The region-locking info checked by home menu is stored in the [[SMDH#Flags|icon]].
+
The decryption key is generated using the [[AES|AES Engine]]. The keyX and keyY for each group are set as follows:
 +
 +
* The "menu info" group uses the primary key, always generated by keyX in the slot 0x2C (set by bootrom) and keyY from the first 0x10 bytes of the NCCH signature.
   −
All of the hashes stored in this NCCH header are over the cleartext data. The ExeFS/RomFS superblock starts at offset 0x0 in the ExeFS/RomFS, and the size is specified by the hash region fields.
+
* The "content" group uses the secondary key. The slot selection for keyX depends on ncchflag[3], as listed in the table below.
 +
{| class="wikitable" border="1"
 +
|-
 +
!  ncchflag[3]
 +
!  FW Introduced
 +
!  Old3DS
 +
!  [[AES#Keyslot|AES Keyslots]]
 +
!  Notes
 +
|-
 +
|  0x00
 +
|  The initial version
 +
|  style="background: #ccffbb" | Yes
 +
|  0x2C
 +
|  This keyslot is initialized by bootrom. This is the same key as the primary key.
 +
|-
 +
|  0x01
 +
|  [[7.0.0-13|7.0.0-X]]
 +
|  style="background: #ccffbb" | Yes
 +
|  0x25
 +
|  This keyslot is [[Savegames|initialized]] by the 6.0 gamecard savegame keyY init function during boot, using a different portion of the [[Savegames|final]] hash (this keyslot is separate from the one used for the 6.0 save crypto).
 +
|-
 +
|  0x0A
 +
|  [[9.3.0-21|9.3.0-X]]
 +
|  style="background: #ffccbb" | No
 +
|  0x18
 +
|  This keyslot is initialized by [[FIRM#New_3DS_FIRM|arm9loader]] on New3DS starting with [[8.1.0-0_New3DS]], but only [[9.3.0-21|9.3.0-X]] and later know how to use it with ncchflag[3].
 +
|-
 +
|  0x0B
 +
|  [[9.6.0-24|9.6.0-X]]
 +
|  style="background: #ffccbb" | No
 +
|  0x1B
 +
|  [[9.6.0-24|9.6.0-X]]'s [[FIRM#New_3DS_FIRM|arm9loader]] changed the contents of keyslots 0x19-0x1F; 9.6.0-X was the first time they were officially used, so this is not a breaking change (there is no content that would use the old versions of those keys).
 +
|}
 +
 
 +
Besides all rules above, if ncchflag[7] bitmask 0x1 is set, and a fixed AES key instead is used for both groups. There are two fixed keys, one for titles which have the system category bit set (SystemFixedKey), and one for the rest ("zeros" key). These are debug keys, as they aren't nomally supported on retail systems.
 +
 
 +
The initial CTR for decryption each region is generated from the partition ID, as described below:
 +
 
 +
* if the version field (NCCH header + 0x112) is 0 or 2, the 16-byte CTR is [partition_id[7], partition_id[6], ..., partition_id[0], M, 0, ..., 0], where
 +
** The 8-byte partition ID starts from the beginning in the reverse order. If the partition ID is viewed as a little-endian u64, and the CTR is viewed as big-endian u128, then this is to put the partition ID to the most significant bits of the CTR
 +
** CTR[8] is set to a magic number M. For [[NCCH/Extended Header|extended header]], M = 1. For [[ExeFS]], M = 2. For [[RomFS]], M = 3.
 +
** The rest 7 bytes (the least significant bits of big-endian CTR) are set to zero
 +
 
 +
* if the version field is 1, the 16-byte CTR is [partition_id[0], partition_id[1], ...,partition_id[7], 0, 0, 0, 0, T[0], T[1], T[2], T[3]], where
 +
** The 8-byte partition ID starts from the beginning in the same order.
 +
** Then four zeros follow.
 +
** Then a number T in big-endian follows. This number is the offset of each encrypted region to the NCCH beginning. So for [[NCCH/Extended Header|extended header]], T = 0x200. For [[ExeFS]]/[[RomFS]]. T = 0x200 * ExeFS/RomFS offset in media units
 +
 
 +
Note that due to the key generation schemes described above, ExeFS can contain regions using different keys. Regardless of this, both regions shared the same initial CTR at the beginning of ExeFS. If one region doesn't start at the beginning of ExeFS, its actual CTR at its own beginning = ExeFS CTR + (region offset / AESBlockSize=16)
 +
 
 +
=== Format ===
 +
 
 +
Currently, only [[ExeFS]]:/.code can be compressed (with a LZ77 variant). A flag in the [[NCCH/Extended Header#System Info|exheader]] determines if this is the case.
 +
 
 +
On retail for SD applications, exheader_systeminfoflags.flag bit1 must be set.
 +
 
 +
Retail CFAs use the default NCCH product code "CTR-P-CTAP", while retail title/gamecard CXIs use NCCH product code "CTR-X-XXXX". This product code is the NCCH [[Serials|serial code]]. The region-locking info checked by home menu is stored in the [[SMDH#BNR Region|icon]].
 +
 
 +
All of the hashes stored in this NCCH header are over the cleartext data. The ExeFS/RomFS superblock starts at offset 0x0 in the ExeFS/RomFS, and the size is specified by the hash region fields. Nintendo's NCCH validation code seems to have the size of this region fixed to 0x200 bytes (for ExeFS at least).
 +
 
 +
As of [[5.0.0-11]] the application [[ExeFS]]:/logo can be loaded from the plaintext region between the access descriptor and the plain region, all applications built since [[5.0.0-11]] store the logo here. The size of this logo is always 0x2000-bytes.
 +
 
 +
The plain region mainly contains tags for each SDK library used when building the CXI. The version used for the "FIRMWARE" tag is the kernel/FIRM [[Configuration_Memory|version]], this version can also be stored in the exheader "kernel release version" ARM11 kernel descriptor field. As of [[2.2.0-X]] the NATIVE_FIRM kernels check the CXI exheader "kernel release version" field, if it is stored in the CXI exheader. If the kernel/FIRM version specified by this field is higher than the version of the running NATIVE_FIRM, the kernel will return error-code 0xD9001413.
    
=== NCCH Header ===
 
=== NCCH Header ===
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
OFFSET
+
Offset
SIZE
+
Size
DESCRIPTION
+
Description
 
|-
 
|-
 
|  0x000
 
|  0x000
Line 76: Line 141:  
|  0x114
 
|  0x114
 
|  4
 
|  4
Reserved
+
When ncchflag[7] = 0x20 starting with FIRM [[9.6.0-24|9.6.0-X]], this is compared with the first output u32 from a SHA256 hash. The data used for that hash is 0x18-bytes: <0x10-long title-unique content lock seed> <programID from NCCH+0x118>. This hash is only used for verification of the content lock seed, and is not the actual keyY.
 
|-
 
|-
 
|  0x118
 
|  0x118
Line 83: Line 148:  
|-
 
|-
 
|  0x120
 
|  0x120
1
+
0x10
Temp flag
+
Reserved
 
|-
 
|-
0x121
+
0x130
0x2F
+
0x20
Reserved
+
Logo Region SHA-256 hash. (For applications built with SDK 5+) (Supported from firmware: [[5.0.0-11]])
 
|-
 
|-
 
|  0x150
 
|  0x150
Line 96: Line 161:  
|  0x160
 
|  0x160
 
|  0x20
 
|  0x20
|  Extended header SHA-256 hash, over 0x400 bytes of the ExHeader
+
|  Extended header SHA-256 hash (SHA256 of 2x Alignment Size, beginning at 0x0 of ExHeader)
 
|-
 
|-
 
|  0x180
 
|  0x180
 
|  4
 
|  4
|  Extended header size
+
|  Extended header size, in bytes
 
|-
 
|-
 
|  0x184
 
|  0x184
Line 108: Line 173:  
|  0x188
 
|  0x188
 
|  8
 
|  8
|  Flags: byte[5]-byte[7] indicate content type ( system update, application, manual, ... ) size of media unit ( 512*2^byte[6] ) and encryption.
+
|  Flags (See Below)
 
|-
 
|-
 
|  0x190
 
|  0x190
Line 119: Line 184:  
|-
 
|-
 
|  0x198
 
|  0x198
8
+
4
Reserved
+
Logo Region offset, in media units (For applications built with SDK 5+) (Supported from firmware: [[5.0.0-11]])
 +
|-
 +
|  0x19c
 +
|  4
 +
|  Logo Region size, in media units (For applications built with SDK 5+) (Supported from firmware: [[5.0.0-11]])
 
|-
 
|-
 
|  0x1A0
 
|  0x1A0
Line 156: Line 225:  
|  0x1C0
 
|  0x1C0
 
|  0x20
 
|  0x20
|  ExeFS superblock SHA-256 hash, over first 0x200 bytes of the ExeFS
+
|  ExeFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the ExeFS over the number of media units specified in the ExeFS hash region size)
 
|-
 
|-
 
|  0x1E0
 
|  0x1E0
 
|  0x20
 
|  0x20
|  RomFS superblock SHA-256 hash, over first 0x200 bytes of the RomFS
+
|  RomFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the RomFS over the number of media units specified in the RomFS hash region size)
 
|}
 
|}
 +
 +
Given offsets are based on the start of the file.
    
=== NCCH Flags ===
 
=== NCCH Flags ===
Line 168: Line 239:  
!  INDEX
 
!  INDEX
 
!  DESCRIPTION
 
!  DESCRIPTION
 +
|-
 +
|  3
 +
|  Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used(see above).
 +
|-
 +
|  4
 +
|  Content Platform: 1 = CTR, 2 = snake (New 3DS).
 
|-
 
|-
 
|  5
 
|  5
When the low 2-bits are 0x1, the NCCH is a CFA. Otherwise, it's a CXI.
+
Content Type Bit-masks: Data = 0x1, Executable = 0x2, SystemUpdate = 0x4, Manual = 0x8, Child = (0x4<nowiki>|</nowiki>0x8), Trial = 0x10. When 'Data' is set, but not 'Executable', NCCH is a CFA. Otherwise when 'Executable' is set, NCCH is a CXI.
 +
|-
 +
|  6
 +
|  Content Unit Size i.e. u32 ContentUnitSize = 0x200*2^flags[6];
 +
|-
 +
|  7
 +
|  Bit-masks: FixedCryptoKey = 0x1, NoMountRomFs = 0x2, NoCrypto = 0x4, using a new keyY generator = 0x20(starting with FIRM [[9.6.0-24|9.6.0-X]]).
 
|}
 
|}
 
CXIs NCCH header signature is verified using the RSA public key stored in the accessdesc,(which follows the exheader) while CFAs NCCH header is verified with a fixed RSA public key.
 
CXIs NCCH header signature is verified using the RSA public key stored in the accessdesc,(which follows the exheader) while CFAs NCCH header is verified with a fixed RSA public key.
Line 233: Line 316:  
  0004ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 
  0004ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 
  0004ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 
  0004ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  −
A tool for parsing this format is available [http://github.com/3dshax/ctr/tree/master/ctrtool here].
      
==== Example dependency list from the extended header ====
 
==== Example dependency list from the extended header ====
Line 260: Line 341:  
  009F0 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 02 . .............
 
  009F0 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 02 . .............
   −
=== Extended Header ===
+
== Tools ==
See also: [https://github.com/3dshax/ctr/blob/master/ctrtool/exheader.h]
     −
{| class="wikitable" border="1"
+
[https://github.com/profi200/Project_CTR/tree/master/ctrtool ctrtool] - (CMD)(Windows/Linux) Parsing and decrypting (debug only) NCCH files
|-
  −
!  OFFSET
  −
!  SIZE
  −
!  DESCRIPTION
  −
|-
  −
|  0x399
  −
|  1
  −
|  Memory type (00 = Base, 01 = Application, 02 = System)
  −
|}
 
242

edits