Nand/private/movable.sed

From 3dbrew
Jump to navigation Jump to search
Offset Size Description
0x0 0x4 Magic "SEED"
0x4 0x4 When u8[1] is non-zero, this indicates that the additional 0x20-bytes AES-MAC block at the end of movable.sed exists. If u8[1] is zero, then u8 [0], [2], and [3] must be zero as well.
0x8 0x110 Copied from Nandrw/sys/LocalFriendCodeSeed_B (or LocalFriendCodeSeed_A if it exists). The last 8 bytes (LocalFriendCodeSeed) becomes the first 8 bytes of a AES engine keyY for 3 keyslots
0x118 0x8 The higher 8 bytes of the keyY
0x120 0x20 This data is written to the file when doing a System Format. The original movable.sed from the factory is only 0x120-bytes. The last 0x10-bytes in this block is an AES-MAC over a SHA256 hash, using the same keyslot used for NAND dbs. This hash is calculated over the first 0x130-bytes of movable.sed. This AES-MAC is verified is during movable.sed verification(before RSA verification).

This keyY is the console-unique portion of the 3 keyslots used for everything stored under sdmc/Nintendo 3DS/<ID0>/<ID1> and nand/data/<ID0>. For SD this is used for encryption and AES MACs, however for NAND this is only used for AES MACs. This file is transferred to the destination 3DS during a System Transfer. The movable.sed keyY high u64 is updated on the source 3DS during a System Transfer, and when doing a system format with System Settings.

Movable.sed always exists on retail and development units(written to NAND at the factory), however if reading this file fails(svcBreak would be executed if the file-read code-path return value is 0xC8804464) the system will fall-back to using a console-unique keyY already in memory, with the last 8-bytes being loaded from the 8-bytes following that u64. On development units the code-path handling movable.sed would execute svcBreak if file-reading(regardless of error-code) or verifying the RSA signature fails(this would brick the 3DS), RSA verification failure on a retail unit here would also cause a brick.

The keyY is hashed with SHA256, the first 0x10-bytes from the hash is used with the below snprintf for ID0 in sdmc/Nintendo 3DS/<ID0>/<ID1> and nand/data/<ID0>. ID0 is generated by: snprintf(outdirname, maxlen, "%08x%08x%08x%08x", hashword[0], hashword[1], hashword[2], hashword[3]). Thus, ID0 is the first half of the SHA-256 of movable.sed bytes 0x110-0x11F inclusive, with the four u32s of the half-SHA-256 byte-flipped.

Note: It has been observed at least 2 times that the 0x120+ part has been left uninitialized, yet the 3DS is still working without any form of modfication, behaving just as if it was initialized and working just fine with Custom Firmware installed. It is currently unknown why this is the case, but the following information holds true for both systems:

  • They are Old 3DS Retail Consoles from Europe
  • They were shipped with Firmware version 1.0.0-0E
  • Their Serial Number starts with CEM10, differ from there on
  • SoC manufacturing date of 2010
  • They have not been formatted, ever

More details on this Github Issue