OTP Registers: Difference between revisions
Created page with "Keys seem to be stored here? Access to this region is disabled once the ARM9 writes 0x2 to REG_SYSPROT9. Originally the console-unique TWL keyinit + region disable wa..." |
Wrong size fixed |
||
(27 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
This region (0x10012000-0x10012100) is used as persistent storage on SoC and for passing the TWL console ID around (0x10012100-0x10012108). | |||
== Overview == | |||
On development units ([[CONFIG|UNITINFO]]!=0) ARM9 uses the first 8-bytes from 0x10012000 for the TWL | Console-unique keys are derived from here. Access to this region is disabled once the ARM9 writes 0x2 to [[CONFIG|REG_SYSPROT9]]. | ||
This is the console-unique data store, including [[CTCert]] etc, that ends up in ITCM at 0x01FFB800. After decryption, the first 0x90-bytes of plaintext are copied to 0x01FFB800 if hash verification passes. Refer to [[Memory_layout#ARM9_ITCM]] for what is contained in the decrypted OTP. | |||
On [[FIRM]] versions prior to [[3.0.0-6|3.0.0-X]], this region was left unprotected. On versions since [[3.0.0-6|3.0.0-X]], this has been fixed, and the region disable is now done by Kernel9 after doing console-unique TWL keyinit, by setting bit 1 of [[CONFIG|REG_SYSPROT9]]. However, with the [[New_3DS]] FIRM ARM9 binary this is now done in the [[FIRM]] ARM9 binary loader, which also uses the 0x10012000 region for New 3DS key generation. | |||
On development units ([[CONFIG|UNITINFO]] != 0) ARM9 uses the first 8-bytes from 0x10012000 for the TWL Console ID. This region doesn't seem to be used by NATIVE_FIRM on retail at all, besides New3DS key-generation in the [[FIRM|ARM9-loader]]. | |||
Normally [[Bootloader|Boot9]] will pass plaintext_otp+0x90 to the AES keyinit function, but when hash verification fails it will pass 0x10012000(otp+0) instead. | |||
== Sections == | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 12: | Line 22: | ||
| 0x0 | | 0x0 | ||
| 0x100 | | 0x100 | ||
| Console-unique data. | | Console-unique data encrypted with AES-CBC. The normalkey and IV are stored in Boot9(retail/devunit have seperate normalkey+IV for this). The last 0x20-bytes of plaintext are a SHA256 hash over the first 0xE0-bytes of plaintext. | ||
|- | |- | ||
| 0x100 | | 0x100 | ||
| 0x8 | | 0x8 | ||
| Before writing REG_SYSPROT9 bit1, the ARM9 copies the 8-byte TWL-keydata to here. | | Before writing REG_SYSPROT9 bit1, the ARM9 copies the 8-byte TWL Console ID here. This sets the registers at 0x4004D00 for ARM7. | ||
|} | |||
== Plaintext OTP == | |||
{| class="wikitable" border="1" | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x4 | |||
| This is always 0xDEADB00F. | |||
|- | |||
| 0x4 | |||
| 0x4 | |||
| This is the u32 DeviceId. | |||
|- | |||
| 0x8 | |||
| 0x10 | |||
| This is the fall-back keyY used for movable.sed keyY when movable.sed doesn't exist in NAND(the first two words here are used on retail for generating console-unique TWL keydata/etc). This is also used for "LocalFriendCodeSeed", etc. | |||
|- | |||
| 0x18 | |||
| 0x1 | |||
| OTP version | |||
|- | |||
| 0x19 | |||
| 0x1 | |||
| This determines if the OTP is for a dev system; it indicates the [[CTCert]] issuer type: 0 = retail "Nintendo CA - G3_NintendoCTR2prod", non-zero = dev "Nintendo CA - G3_NintendoCTR2dev". | |||
|- | |||
| 0x1A | |||
| 0x6 | |||
| Manufacturing date (of the SoC?). Usually month(s) before the dates in the logs stored in [[Flash_Filesystem|TWLNAND]]. Each byte is one field: year, month, day, hour, minute, second. Year is encoded as year-1900 so that it fits in one byte. This order matches up with the layout of a <code>struct tm</code>. | |||
|- | |||
| 0x20 | |||
| 0x4 | |||
| This is the CTCert expiry time as UNIX timestamp, this is specified in big endian if the OTP version is <5. | |||
|- | |||
| 0x24 | |||
| 0x20 | |||
| This is the CTCert ECDSA privk. | |||
|- | |||
| 0x44 | |||
| 0x3C | |||
| This is the CTCert ECDSA signature (sect233r1?/SHA-256). | |||
|- | |||
| 0x80 | |||
| 0x10 | |||
| This is all-zero. | |||
|- | |||
| 0x90 | |||
| 0x50 | |||
| Used by Boot9 for generating the console-unique AES [[AES_Registers|keyXs]]. However, due to a bug(?) in Boot9, only the first 0x1C-bytes here actually affect console-unique key generation. The rest of the data is used for hashing, but that output hash only gets overwritten without being used afterwards. | |||
Note that the size passed to the Boot9 keyinit code for console-unique-buffer-size is 0x70, hence this includes the below OTP hash. | |||
|- | |||
| 0xE0 | |||
| 0x20 | |||
| SHA256 hash over the previous 0xE0-bytes. | |||
|} | |} |