Changes

358 bytes added ,  19:01, 1 May 2019
→‎Encryption: Just document the encryption stuff here instead of external link
Line 32: Line 32:     
=== Encryption ===
 
=== Encryption ===
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.
+
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.  
   −
'''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.'''.
+
All encrypted regions are grouped into two categories, each of which uses one kind of encryption scheme:
   −
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 "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.
   −
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.
+
* 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).
   −
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.
+
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.
   −
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.
+
* 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"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 50: Line 52:  
!  [[AES#Keyslot|AES Keyslots]]
 
!  [[AES#Keyslot|AES Keyslots]]
 
!  Notes
 
!  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
 
|  0x01
Line 69: Line 77:  
|  [[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).
 
|  [[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 ===
 
=== Format ===
242

edits