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]] |