Changes

Jump to navigation Jump to search
2,887 bytes added ,  02:09, 12 December 2016
m
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 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 an '''optional''' plain binary region,
 
* followed by an '''optional''' plain binary region,
Line 20: Line 20:  
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 in the [[Flash Filesystem#CTR partition|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:
Line 29: Line 29:  
* followed by an '''optional''' read-only filesystem ([[RomFS]])
 
* followed by an '''optional''' read-only filesystem ([[RomFS]])
   −
Non-Executable NCCH file examples(Includes Decrypted [[RomFS]]):
+
== Container File Format ==
   −
[https://dl.dropbox.com/u/60710927/CTR/Sample/DLP%20Child.7z DLPChild Container]
+
=== Encryption ===
[https://dl.dropbox.com/u/60710927/CTR/Sample/Manual.7z Electronic Manual]
+
The 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. Generally, the decryption key is generated using the [[AES|AES Engine]] key generator by selecting a particular key slot (see below), the keyX of which is usually set by the bootrom and keyY of which was originally set to the first 0x10 bytes of the NCCH signature.
   −
== NCCH Specs ==
+
'''NOTE: For a full understanding of the steps involved in decryption, consult the [https://github.com/Relys/Project_CTR ctrtool] and [https://github.com/archshift/Decrypt9 Decrypt9] source code instead.'''.
   −
=== Encryption ===
+
Starting with [[9.6.0-24|9.6.0-X]] Process9, there is a different method of generating the NCCH keyY which is enabled by setting the bitmask 0x20 in ncchflag[7]: The keyY will be set to a SHA256 hash generated with the 0x20 bytes of data constituted by the old-method-keyY and a unique content lock seed (each of which are 0x10 bytes wide), where seeds for downloaded titles that use the new crypto are stored in [[Filesystem_services#SEEDDB|SEEDDB]] (nand:/data/<console-unique>/sysdata/0001000f/00000000). The decryption is transparent to ARM11 userland: When FSUSER OpenFile is used with a NCCH archive which uses this crypto, the FS-module will add the seed-data from SEEDDB to the end of the file lowpath used for [[FSPXI:OpenFile]], using which Process9 then gets the hash for calculating the NCCH keyY. It has been observed that this new keyY generation is only used for [[RomFS]] and for [[ExeFS]] sections other than "icon" and "banner" (the same sections which would be used for the additional NCCH keyslots, however this keyY generation can be used without any additional NCCH keyslot). Not applying the encryption to "icon" and "banner" was presumably done to support pre-loading of games from the eShop (i.e. being able to download and install titles without being able to start them until official release).
The extended header, the [[ExeFS]] and the [[RomFS]] are encrypted using 128-bit AES CTR. See here regarding the [https://github.com/3dshax/ctr/blob/master/ctrtool/ncch.c CTR].
     −
By default encrypted regions are compressed(ExeFS:/.code only) with an LZ77 variant, then encrypted. The spec allows for both unencrypted and uncompressed regions to exist. Development units use a fixed system key for system titles. For the "Secure crypto" NCCH encryption mode(the encryption mode used for retail NCCH) the [[AES|keyY]] is the first 0x10-bytes of the NCCH signature, the AES engine internally generates the final-normal key(see [[AES|here]] for the keyslot).
+
If a certain NCCH flag is set, a fixed AES key is used. 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.
   −
As of [[7.0.0-13]] the system now supports a new encryption method for the secure-cryptotype, the CTR for this is the same as before. This is enabled when NCCH flag[3] is non-zero. When enabled, the [[RomFS]] and [[ExeFS]] files which don't have filenames "icon" or "banner"(that is, ".code") are crypted with a different keyslot. 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).
+
As of [[7.0.0-13|7.0.0-X]] the system supports a new encryption method for secure-crypto (when ncchflag[3] != 0). Where a second key is generated using the same keyY but with another [[AES|keyslot]]. The second key is used to crypt the [[RomFS]] and [[ExeFS]] files which don't have filenames "icon" or "banner" (i.e. ".code" and ".firm"). While everything else is crypted with the original key. Note the CTR used is the same for both keys. This makes titles "recognizable" but not "launchable" on systems which don't support this method or the keyslot used.
   −
With New3DS [[9.3.0-21|9.3.0-X]] new NCCH crypto support was added, enabled via ncchflag[3]=0x0A. This is identical to the v7.0 crypto except with a New3DS-only keyslot.
+
See below for the secondary keyslots used in NCCH crypto(as mentioned above). As of [[9.6.0-24|9.6.0-X]], Old3DS Process9 will *only* use secondary-keyslot 0x25 when ncchflag[3] is non-zero.
 +
{| class="wikitable" border="1"
 +
|-
 +
!  ncchflag[3]
 +
!  FW Introduced
 +
!  Old3DS
 +
!  [[AES#Keyslot|AES Keyslots]]
 +
!  Notes
 +
|-
 +
|  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).
 +
|}
    
=== Format ===
 
=== 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.
 
On retail for SD applications, exheader_systeminfoflags.flag bit1 must be set.
   −
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#BNR Region|icon]].
+
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. Interestingly, Nintendo's NCCH validation code seems to have the size of this region fixed to 0x200 bytes (for ExeFS at least).  
+
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.
+
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.
 
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.
Line 60: Line 87:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
OFFSET
+
Offset
SIZE
+
Size
DESCRIPTION
+
Description
 
|-
 
|-
 
|  0x000
 
|  0x000
Line 90: Line 117:  
|  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 114: Line 141:  
|  0x180
 
|  0x180
 
|  4
 
|  4
|  Extended header size
+
|  Extended header size, in bytes
 
|-
 
|-
 
|  0x184
 
|  0x184
Line 180: Line 207:  
|  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)
 
|  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 188: Line 217:  
|-
 
|-
 
|  3
 
|  3
|  Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used(see above). v7.0 keyslot(Old3DS/New3DS) = 0x01, v9.3 keyslot(New3DS only) = 0x0A.
+
|  Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used(see above).
 
|-
 
|-
 
|  4
 
|  4
|  Content Platform: 1 = CTR.
+
|  Content Platform: 1 = CTR, 2 = snake (New 3DS).
 
|-
 
|-
 
|  5
 
|  5
Line 200: Line 229:  
|-
 
|-
 
|  7
 
|  7
|  Bit-masks: FixedCryptoKey = 0x1, NoMountRomFs = 0x2, NoCrypto = 0x4
+
|  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 287: Line 316:  
  009E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
  009E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
  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 ===
  −
See also: [https://github.com/3dshax/ctr/blob/master/ctrtool/exheader.h]
  −
  −
See [[NCCH/Extended Header|this]]
      
== Tools ==
 
== Tools ==
   −
[https://github.com/3dshax/ctr/tree/master/ctrtool ctrtool] - (CMD)(Windows/Linux) Parsing and decrypting(debug only) NCCH files
+
[https://github.com/profi200/Project_CTR/tree/master/ctrtool ctrtool] - (CMD)(Windows/Linux) Parsing and decrypting (debug only) NCCH files
 
  −
[[3DSExplorer]] - (GUI)(Windows Only) Parsing NCCH files
 
7

edits

Navigation menu