Hardware/OTP

From WiiUBrew
Jump to: navigation, search

OTP
Latte Registers
Access
EspressoNone
StarbuckFull
Registers
Base0x0d8001ec
Length0x8
Access size32 bits
Byte orderBig Endian
This box: view  talk  edit

Contents

General

The One Time Programmable memory is programmed sometime during the factory process and can never be changed afterwards. The Wii U's OTP is much larger than the Wii's (1KB split across 8 banks of 128 bytes each) and contains an assortment of read-only data, including the console's encryption/decryption keys.

Register List

Latte GPIOs
Address Bits Name Description
0x0d8001ec 32 LT_OTP_COMMAND OTP command
0x0d8001f0 32 LT_OTP_DATA OTP data

General Registers

LT_OTP_COMMAND (0x0d8001ec)
  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Access R/W U
Field RD
  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Access U R/W
Field ADDR
Field Description
RD Set to one to execute a read command. If clear, then the data in LT_OTP_DATA is unchanged.
ADDR Word address to read. 0x00 to 0x1F (32 4byte words) ORed with the bank's number (0x000 to 0x700).

This register contains the command sent to the OTP. It is unknown whether is register is also used during the factory process to program the OTP.


LT_OTP_DATA (0x0d8001f0)
  310
Access R

This register contains the output data for the last issued OTP read command. The execution of a read operation via the LT_OTP_COMMAND register immediately changes this register without any delay.

IOSU

The Wii U's IOSU interacts with the OTP by setting it's respective Latte registers. In addition to this, the IOS-CRYPTO process is also able to access the OTP indirectly through syscall 0x22, which takes the OTP word index, a buffer to store the result and the requested size as parameters. The IOS-KERNEL then converts the word index:

int read_otp_internal(int index, void* out_buf, u32 size)
{
  int i_res = disable_interrupts();
  
  if (size != 0)
  {
    int step = 0;
    
    while (step < size)
    {
      int word_addr = index + (step >> 2);
      int word_offset = word_addr & 0x1F;      // Each OTP bank has 0x20 * 4 = 0x80 bytes. Valid word indexes go from 0x00 to 0x1F.
      word_addr = word_addr << 3;
      word_offset = word_offset | 0x80000000;  // Set OTP read flag.
      word_addr = word_addr & 0x700;           // OTP bank goes from 0x000 to 0x700.
      word_addr = word_addr | word_offset;
      
      *(u32*)0x0D8001EC = word_addr;                     // Write to LT_OTPCMD
       u32 temp = *(u32*)0x0D8001EC;                     // Read from LT_OTPCMD (sync?)
      
      *(u32*)(out_buf + step) = *(u32*)0x0D8001F0;       // Copy from LT_OTPDATA
      
      step += 4;	
    }
  }
  
  enable_interrupts(i_res);
  return 0;
}
syscall_0x22(index, out_buf, size)
{
  // Do some permission checks.
  ...
  
  // Internal IOS-KERNEL function.
  read_otp_internal(index, out_buf, size);
}

OTP Contents

The following things are stored inside the OTP and requested by the IOSU kernel at some point:

