Changes

Jump to navigation Jump to search
5,879 bytes added ,  22:29, 7 November 2020
→‎Versions: fix M1-M4
Line 1: Line 1: −
== BootROM ==
+
= BootROM =
 
The bootrom initializes two keyslots in the hardware engine:
 
The bootrom initializes two keyslots in the hardware engine:
   Line 8: Line 8:  
The SBK is stored in [[Fuses#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY]], which are locked to read out only FFs after the bootrom finishes.
 
The SBK is stored in [[Fuses#FUSE_PRIVATE_KEY|FUSE_PRIVATE_KEY]], which are locked to read out only FFs after the bootrom finishes.
   −
SBK should be shared amongst all consoles, but we don't know this is the case.
+
SBK is '''unique''' per console, and not shared among consoles as originally believed.
    
The SSK is derived on boot via the SBK, the 32-bit console-unique "Device Key", and hardware information stored in fuses.
 
The SSK is derived on boot via the SBK, the 32-bit console-unique "Device Key", and hardware information stored in fuses.
Line 48: Line 48:  
   }
 
   }
 
   
 
   
== Falcon coprocessor ==
+
= Falcon coprocessor =
The falcon processor (TSEC) stores a special console-unique key (that will be referred to as the "tsec key").
+
The falcon processor (TSEC) generates a special console-unique key (that will be referred to as the "tsec key").
   −
This is presumably stored in fuses that only microcode authenticated by NVidia has access to.
+
This is presumably using data stored in fuses that only microcode authenticated by NVidia has access to.
 
  −
The tsec key is the source of all per-console entropy, because SSK is not used on retail.
  −
 
  −
== Package1 ==
  −
 
  −
=== Key generation ===
      +
= Package1ldr =
 +
== Key table ==
 +
[1.0.0-3.0.2] During package1ldr:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 64: Line 61:  
! Name
 
! Name
 
! Set by
 
! Set by
! Cleared by
   
! Per-console
 
! Per-console
 
! Per-firmware
 
! Per-firmware
! Introduced in
   
|-
 
|-
 
| 11
 
| 11
 
| Package1Key
 
| Package1Key
| [[Package1]]
+
| [[Package1#Package1ldr|Package1ldr]]
| [[Package1]]
   
| No
 
| No
 
| Yes
 
| Yes
| [[1.0.0]]
+
|-
 +
| 14
 +
| SecureBootKey
 +
| Bootrom
 +
| Yes
 +
| No
 +
|-
 +
| 15
 +
| SecureStorageKey
 +
| Bootrom
 +
| Yes
 +
| No
 +
|}
 +
 
 +
[1.0.0-3.0.2] After package1ldr:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Keyslot
 +
! Name
 +
! Set by
 +
! Per-console
 +
! Per-firmware
 
|-
 
|-
 
| 12
 
| 12
 
| MasterKey
 
| MasterKey
| [[Package1]]
+
| [[Package1#Package1ldr|Package1ldr]]
| Forever
   
| No
 
| No
 
| Yes, on security updates
 
| Yes, on security updates
| [[1.0.0]]
   
|-
 
|-
 
| 13
 
| 13
 
| PerConsoleKey
 
| PerConsoleKey
| [[Package1]]
+
| [[Package1#Package1ldr|Package1ldr]]
| Forever
+
| Yes
 +
| No
 +
|}
 +
 
 +
[4.0.0+] After package1ldr (Secure Monitor boot):
 +
{| class="wikitable" border="1"
 +
|-
 +
! Keyslot
 +
! Name
 +
! Set by
 +
! Per-console
 +
! Per-firmware
 +
|-
 +
| 12
 +
| MasterKey
 +
| [[Package1#Package1ldr|Package1ldr]]
 +
| No
 +
| Yes, on security updates
 +
|-
 +
| 13
 +
| PerConsoleKeyForFirmwareSpecificPerConsoleKeyGen
 +
| [[Package1#Package1ldr|Package1ldr]]
 
| Yes
 
| Yes
 
| No
 
| No
| [[1.0.0]]
   
|-
 
|-
 
| 14
 
| 14
| SecureBootKey
+
| StaticKeyForFirmwareSpecificPerConsoleKeyGen
| Bootrom
+
| [[Package1#Package1ldr|Package1ldr]]
| [[Package1]]
   
| No
 
| No
 +
| Yes, on security updates
 +
|-
 +
| 15
 +
| PerConsoleKey
 +
| [[Package1#Package1ldr|Package1ldr]]
 +
| Yes
 
| No
 
| No
| [[1.0.0]]
+
|}
 +
 
 +
[4.0.0+] After package1ldr (Secure Monitor runtime):
 +
{| class="wikitable" border="1"
 +
|-
 +
! Keyslot
 +
! Name
 +
! Set by
 +
! Per-console
 +
! Per-firmware
 
|-
 
|-
| 14
+
| 12
| OtherMasterKey
+
| MasterKey
| [[Package1]]
+
| [[Package1#Package1ldr|Package1ldr]]
| ?
   
| No
 
| No
 
| Yes, on security updates
 
| Yes, on security updates
| [[4.0.0]]
+
|-
 +
| 13
 +
| FirmwareSpecificPerConsoleKey
 +
| Secure Monitor init
 +
| Yes
 +
| Yes, on security updates
 
|-
 
|-
 
| 15
 
| 15
| SecureStorageKey
+
| PerConsoleKey
 +
| [[Package1#Package1ldr|Package1ldr]]
 +
| Yes
 +
| No
 +
|}
 +
 
 +
[6.2.0+] After package1ldr/TSEC Payload (Secure Monitor boot):
 +
{| class="wikitable" border="1"
 +
|-
 +
! Keyslot
 +
! Name
 +
! Set by
 +
! Per-console
 +
! Per-firmware
 +
|-
 +
| 12
 +
| TsecKey
 +
| [[TSEC#Payload|Package1ldr TSEC Firmware]]
 +
| Yes
 +
| No
 +
|-
 +
| 13
 +
| TsecRootKey
 +
| [[TSEC#Payload|Package1ldr TSEC Firmware]]
 +
| No
 +
| Unknown
 +
|-
 +
| 14
 +
| SecureBootKey
 
| Bootrom
 
| Bootrom
| [[Package1]]
   
| Yes
 
| Yes
 
| No
 
| No
| [[1.0.0]]
   
|-
 
|-
 
| 15
 
| 15
| OtherPerConsoleKey
+
| SecureStorageKey
| [[Package1]]
+
| Bootrom
| ?
   
| Yes
 
| Yes
 
| No
 
| No
| [[4.0.0]]
   
|}
 
|}
    +
== Key generation ==
 
Note: aes_unwrap(wrapped_key, wrap_key) is just another name for a single AES-128 block decryption.
 
Note: aes_unwrap(wrapped_key, wrap_key) is just another name for a single AES-128 block decryption.
    
If bit0 of 0x7000FB94 is clear, it will initialize keys like this (probably used for internal development units only):
 
If bit0 of 0x7000FB94 is clear, it will initialize keys like this (probably used for internal development units only):
 
   // Final keys:
 
   // Final keys:
   package1_key    /* slot11 */ = aes_unwrap(f5baeadb.., sbk)
+
   package1_key    /* slot11 */ = aes_unwrap(f5b1eadb.., sbk)
   master_key      /* slot12 */ = aes_unwrap(bct->pubkey[0] == 0x11 ? aff11423.. : 5e177ee1.., aes_unwrap(5ff9c2d9.., sbk))
+
   master_key      /* slot12 */ = aes_unwrap(bct->pubkey[0] == 0x11 ? simpleseed_dev0 : simpleseed_dev1, aes_unwrap(5ff9c2d9.., sbk))
 
   per_console_key /* slot13 */ = aes_unwrap(4f025f0e..., aes_unwrap(6e4a9592.., ssk))
 
   per_console_key /* slot13 */ = aes_unwrap(4f025f0e..., aes_unwrap(6e4a9592.., ssk))
 +
 +
[4.0.0+] Above method was removed.
    
Normal key generation looks like this on 1.0.0/2.0.0:
 
Normal key generation looks like this on 1.0.0/2.0.0:
   keyblob_key /* slot13 */ = aes_unwrap(aes_unwrap(df206f59.., tsec_key /* slot13 */, sbk /* slot14 */)
+
 
 +
   keyblob_key /* slot13 */ = aes_unwrap(aes_unwrap(wrapped_keyblob_key, tsec_key /* slot13 */), sbk /* slot14 */)
 
   cmac_key    /* slot11 */ = aes_unwrap(59c7fb6f.., keyblob_key)
 
   cmac_key    /* slot11 */ = aes_unwrap(59c7fb6f.., keyblob_key)
 
    
 
    
Line 145: Line 224:  
   // Final keys:
 
   // Final keys:
 
   package1_key    /* slot11 */ = keyblob[0x80:0x90]
 
   package1_key    /* slot11 */ = keyblob[0x80:0x90]
   master_key      /* slot12 */ = aes_unwrap(is_debug ? 0542a0fd.. : d8a2410a.., keyblob+0x20)
+
   master_key      /* slot12 */ = aes_unwrap(bct->pubkey[0] == 0x4f ? normalseed_dev : normalseed_retail, keyblob+0x20)
 
   per_console_key /* slot13 */ = aes_unwrap(4f025f0e.., keyblob_key)
 
   per_console_key /* slot13 */ = aes_unwrap(4f025f0e.., keyblob_key)
 +
 +
.. and on 3.0.0, they moved keyslots around a little to generate the same per-console key as 1.0.0:
 +
 +
  old_keyblob_key /* slot10 */ = aes_unwrap(aes_unwrap(df206f59.., tsec_key /* slot13 */), sbk /* slot14 */)
 +
  keyblob_key    /* slot13 */ = aes_unwrap(aes_unwrap(wrapped_keyblob_key, tsec_key /* slot13 */), sbk /* slot14 */)
 +
  cmac_key        /* slot11 */ = aes_unwrap(59c7fb6f.., keyblob_key)
 +
 
 +
  if aes_cmac(buf=keyblob+0x10, len=0xA0, cmac_key) != keyblob[0:0x10]:
 +
    panic()
 +
 
 +
  aes_ctr_decrypt(buf=keyblob+0x20, len=0x90, iv=keyblob+0x10 key=keyblob_key)
 +
 
 +
  // Final keys:
 +
  package1_key    /* slot11 */ = keyblob[0x80:0x90]
 +
  master_key      /* slot12 */ = aes_unwrap(bct->pubkey[0] == 0x4f ? normalseed_dev : normalseed_retail, keyblob+0x20)
 +
  per_console_key /* slot13 */ = aes_unwrap(4f025f0e.., old_keyblob_key)
 +
 +
.. and on 4.0.0 it was further moved around:
 +
 +
  keyblob_key    /* slot13 */ = aes_unwrap(aes_unwrap(wrapped_keyblob_key, tsec_key /* slot13 */), sbk /* slot14 */)
 +
  cmac_key        /* slot11 */ = aes_unwrap(59c7fb6f.., keyblob_key)
 +
 
 +
  if aes_cmac(buf=keyblob+0x10, len=0xA0, cmac_key) != keyblob[0:0x10]:
 +
    panic()
 +
 
 +
  aes_ctr_decrypt(buf=keyblob+0x20, len=0x90, iv=keyblob+0x10 key=keyblob_key)
 +
 
 +
  // Final keys:
 +
  package1_key        /* slot11 */ = keyblob[0x80:0x90]
 +
  master_key          /* slot12 */ = aes_unwrap(normalseed_retail, keyblob+0x20)
 +
  new_master_key      /* slot14 */ = aes_unwrap(2dc1f48d.., keyblob+0x20)
 +
  new_per_console_key /* slot13 */ = aes_unwrap(0c9109db.., old_keyblob_key)
 +
  per_console_key    /* slot15 */ = aes_unwrap(4f025f0e.., old_keyblob_key)
 +
 +
.. and on 6.2.0, they moved key generation out of package1ldr, and into the Secure Monitor's boot section:
 +
 +
  clear_keyslots_other_than_12_13_and_14()
 +
 
 +
  old_keyblob_key /* slot15 */ = aes_unwrap(aes_unwrap(df206f59.., tsec_key /* slot12 */), sbk /* slot14 */)
 +
  /* Previously, master_kek was stored at keyblob+0x20) */
 +
  master_kek      /* slot13 */ = aes_unwrap(374b7729.. /* probably firmware specific */, tsec_root_key /* slot13 */)
 +
 
 +
  clear_keyslot(12)
 +
 
 +
  // Final keys:
 +
  new_master_key      /* slot12 */ = aes_unwrap(2dc1f48d.., master_kek)       
 +
  master_key          /* slot13 */ = aes_unwrap(normalseed_retail, master_kek)
 +
  new_per_console_key /* slot14 */ = aes_unwrap(0c9109db.., old_keyblob_key)
 +
  per_console_key    /* slot15 */ = aes_unwrap(4f025f0e.., old_keyblob_key)
 +
    
SBK and SSK keyslots are cleared after keys have been generated.
 
SBK and SSK keyslots are cleared after keys have been generated.
Line 158: Line 287:  
This means that if you have an attack on the bootloader, you need to re-preform it every time they move to a new keyblob.
 
This means that if you have an attack on the bootloader, you need to re-preform it every time they move to a new keyblob.
   −
Dumping the SBK and TSEC key of any single system should be enough to derive all key material on the system.
+
Dumping the SBK and TSEC key of any single system should be enough to derive all key material on the system, prior to 6.2.0.
    
The key-derivation is described in more detail [[Package1#Key_generation|here]].
 
The key-derivation is described in more detail [[Package1#Key_generation|here]].
   −
==== Table of used keyblobs ====
+
=== Keyblob ===
 +
There are 32 keyblobs written to NAND at factory, with each keyblob encrypted with a console-unique key derived from the console's SBK, the console's tsec key, and a constant specific to each keyblob.
 +
 
 +
Despite being encrypted with console unique keys, though, the decrypted keyblob contents are shared for all consoles.
 +
 
 +
Used keyblobs are as follows:
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 182: Line 316:  
| 1
 
| 1
 
|-
 
|-
| 4.0.0
+
| 4.0.0-4.1.0
 
| 4
 
| 4
 
| 1
 
| 1
 +
|-
 +
| 5.0.0-5.1.0
 +
| 5
 +
| 1
 +
|-
 +
| 6.0.0-6.1.0
 +
| 6
 +
| 1
 +
|}
 +
 +
Starting from 6.2.0, key generation no longer uses keyblobs.
 +
 +
=== Seeds ===
 +
  normalseed_retail = d8a2410a...
 +
 
 +
  [1.0.0] wrapped_keyblob_key = df206f59...
 +
  [1.0.0] simpleseed_dev0  = aff11423...
 +
  [1.0.0] simpleseed_dev1  = 5e177ee1...
 +
  [1.0.0] normalseed_dev    = 0542a0fd...
 +
 
 +
  [3.0.0] wrapped_keyblob_key = 0c25615d... 
 +
  [3.0.0] simpleseed_dev0  = de00216a...
 +
  [3.0.0] simpleseed_dev1  = 2db7c0a1...
 +
  [3.0.0] normalseed_dev    = 678c5a03...
 +
 
 +
  [3.0.1] wrapped_keyblob_key = 337685ee... 
 +
  [3.0.1] simpleseed_dev0  = e045f5ba...
 +
  [3.0.1] simpleseed_dev1  = 84d92e0d...
 +
  [3.0.1] normalseed_dev    = cd88155b...
 +
 
 +
  [4.0.0] wrapped_keyblob_key = 2d1f4880...
 +
 +
=== Versions ===
 +
The key generation system has historically been revised several times. Each version is bound to a specific BCT public key and can be identified by its first byte as follows:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Version
 +
! BCT public key's first byte
 +
! Description
 +
|-
 +
| K1
 +
| 0x11
 +
| Erista prototype development
 +
|-
 +
| K2
 +
| 0xFB
 +
| Erista prototype development
 +
|-
 +
| K3
 +
| 0x4F
 +
| Erista prototype development
 +
|-
 +
| K4
 +
|
 +
| Erista prototype retail
 +
|-
 +
| K5
 +
| 0x37
 +
| Erista development
 +
|-
 +
| K6
 +
| 0xF7
 +
| Erista retail
 +
|-
 +
| M1
 +
| 0x19
 +
| Mariko prototype development
 +
|-
 +
| M2
 +
| 0xC3
 +
| Mariko development
 +
|-
 +
| M3
 +
| 0xDD
 +
| Mariko prototype retail (pre-6.0.0)
 +
|-
 +
| M4
 +
| 0x9B
 +
| Mariko retail
 
|}
 
|}
   −
== Bootloader stage 1 ==
+
= Secure Monitor Init =
It is currently unknown what key generation the stage 2 bootloader does.
+
On all versions, the key to decrypt [[Package2]] is generated by decrypting a constant seed with the master key. The key is erased after use. 
 +
 
 +
Additionally, starting from 4.0.0, the Secure Monitor init will decrypt another constant seed successively with a special per console key and a special static key passed by package1loader, to generate the firmware specific per-console key. The operation will erase these special keys passed by package1loader.  
   −
== Secure Monitor ==
+
= Secure Monitor =
 
The secure monitor performs some runtime cryptographic operations. See [[SMC]] for what operations it provides.
 
The secure monitor performs some runtime cryptographic operations. See [[SMC]] for what operations it provides.

Navigation menu