Line 15:
Line 15:
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.
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.
−
The [[AES]]-MAC(which uses a hardware key-generator keyslot, as mentioned above) at the the beginning of the savegame must match the calculated MAC using the DISA/DIFF data, otherwise the savegame is considered corrupted(see below).
+
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).
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:
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:
Line 47:
Line 47:
[[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]]-MAC(the keyslot used for this uses the hardware key-scrambler) is then calculated over this hash, the output MAC is used for the savegame keyY.
+
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.
−
The keyY used for calculating this AES MAC 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 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.
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.
Line 97:
Line 97:
* to calculate the checksum, a CRC16 of the block (with starting value 0xFFFF) is calculated, and the two bytes of the CRC16 are XORed together to produce the 8bit checksum
* to calculate the checksum, a CRC16 of the block (with starting value 0xFFFF) is calculated, and the two bytes of the CRC16 are XORed together to produce the 8bit checksum
−
=== AES MAC header ===
+
=== AES CMAC header ===
{| class="wikitable"
{| class="wikitable"
Line 107:
Line 107:
| 0x00
| 0x00
| 0x10
| 0x10
−
| [[AES]] MAC over a 0x20-byte SHA256 hash(the keyslot used here uses the hardware key-scrambler).
+
| [[AES]]-CMAC over a 0x20-byte SHA256 hash(the keyslot used here uses the hardware key-scrambler).
|-
|-
| 0x10
| 0x10
Line 114:
Line 114:
|}
|}
−
This AES MAC is used to "sign" the DISA/DIFF header. Each time the savegame is updated the hash stored in the DISA/DIFF is updated, therefore the MAC must be updated each time the save is modified as well. SHA256_Update() is used to calculate the hash with the blocks described below.
+
This AES CMAC is used to "sign" the DISA/DIFF header. Each time the savegame is updated the hash stored in the DISA/DIFF is updated, therefore the CMAC must be updated each time the save is modified as well. SHA256_Update() is used to calculate the hash with the blocks described below.
==== Savegame Types ====
==== Savegame Types ====
Line 205:
Line 205:
|}
|}
−
For gamecard savegames the output hash from this is used with the MAC. This save-type is also used for SD savegames, for SD saves the input data is the 0x100-byte DISA header. For SD savegames, the calculated output hash is used with CTR-SIGN.
+
For gamecard savegames the output hash from this is used with the CMAC. This save-type is also used for SD savegames, for SD saves the input data is the 0x100-byte DISA header. For SD savegames, the calculated output hash is used with CTR-SIGN.
==== CTR-SIGN SHA256 Blocks ====
==== CTR-SIGN SHA256 Blocks ====
Line 222:
Line 222:
| SHA-256 hash from CTR-SAV0
| SHA-256 hash from CTR-SAV0
|}
|}
−
This is used for SD savegames, the calculated hash from this is used with the MAC.
+
This is used for SD savegames, the calculated hash from this is used with the CMAC.
==== CTR-9DB0 SHA256 Blocks ====
==== CTR-9DB0 SHA256 Blocks ====
Line 240:
Line 240:
|}
|}
−
This is used for the SD/NAND /[[Title_Database|dbs]] .db extdata images, see [[Title_Database]] regarding AES-MAC keyslots used here.
+
This is used for the SD/NAND /[[Title_Database|dbs]] .db extdata images, see [[Title_Database]] regarding AES-CMAC keyslots used here.
=== Partitions ===
=== Partitions ===
Line 250:
Line 250:
==== DISA ====
==== DISA ====
−
* This is located @ 0x100 in the image, following the MAC header.
+
* This is located @ 0x100 in the image, following the CMAC header.
* If the uint32 @ 0x68 in the DISA(the low 8-bits) is non-zero, then the secondary table is is used, otherwise the primary table is used.
* If the uint32 @ 0x68 in the DISA(the low 8-bits) is non-zero, then the secondary table is is used, otherwise the primary table is used.
* If the table has more then 1 DIFI then the uint32 @ 0x168 is the offset from the DATA partition to the file base (masked with 0xFFFFFFFE).
* If the table has more then 1 DIFI then the uint32 @ 0x168 is the offset from the DATA partition to the file base (masked with 0xFFFFFFFE).
Line 807:
Line 807:
=== Tools ===
=== Tools ===
−
* [https://github.com/3dshax/3ds/tree/master/3dsfuse 3dsfuse] supports reading and modifying savegames. In the mounted FUSE filesystem, the /output.sav is the raw FLASH save-image. When the save was modified, a separate tool to update the MAC must be used with /clean.sav, prior to writing output.sav to a gamecard.
+
* [https://github.com/3dshax/3ds/tree/master/3dsfuse 3dsfuse] supports reading and modifying savegames. In the mounted FUSE filesystem, the /output.sav is the raw FLASH save-image. When the save was modified, a separate tool to update the CMAC must be used with /clean.sav, prior to writing output.sav to a gamecard.
* [[3DSExplorer]] supports reading of savegames, it doesn't support reading the new encrypted savegames and maybe in the future it will support modifying (some of the modyfing code is already implemented).
* [[3DSExplorer]] supports reading of savegames, it doesn't support reading the new encrypted savegames and maybe in the future it will support modifying (some of the modyfing code is already implemented).
[[セーブデータ|Japanese]]
[[セーブデータ|Japanese]]