Line 9: |
Line 9: |
| | | |
| 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. |
| + | |
| + | The gamecard savegame [[AES|keyslot]] keyY is unique per gamecard. |
| | | |
| All savegames, including non-gamecard savegames, are encrypted with AES-CTR. The base CTR never changes after savegame creation. The CTR used for gamecard savegames eventually repeats, while non-gamecard savegames don't use a repeating CTR. For the old gamecard CTR method, it repeated every 0x200-bytes. With the new method it repeats at least every 0x1000-bytes, but the exact period isn't known for certain. Non-gamecard savegames use a separate CTR method from the gamecard savegames, see the [[extdata]] page regarding extdata encryption. | | All savegames, including non-gamecard savegames, are encrypted with AES-CTR. The base CTR never changes after savegame creation. The CTR used for gamecard savegames eventually repeats, while non-gamecard savegames don't use a repeating CTR. For the old gamecard CTR method, it repeated every 0x200-bytes. With the new method it repeats at least every 0x1000-bytes, but the exact period isn't known for certain. Non-gamecard savegames use a separate CTR method from the gamecard savegames, see the [[extdata]] page regarding extdata encryption. |
Line 420: |
Line 422: |
| |} | | |} |
| | | |
− | * The first-hash is a SHA256 hash over the second-hash, with the buffer padded to the second-hash 1<<x block-size. | + | * The first-hash is a SHA256 hash over the second-hash, with the buffer which is hashed aligned to the second-hash 1<<x block-size.(Since the second-hash size is usually 0x20 and the 1<<block-size normally is 0x200, the final buffer size for second-hash is usually 0x200) |
− | * The second-hash is a SHA256 hash over the hash-table, with the buffer padded to the hash-table 1<<x block-size. | + | * The second-hash is a SHA256 hash over the hash-table, with the buffer which is hashed aligned to the hash-table 1<<x block-size. |
| | | |
| '''DPFS''' | | '''DPFS''' |
Line 485: |
Line 487: |
| '''DIFI Hash''' | | '''DIFI Hash''' |
| | | |
− | The last 0x20-bytes of the partition following the DIFI, IVFC and DPFS is a SHA256 hash. The offset to this hash is stored in the DIFI. This hashes the IVFC first-hash, with the buffer padded with zeros to the first-hash 1<<x block-size. | + | The last 0x20-bytes of the partition following the DIFI, IVFC and DPFS is a SHA256 hash. The offset to this hash is stored in the DIFI. This hashes the IVFC first-hash, with the buffer which is hashed aligned to the first-hash 1<<x block-size. |
| | | |
| '''Summary Drawing''' | | '''Summary Drawing''' |