Changes

1,999 bytes added ,  20:50, 17 October 2017
Document SSK generation.
Line 12: Line 12:  
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.
    +
Pseudocode for the derivation is as follows:
 +
  void generateSSK() {
 +
      char keyBuffer[0x10]; // Used to store keydata
 +
      uint hwInfoBuffer[4]; // Used to store info about hardware from fuses
 +
      uint deviceKey = getDeviceKey(); // Reads 32-bit device key from FUSE_PRIVATE_KEY4.
 +
      for (int i = 0; i < 4; i++) { // Keybuffer = deviceKey || deviceKey || deviceKey || deviceKey
 +
          ((uint *)keyBuffer)[i] = deviceKey;
 +
      }
 +
     
 +
      encryptWithSBK(keyBuffer); // keyBuffer = AES-ECB(SBK, deviceKey || {...})
 +
     
 +
      // Set up Hardware info buffer
 +
      uint vendor_code = *((uint *)0x7000FA00) & 0x0000000F; // FUSE_VENDOR_CODE
 +
      uint fab_code    = *((uint *)0x7000FA04) & 0x0000000F; // FUSE_FAB_CODE
 +
      uint lot_code_0  = *((uint *)0x7000FA08) & 0xFFFFFFFF; // FUSE_LOT_CODE_0
 +
      uint lot_code_1  = *((uint *)0x7000FA0C) & 0x0FFFFFFF; // FUSE_LOT_CODE_1
 +
      uint wafer_id    = *((uint *)0x7000FA10) & 0x0000003F; // FUSE_WAFER_ID
 +
      uint x_coord    = *((uint *)0x7000FA14) & 0x000001FF; // FUSE_X_COORDINATE
 +
      uint y_coord    = *((uint *)0x7000FA18) & 0x000001FF; // FUSE_Y_COORDINATE
 +
      uint unk_hw_fuse = *((uint *)0x7000FA20) & 0x0000003F; // Unknown cached fuse.
 +
     
 +
      // HARDWARE_INFO_BUFFER = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID
 +
      hwInfoBuffer[0] = (lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | unk_hw_fuse;
 +
      hwInfoBuffer[1] = (lot_code_0 << 26) | (lot_code_1 >> 2);
 +
      hwInfoBuffer[2] = (fab_code << 26) | (lot_code_0 >> 6);
 +
      hwInfoBuffer[3] = vendor_code;
 +
     
 +
      for (int i = 0; i < 0x10; i++) { // keyBuffer = XOR(AES-ECB(SBK, deviceKey || {...}), HARDWARE_INFO_BUFFER)
 +
          keyBuffer[i] ^= ((char *)hwInfoBuffer)[i];
 +
      }
 +
     
 +
      encryptWithSBK(keyBuffer); // keyBuffer = AES-ECB(SBK, XOR(AES-ECB(SBK, deviceKey || {...}), HARDWARE_INFO_BUFFER))
 +
     
 +
      setKeyslot(KEYSLOT_SSK, keyBuffer); SSK = keyBuffer.
 +
  }
 +
 
== 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) stores a special console-unique key (that will be referred to as the "tsec key").