Changes

Jump to navigation Jump to search
870 bytes removed ,  05:51, 23 December 2019
Line 13: Line 13:  
!  Old3DS
 
!  Old3DS
 
!  [[AES#Keyslot|AES Keyslots]] (Encryotion / CMAC)
 
!  [[AES#Keyslot|AES Keyslots]] (Encryotion / CMAC)
Key Y generation method
+
KeyY generation method
 
!  Repeating CTR
 
!  Repeating CTR
 
|-
 
|-
Line 54: Line 54:  
So how do you use this to decrypt a savegame on a 3DS? First off, you chunk up the savegame into 512 byte chunks. Then, you bin these chunks by their contents, discarding any that contain only FF. Now look for the most common chunk. This is your keystream. Now XOR the keystream with your original savegame and you should have a fully decrypted savegame. XOR with the keystream again to produce an encrypted savegame.
 
So how do you use this to decrypt a savegame on a 3DS? First off, you chunk up the savegame into 512 byte chunks. Then, you bin these chunks by their contents, discarding any that contain only FF. Now look for the most common chunk. This is your keystream. Now XOR the keystream with your original savegame and you should have a fully decrypted savegame. XOR with the keystream again to produce an encrypted savegame.
   −
=== Savegame keyY ===
     −
All gamecard and SD savegames are encrypted with AES-CTR. The base CTR for gamecard savegames is all-zero. The gamecard savegame [[AES|keyslots]]' keyY(these savegame keyslots use the hardware key-generator) is unique for each region and for each game. The [[NCSD]] partition flags determine the method used to generate this keyY. When the save [[NCSD]] flags checked by the running NATIVE_FIRM are all-zero, the system will use the repeating CTR, otherwise a proper CTR which never repeats within the image is used.
+
=== KeyY Generation methid ===
   −
The [[AES]]-CMAC (which uses a hardware key-generator keyslot, as mentioned above) at the the beginning of the savegame must match the calculated CMAC using the DISA/DIFF data, otherwise the savegame is considered corrupted(see below).
+
The [[NCSD]] partition flags determine the method used to generate this keyY.
   −
When all of the flags checked by the running NATIVE_FIRM are clear, the keyY(original keyY method used with saves where the CTR repeats within the image) is the following:
+
==== v1 ====
 +
 
 +
When all of the flags checked by the running NATIVE_FIRM are clear, the keyY is the following:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 80: Line 81:  
|}
 
|}
   −
==== [[2.0.0-2]] Hashed keyY and [[2.2.0-4]] Savegame Encryption ====
+
==== v2 ====
 +
 
 +
Key Y is the first 0x10 bytes of SHA-256 calculated over the following data
   −
When certain [[NCSD]] partition flags are set, a SHA-256 hash is calculated over the data from the CXI(same data used with the original plain keyY), and the 0x40-bytes read from a gamecard command(this 0x40-byte data is also read by [[Process_Services_PXI|GetRomId]], which is the gamecard-uniqueID). The first 0x10-bytes from this hash is used for the keyY. When flag[7] is set, the CTR will never repeat within the save image, unlike the original CTR-method. All games which had the retail NCSD image finalized after the [[2.2.0-4]] update(and contain [[2.2.0-4]]+ in the [[System Update CFA|System update partition]]), use this encryption method.
+
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| First 8-bytes from the plaintext [[NCCH#CXI|CXI]] accessdesc signature.
 +
|-
 +
| 0x8
 +
| 0x40
 +
| read from a gamecard command(this 0x40-byte data is also read by [[Process_Services_PXI|GetRomId]], which is the gamecard-uniqueID)
 +
|}
    
This keyY generation method was implemented with [[2.0.0-2]] via NCSD partition flag[3], however the proper CTR wasn't implemented for flag[7] until [[2.2.0-4]]. The hashed keyY flag[3] implemented with [[2.0.0-2]] was likely never used with retail gamecards.
 
This keyY generation method was implemented with [[2.0.0-2]] via NCSD partition flag[3], however the proper CTR wasn't implemented for flag[7] until [[2.2.0-4]]. The hashed keyY flag[3] implemented with [[2.0.0-2]] was likely never used with retail gamecards.
   −
==== [[6.0.0-11]] Savegame keyY ====
+
==== v3 ====
    
[[6.0.0-11]] implemented support for generating the savegame keyY with a new method, this method is much more complex than previous keyY methods. This is enabled via new [[NCSD]] partition flags, all retail games which have the NCSD image finalized after the [[6.0.0-11]] release(and [[6.0.0-11]]+ in the system update partition) will have these flags set for using this new method.
 
[[6.0.0-11]] implemented support for generating the savegame keyY with a new method, this method is much more complex than previous keyY methods. This is enabled via new [[NCSD]] partition flags, all retail games which have the NCSD image finalized after the [[6.0.0-11]] release(and [[6.0.0-11]]+ in the system update partition) will have these flags set for using this new method.
   −
A SHA-256 hash is calculated over the same data used with the above hashed keyY method, after hashing the above data the following data is hashed: the CXI programID, and the ExeFS:/.code hash from the decrypted [[ExeFS]] header. An [[AES]]-CMAC (the keyslot used for this uses the hardware key-scrambler) is then calculated over this hash, the output CMAC is used for the savegame keyY.
+
First, a SHA-256 hash is calculated over the following data
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| First 8-bytes from the plaintext [[NCCH#CXI|CXI]] accessdesc signature.
 +
|-
 +
| 0x8
 +
| 0x40
 +
| Same ID as [[Process_Services_PXI|GetRomId]]
 +
|-
 +
| 0x48
 +
| 0x8
 +
| CXI Program ID
 +
|-
 +
| 0x50
 +
| 0x20
 +
| ExeFS:/.code hash from the decrypted [[ExeFS]] header
 +
|}
 +
 
 +
Then an [[AES]]-CMAC is calculated over this hash. The output CMAC is used for keyY. The key slot for this CMAC is 0x2F.
   −
The keyY used for calculating this AES-CMAC is initialized while NATIVE_FIRM is loading, this keyY is generated via the [[RSA]] engine. The RSA slot used here is slot0(key-data for slot0 is initialized by bootrom), this RSA slot0 key-data is overwritten during system boot. This RSA slot0 key-data gets overwritten with the RSA key-data used for verifying RSA signatures, every time Process9 verifies any RSA signatures except for [[NCCH|NCCH]] accessdesc signatures. Starting with [[7.0.0-13]] this key-init function used at boot is also used to initialize a separate keyslot used for the new [[NCCH]] encryption method.
+
The 0x2F keyY used for calculating this AES-CMAC (not to be confused with the final keyY for decrypting/signing savegames) is initialized while NATIVE_FIRM is loading, this keyY is generated via the [[RSA]] engine. The RSA slot used here is slot0(key-data for slot0 is initialized by bootrom), this RSA slot0 key-data is overwritten during system boot. This RSA slot0 key-data gets overwritten with the RSA key-data used for verifying RSA signatures, every time Process9 verifies any RSA signatures except for [[NCCH|NCCH]] accessdesc signatures. Starting with [[7.0.0-13]] this key-init function used at boot is also used to initialize a separate keyslot used for the new [[NCCH]] encryption method.
    
This [[FIRM|Process9]] key-init function first checks if a certain 0x10-byte block in the 0x01FF8000 region is all-zero. When all-zero it immediately returns, otherwise it clears that block then continues to do the key generation. This is likely for supporting launching a v6.0+ NATIVE_FIRM under this FIRM.
 
This [[FIRM|Process9]] key-init function first checks if a certain 0x10-byte block in the 0x01FF8000 region is all-zero. When all-zero it immediately returns, otherwise it clears that block then continues to do the key generation. This is likely for supporting launching a v6.0+ NATIVE_FIRM under this FIRM.
242

edits

Navigation menu