Changes

Jump to navigation Jump to search
5,639 bytes added ,  11:30, 28 July 2020
no edit summary
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]]
| 0x10009004
+
| 0x10009006
| 4
+
| 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
{| class="wikitable" border="1"
  −
!  Bit
  −
!  Description
  −
|-
  −
| 16-31
  −
| (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 ==
When writing to the AES_CTR, AES_MAC or AES_KEY0/1/2/3 register, the hardware will process the written data according to the current input endianness specified in AES_CNT. However, the current specified input word order will not be honored for this register, and always defaults to reversed word order. Therefore, for normal word order, the reversal must be carried out manually if required.
+
 
 +
=== 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: red" | No
+
| 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
 
| -
 
| -
| Not set.
+
| Set for all except 0x11..0x13. Keydata is different for these.
| Not set.
+
| 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: green" | Yes
+
| 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: green" | Yes
+
| 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" | Normalkey is not. keyX is. keyY unknown.
+
| 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" | Normalkey is not. keyX is. keyY unknown.
+
| 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.
| 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" | Normalkey is not. keyX is. keyY unknown.
+
| 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, probably.
+
| 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, probably.
+
| 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, probably.
+
| 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.
| Different 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 555: Line 575:  
| Movable.sed key.
 
| Movable.sed key.
   −
This is the keyslot used for movable.sed encryption + AES-CMAC 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.
 
| Bootrom.
 +
| NATIVE_FIRM.
 
| -
 
| -
 
| Yes
 
| Yes
Line 607: Line 627:  
| [[CTRCARD_Registers#CTRCARD_SECSEED|CTR-CARD hardware-crypto seed]] decryption key.
 
| [[CTRCARD_Registers#CTRCARD_SECSEED|CTR-CARD hardware-crypto seed]] decryption key.
   −
AES-CCM is used, the keyY, nonce and CMAC are stored in the [[NCSD#Card_Info_Header|Card Info Header]].
+
AES-CCM is used, the keyY, nonce and MAC are stored in the [[NCSD#Card_Info_Header|Card Info Header]].
 
| Bootrom.
 
| Bootrom.
 
| NATIVE_FIRM.
 
| NATIVE_FIRM.
Line 620: Line 640:  
| 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 685:  
=== 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
38

edits

Navigation menu