AES Registers: Difference between revisions
pathetic |
TimmSkiller (talk | contribs) No edit summary |
||
(23 intermediate revisions by 11 users not shown) | |||
Line 12: | Line 12: | ||
| 4 | | 4 | ||
| RW | | RW | ||
|- | |||
| style="background: green" | Yes | |||
| [[#AES_MACEXTRABLKCNT|AES_MACBLKCNT]] | |||
| 0x10009004 | |||
| 2 | |||
| W | |||
|- | |- | ||
| style="background: green" | Yes | | style="background: green" | Yes | ||
| [[#AES_BLKCNT|AES_BLKCNT]] | | [[#AES_BLKCNT|AES_BLKCNT]] | ||
| | | 0x10009006 | ||
| | | 2 | ||
| W | | W | ||
|- | |- | ||
Line 165: | Line 171: | ||
Changing the input word order triggers the key/keyX/keyY FIFOs to be flushed. | Changing the input word order triggers the key/keyX/keyY FIFOs to be flushed. | ||
== AES_MACEXTRABLKCNT == | |||
(CCM-MAC extra data length)>>4, i.e. the number of block of CCM-MAC extra data. | |||
== AES_BLKCNT == | == AES_BLKCNT == | ||
(Data length)>>4, i.e. the number of blocks to process | |||
== AES_WRFIFO/AES_RDFIFO == | == AES_WRFIFO/AES_RDFIFO == | ||
Line 230: | Line 232: | ||
== Endianness and word order == | == Endianness and word order == | ||
=== AES_CNT.input_endianness === | |||
Swaps the bytes of 32-bit writes to AES_CTR, AES_WRFIFO, AES_KEY*FIFO according to specified endianness. AES_MAC? | |||
=== AES_CNT.output_endianness === | |||
Swaps the bytes of 32-bit reads from AES_RDFIFO. | |||
=== AES_CNT.input_word_order === | |||
If reversed, writes to AES_KEY*FIFO and AES_WRFIFO fill the FIFO backwards. For AES_WRFIFO, this means that every 16-byte block will have its words in the reverse order, but the order of these blocks remains the same. AES_CTR is unaffected by this field. AES_MAC? | |||
=== AES_CNT.output_word_order === | |||
If reversed, reads from AES_RDFIFO will drain the FIFO backwards. This means that every 16-byte output block will have its words in the reverse order, but the order of these blocks remains the same. | |||
== CCM mode pitfall == | |||
Non-standard AES-CCM behaviour is observed on [[APT:Wrap|Wrap]]/[[APT:Unwrap|Unwrap]] function. According to [https://tools.ietf.org/html/rfc3610 RFC 3610], the first block B_0 for authentication should be generated from the message length and some other parameters. Using these function, it seems that the message length is aligned up to 16 when generating B_0. This makes the generated MAC not compliant with the standard when (inputsize-noncesize)%16!=0. It is very likely that this non-standard behaviour happens on the hardware level, but not confirmed yet. | |||
== Keyslot ranges == | == Keyslot ranges == | ||
Line 263: | Line 283: | ||
| SSL cert key. | | SSL cert key. | ||
| Same for all. | | Same for all. | ||
| Same for all. | | Same for all, normalkeys-only. | ||
| style="background: | | style="background: orange" | The keyXs are console-unique, however the normalkeys setup by Boot9 later during keyinit are not console-unique. | ||
|- | |- | ||
| 0x10-0x17 | | 0x10-0x17 | ||
| - | | - | ||
| | | Set for all except 0x11..0x13. Keydata is different for these. | ||
| | | Normalkey, same for all except the last 4 are all different. | ||
| - | | - | ||
|- | |- | ||
Line 275: | Line 295: | ||
| Never used. | | Never used. | ||
| Same for all. | | Same for all. | ||
| Same for all. | | Same for all, normalkeys-only. | ||
| style="background: | | style="background: orange" | The keyXs are console-unique, however the normalkeys setup by Boot9 later during keyinit are not console-unique. | ||
|- | |- | ||
| 0x1C-0x1F | | 0x1C-0x1F | ||
| Never used. | | Never used. | ||
| Same for all. | | Same for all. | ||
| Same for all. | | Same for all, normalkeys-only. | ||
| style="background: | | style="background: orange" | The keyXs are console-unique, however the normalkeys setup by Boot9 later during keyinit are not console-unique. | ||
|- | |- | ||
| 0x20-0x23 | | 0x20-0x23 | ||
| Never used. | | Never used. | ||
| Same for all. | | Same for all. | ||
| Same for all. | | Same for all, normalkeys-only. | ||
| style="background: orange" | | | style="background: orange" | The keyXs are console-unique, however the normalkeys setup by Boot9 later during keyinit are not console-unique. | ||
|- | |- | ||
| 0x24 | | 0x24 | ||
| Never used. | | Never used. | ||
| Individually set. | | Individually set. | ||
| Individually set. | | Individually set, normalkey-only. | ||
| style="background: orange" | | | style="background: orange" | The keyX is console-unique, however the normalkey setup by Boot9 later during keyinit is not console-unique. | ||
|- | |- | ||
| 0x25-0x27 | | 0x25-0x27 | ||
| - | | - | ||
| Not set. | | Not set. | ||
| | | Same for all, normalkeys-only. Same keydata as keyslot 0x24. | ||
| | | style="background: red" | No | ||
|- | |- | ||
| 0x28-0x2B | | 0x28-0x2B | ||
| Never used. | | Never used. | ||
| Individually set. | | Individually set. | ||
| Individually set. | | Individually set, normalkeys-only. Keyslot 0x28 has same normalkey as keyslot 0x24. | ||
| style="background: orange" | | | style="background: orange" | The keyX is console-unique, however the normalkey setup by Boot9 later during keyinit is not console-unique. | ||
|- | |- | ||
| 0x2C-0x2F | | 0x2C-0x2F | ||
| Various uniques. | | Various uniques. | ||
| Same for all. | | Same for all. | ||
| Same for all, | | Same for all, normalkeys-only. | ||
| style="background: red" | No | | style="background: red" | No | ||
|- | |- | ||
Line 317: | Line 337: | ||
| Various uniques. | | Various uniques. | ||
| Same for all. | | Same for all. | ||
| Same for all, | | Same for all, normalkeys-only. | ||
| style="background: red" | No | | style="background: red" | No | ||
|- | |- | ||
Line 323: | Line 343: | ||
| Various uniques. | | Various uniques. | ||
| Same for all. | | Same for all. | ||
| Same for all, | | Same for all, normalkeys-only. | ||
| style="background: red" | No | | style="background: red" | No | ||
|- | |- | ||
Line 329: | Line 349: | ||
| Various uniques. | | Various uniques. | ||
| Same for all. | | Same for all. | ||
| | | Same for all, normalkeys-only. | ||
| style="background: red" | No | | style="background: red" | No | ||
|- | |- | ||
Line 335: | Line 355: | ||
| Various uniques. | | Various uniques. | ||
| Individually set. | | Individually set. | ||
| Individually set. | | Individually set, normalkeys-only. Keyslot 0x3C has same normalkey as 0x38-0x3B. | ||
| style="background: red" | No | | style="background: red" | No | ||
|} | |} | ||
Line 379: | Line 399: | ||
|- | |- | ||
| 0x0B | | 0x0B | ||
| This is console-unique. This keyslot is used for the NAND [[Title_Database|dbs]] images | | This is console-unique. This keyslot is used for the NAND [[Title_Database|dbs]] images AES-CMACs, and the [[Nand/private/movable.sed]] AES-CMAC(when used). | ||
| See above keyslot info. | | See above keyslot info. | ||
| See above keyslot info. | | See above keyslot info. | ||
Line 439: | Line 459: | ||
|- | |- | ||
| 0x19 | | 0x19 | ||
| New3DS gamecard [[Savegames|savedata]] AES- | | New3DS gamecard [[Savegames|savedata]] AES-CMAC key. | ||
Equivalent of keyslot 0x33, used when a [[NCSD]] flag is set to a certain value (implemented with [[9.3.0-21|9.3.0-X]]). | Equivalent of keyslot 0x33, used when a [[NCSD]] flag is set to a certain value (implemented with [[9.3.0-21|9.3.0-X]]). | ||
Line 462: | Line 482: | ||
| - | | - | ||
| No | | No | ||
|- | |||
| 0x20 | |||
| [[System_SaveData|System Save Data]] encryption key during [[System_Transfer|System Transfers]]. See [[System_Transfer#System_Save_Data_Transfer|System Save Data Transfer]]. | |||
| Bootrom. | |||
| NATIVE_FIRM | |||
| NATIVE_FIRM | |||
| Yes | |||
|- | |- | ||
| 0x24 | | 0x24 | ||
| AGB_FIRM savegame AES- | | AGB_FIRM savegame AES-CMAC key. | ||
| Bootrom. | | Bootrom. | ||
| AGB/NATIVE_FIRM. | | AGB/NATIVE_FIRM. | ||
Line 510: | Line 537: | ||
|- | |- | ||
| 0x30 | | 0x30 | ||
| SD/NAND AES- | | SD/NAND AES-CMAC key. | ||
This keyY is initialized via [[Nand/private/movable.sed|movable.sed]]. This is used for calculating the | This keyY is initialized via [[Nand/private/movable.sed|movable.sed]]. This is used for calculating the AES-CMACs under SD [[SD_Filesystem|/Nintendo 3DS/<ID0>/<ID1>/]] (except [[DSiWare_Exports]]) and [[Flash_Filesystem|NAND]] /data/. | ||
| Bootrom. | | Bootrom. | ||
| NATIVE_FIRM. | | NATIVE_FIRM. | ||
Line 537: | Line 564: | ||
|- | |- | ||
| 0x33 | | 0x33 | ||
| Gamecard [[Savegames|savedata]] AES- | | Gamecard [[Savegames|savedata]] AES-CMAC. | ||
| Bootrom. | | Bootrom. | ||
| NATIVE_FIRM. | | NATIVE_FIRM. | ||
Line 555: | Line 582: | ||
| Movable.sed key. | | Movable.sed key. | ||
This is the keyslot used for movable.sed encryption + AES-MAC with the import/export [[FSPXI:ImportIntegrityVerificationSeed|commands]]. | This is the keyslot used for movable.sed encryption + AES-CBC MAC with the import/export [[FSPXI:ImportIntegrityVerificationSeed|commands]]. The keyYs used for crypto/CMAC are different, but both can be found in process9 rodata. | ||
| Bootrom. | | Bootrom. | ||
| NATIVE_FIRM. | |||
| - | | - | ||
| Yes | | Yes | ||
|- | |- | ||
| 0x36 | | 0x36 | ||
| | | Used by the [[Friend_Services|the friends module]] for [[Friend_Services#Approach_Contexts|ApproachContext]] encryption. See [[FRDU:GetMyApproachContext]]. | ||
See [[ | |||
| Bootrom. | | Bootrom. | ||
| Bootrom. | | Bootrom. | ||
Line 598: | Line 623: | ||
| DSiWare export key. | | DSiWare export key. | ||
This keyY is initialized via [[Nand/private/movable.sed|movable.sed]]. This is used for calculating the | This keyY is initialized via [[Nand/private/movable.sed|movable.sed]]. This is used for calculating the AES-CMACs for SD [[DSiWare_Exports]]. | ||
| Bootrom. | | Bootrom. | ||
| NATIVE_FIRM. | | NATIVE_FIRM. | ||
Line 620: | Line 645: | ||
| NATIVE_FIRM. | | NATIVE_FIRM. | ||
| - | | - | ||
| Yes | |||
|- | |||
| 0x3F | |||
| Used for various internal Boot9 crypto operations, different keydata for each one. Used to decrypt the [[OTP_Registers|OTP]], the FIRM sections when [[Bootloader#Non-NAND_FIRM_boot|booting from non-NAND]], and when generating the console-unique keys. | |||
The keydata for this keyslot is overwritten with other keydata before booting FIRM. This keyslot is not known to be used post-Boot9. | |||
| Bootrom. | |||
| Bootrom. | |||
| Bootrom. | |||
| Yes | | Yes | ||
|} | |} | ||
Line 656: | Line 690: | ||
=== FIRM-launch key clearing === | === FIRM-launch key clearing === | ||
Starting with [[9.0.0-20]] the Process9 FIRM-launch code now "clears" the following AES keyslots, with certain keydata by writing the normal-key: 0x15 and 0x18-0x20. These are the keyslots used by the New3DS [[FIRM]] arm9bin loader(minus keyslot 0x11), the New3DS Process9 does this too. | Starting with [[9.0.0-20]] the Process9 FIRM-launch code now "clears" the following AES keyslots, with certain keydata by writing the normal-key: 0x15 and 0x18-0x20. These are the keyslots used by the New3DS [[FIRM]] arm9bin loader(minus keyslot 0x11), the New3DS Process9 does this too. | ||
=== AES key-init === | |||
See [[Bootloader|here]] for how Boot9 initializes the AES keyslots. | |||
For an issue with console-unique key-init, see [[OTP_Registers|here]]. | |||
Some of the Boot9 key-init appears to have a bug(?) when initializing a chunk of keyslots at once: normally it does <code>for(i=0; i<4; i++){... <setup_keyslot_keydata(keyslotbase+i, keydata)> ...}</code>, however in some cases it does that except with <code>(keyslotbase,</code> instead. This results in the keyslot specified by keyslotbase being initialized 4 times in a row, with the remaining 3 keyslots following keyslotbase being left uninitialized. | |||
initialize_aeskeys() works as follows: | |||
* Validates input, calls panic() on failure. conunique_dataptr and bootrom_dataptr are both input parameters for initialize_aeskeys(). | |||
* Calls crypto_initialize(). | |||
* Then it ''basically'': copies 0x1C-bytes from conunique_dataptr to tmpbuf+0(sp+12), and copies data from bootrom_dataptr with size 0x40-0x1C to tmpbuf+0x1C(conunique_dataptr and bootrom_dataptr are updated afterwards). | |||
* The 0x40-byte tmpbuf is hashed with SHA256. | |||
* Keyslot 0x3F is then initialized using the above hash: keyX = first 0x10-bytes of the hash, keyY = last 0x10-bytes of the hash. | |||
* Then with each console-unique key-init code-block: IV is loaded from bootrom_dataptr(which is updated afterwards), then the 0x40-bytes from bootrom_dataptr is encrypted with AES-CBC. The output is then used as 4 keyXs for initializing keyslots. How bootrom_dataptr is updated if at all varies per code-block. Hashing similar to the code at the start of this function is also run(when the remaining size for conunique_dataptr is non-zero), but the output hash isn't used(this code is also slightly different for one code-block). | |||
* Once finished with that, the non-console-unique keyslots are initialized. This is done with keydata loaded directly from bootrom_dataptr. | |||
* The last initialized keyslot is 0x3F, via normalkey. The keydata for this is copied to 0xFFF00618. This is for restoring the keydata when non-NAND FIRM boot ''fails'', since those use keyslot 0x3F with other keydata. | |||
* Lastly it clears the 0x40-bytes at tmpbuf with the u32 loaded from bootrom_dataptr(the word following the above keyslot 0x3F keydata), then returns. | |||
The keyslots are initialized with the same order of keyslots+keydata_type listed below: | |||
Console-unique keydata, after the initialization for the key-generation keyslot(0x3F): | |||
0x04..0x07 keyX | |||
0x08..0x0B keyX | |||
0x0C..0x0F keyX | |||
0x10 keyX | |||
0x14..0x17 keyX | |||
0x18..0x1B keyX | |||
0x1C..0x1F keyX | |||
0x20..0x23 keyX | |||
0x24 keyX | |||
0x28..0x2B keyX | |||
Common keydata: | |||
0x2C..0x2F keyX | |||
0x30..0x33 keyX | |||
0x34..0x37 keyX | |||
0x38..0x3B keyX | |||
0x3C..0x3F keyX | |||
0x04..0x0B keyY | |||
0x0C..0x0F normalkey | |||
0x10..0x13 normalkey | |||
0x14..0x17 normalkey | |||
0x18..0x1B normalkey | |||
0x1C..0x1F normalkey | |||
0x20..0x23 normalkey | |||
0x24..0x27 normalkey | |||
0x28..0x2B normalkey | |||
0x2C..0x2F normalkey | |||
0x30..0x33 normalkey | |||
0x34..0x37 normalkey | |||
0x38..0x3B normalkey | |||
0x3C..0x3F normalkey |