Bank Offset (word index * 4) Size Description
0 (Wii bank) 0x000 (0x00 * 4) 0x14 bytes Wii boot1 SHA-1 hash
0 (Wii bank) 0x014 (0x05 * 4) 0x10 bytes Wii common key
0 (Wii bank) 0x024 (0x09 * 4) 0x04 bytes Wii NG ID
0 (Wii bank) 0x028 (0x0A * 4) 0x1C bytes Wii NG private key
0 (Wii bank) 0x044 (0x11 * 4) 0x14 bytes Wii NAND HMAC (overlaps with NG private key)
0 (Wii bank) 0x058 (0x16 * 4) 0x10 bytes Wii NAND key
0 (Wii bank) 0x068 (0x1A * 4) 0x10 bytes Wii RNG key
0 (Wii bank) 0x078 (0x1E * 4) 0x08 bytes Unknown (padding)
1 (Wii U bank) 0x080 (0x20 * 4) 0x04 bytes Security level flag
Retail: 0x90000000; Debug: 0x88000000; Factory: 0x00000000
Flag 0x40000000 causes an error in boot0.
Flag 0x80000000 means the console type has been programmed.
Flag 0x00000000 tells boot0 to not crypt or verify ancast images, skip OTP locking, and not require valid SEEPROM info (factory mode).
Flag 0x08000000 tells boot0 to use its first RSA key and debug ancast images (debug mode).
Flag 0x10000000 tells boot0 to use its second RSA key and retail ancast images (retail mode).
If both retail and debug flags are set, boot0 will throw an error.
1 (Wii U bank) 0x084 (0x21 * 4) 0x04 bytes IOStrength configuration flags
Flag 0x00008000 sets register LT_IOSTRENGTH_CTRL0.
Flags 0x00000008, 0x00000080, 0x00000800, 0x00002000 set register LT_IOSTRENGTH_CTRL1.
Should be 0x00000000 in retail units.
1 (Wii U bank) 0x088 (0x22 * 4) 0x04 bytes Pulse length for SEEPROM manual CLK
Should be 0x00000000 in retail units (defaults to 0xFA in boot0).
1 (Wii U bank) 0x08C (0x23 * 4) 0x04 bytes Unknown (0x00010000)
1 (Wii U bank) 0x090 (0x24 * 4) 0x10 bytes Wii U Starbuck ancast key
1 (Wii U bank) 0x0A0 (0x28 * 4) 0x10 bytes Wii U SEEPROM key
1 (Wii U bank) 0x0B0 (0x2C * 4) 0x10 bytes Unknown (unused)
1 (Wii U bank) 0x0C0 (0x30 * 4) 0x10 bytes Unknown (unused)
1 (Wii U bank) 0x0D0 (0x34 * 4) 0x10 bytes vWii common key
1 (Wii U bank) 0x0E0 (0x38 * 4) 0x10 bytes Wii U common key
1 (Wii U bank) 0x0F0 (0x3C * 4) 0x10 bytes Unknown (unused)
2 (Wii U bank) 0x100 (0x40 * 4) 0x10 bytes Unknown (unused)
2 (Wii U bank) 0x110 (0x44 * 4) 0x10 bytes Unknown (unused)
2 (Wii U bank) 0x120 (0x48 * 4) 0x10 bytes Key to encrypt/decrypt SSL RSA key
2 (Wii U bank) 0x130 (0x4C * 4) 0x10 bytes Key to encrypt/decrypt seeds for USB storage keys
2 (Wii U bank) 0x140 (0x50 * 4) 0x10 bytes Unknown
2 (Wii U bank) 0x150 (0x54 * 4) 0x10 bytes Wii U XOR key
2 (Wii U bank) 0x160 (0x58 * 4) 0x10 bytes Wii U RNG key
2 (Wii U bank) 0x170 (0x5C * 4) 0x10 bytes Wii U SLC (NAND) key
3 (Wii U bank) 0x180 (0x60 * 4) 0x10 bytes Wii U MLC (eMMC) key
3 (Wii U bank) 0x190 (0x64 * 4) 0x10 bytes Key to encrypt/decrypt SHDD key
3 (Wii U bank) 0x1A0 (0x68 * 4) 0x10 bytes Key to encrypt/decrypt DRH WLAN data
3 (Wii U bank) 0x1B0 (0x6C * 4) 0x30 bytes Unknown (unused)
3 (Wii U bank) 0x1E0 (0x78 * 4) 0x14 bytes Wii U SLC (NAND) HMAC
3 (Wii U bank) 0x1F4 (0x7D * 4) 0x0C bytes Unknown (padding)
4 (Wii U NG bank) 0x200 (0x80 * 4) 0x10 bytes Unknown (unused)
4 (Wii U NG bank) 0x210 (0x84 * 4) 0x0C bytes Unknown (unused)
4 (Wii U NG bank) 0x21C (0x87 * 4) 0x04 bytes Wii U NG ID
4 (Wii U NG bank) 0x220 (0x88 * 4) 0x20 bytes Wii U NG private key
Only 0x1E bytes are used.
4 (Wii U NG bank) 0x240 (0x90 * 4) 0x20 bytes Wii U private key for NSS device certificate
Only 0x1E bytes are used.
4 (Wii U NG bank) 0x260 (0x98 * 4) 0x10 bytes Wii U OTP RNG seed
Only the first 0x04 bytes are used.
4 (Wii U NG bank) 0x270 (0x9C * 4) 0x10 bytes Unknown (unused)
5 (Wii U certificate bank) 0x280 (0xA0 * 4) 0x04 bytes Wii U root certificate MS ID
Always 0x00000012.
5 (Wii U certificate bank) 0x284 (0xA1 * 4) 0x04 bytes Wii U root certificate CA ID
Always 0x00000003.
5 (Wii U certificate bank) 0x288 (0xA2 * 4) 0x04 bytes Wii U root certificate NG key ID
5 (Wii U certificate bank) 0x28C (0xA3 * 4) 0x3C bytes Wii U root certificate NG signature
5 (Wii U certificate bank) 0x2C8 (0xB2 * 4) 0x18 bytes Unknown (unused)
5 (Wii U certificate bank) 0x2E0 (0xB8 * 4) 0x20 bytes Unknown (locked out by boot1)
6 (Wii certificate bank) 0x300 (0xC0 * 4) 0x04 bytes Wii root certificate MS ID
Always 0x00000002.
6 (Wii certificate bank) 0x304 (0xC1 * 4) 0x04 bytes Wii root certificate CA ID
Always 0x00000001
6 (Wii certificate bank) 0x308 (0xC2 * 4) 0x04 bytes Wii root certificate NG key ID
6 (Wii certificate bank) 0x30C (0xC3 * 4) 0x3C bytes Wii root certificate NG signature
6 (Wii certificate bank) 0x348 (0xD2 * 4) 0x10 bytes Wii Korean key
6 (Wii certificate bank) 0x358 (0xD6 * 4) 0x08 bytes Unknown (unused)
6 (Wii certificate bank) 0x360 (0xD8 * 4) 0x20 bytes Wii private key for NSS device certificate
Only 0x1E bytes are used.
7 (Misc bank) 0x380 (0xE0 * 4) 0x20 bytes Unknown (locked out by boot1)
7 (Misc bank) 0x3A0 (0xE8 * 4) 0x10 bytes Wii U boot1 key (locked out by boot0)
7 (Misc bank) 0x3B0 (0xEC * 4) 0x10 bytes Unknown (locked out by boot0, unused)
7 (Misc bank) 0x3C0 (0xF0 * 4) 0x20 bytes Empty
7 (Misc bank) 0x3E0 (0xF8 * 4) 0x04 bytes Empty
7 (Misc bank) 0x3E4 (0xF9 * 4) 0x04 bytes OTP version and revision
7 (Misc bank) 0x3E8 (0xFA * 4) 0x08 bytes OTP date code
7 (Misc bank) 0x3F0 (0xFC * 4) 0x08 bytes OTP version name string
7 (Misc bank) 0x3F8 (0xFE * 4) 0x04 bytes Empty
7 (Misc bank) 0x3FC (0xFF * 4) 0x04 bytes JTAG status
Set to 0xE1 in retail.
If bit 0x80 is set, JTAG is disabled.

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox