BCT (Boot Configuration Table) is a data structure present on Tegra based devices that supplies boot time configuration parameters.
The Switch's BCT is included in the firmware package titles (0100000000000819 and 010000000000081A) and is installed into eMMC storage's boot partition 0. A total of four BCT copies can be installed into the system: normal, normal backup, safe mode and safe mode backup.
The Erista BCT's data is only signed after offset 0x0510. Therefore, regions like CustomerData can be freely modified without resigning. This is done by NS when injecting a new keyblob during a system update, for example.
The Mariko BCT's data is signed and encrypted, so the keyblob system is no longer used.
During boot, the boot ROM parses the appropriate BCT from eMMC storage and stores a copy of it in IRAM at address 0x40000000.
Format
Below are the BCT structure formats used by the Switch.
Erista
Offset | Size | Field | Description |
---|---|---|---|
0x0000 | 0x210 | BadBlockTable | Table containing information on bad blocks
0x0000: EntriesUsed (0x200) 0x0004: VirtualBlockSizeLog2 (0x0F) 0x0005: BlockSizeLog2 (0x0E) 0x0006: BadBlocks 0x0206: Reserved |
0x0210 | 0x100 | Key | BCT RSA public key's modulus |
0x0310 | 0x110 | Signature | BCT cryptographic signature
0x0310: CryptoHash (empty) 0x0320: RsaPssSig |
0x0420 | 0x04 | SecProvisioningKeyNumInsecure | Used for Factory Secure Provisioning (always 0) |
0x0424 | 0x20 | SecProvisioningKey | Used for Factory Secure Provisioning (always 0) |
0x0444 | 0xC4 | CustomerData | Data block available for the customer (used in key generation)
0x0444: Reserved (0x0C bytes) 0x0450: Keyblob (0xB0 bytes) 0x0500: Reserved (0x08 bytes) |
0x0508 | 0x04 | OdmData | Legacy field (unused) |
0x050C | 0x04 | Reserved | Legacy field (unused) |
0x0510 | 0x10 | RandomAesBlock | Always empty |
0x0520 | 0x10 | UniqueChipId | Always empty |
0x0530 | 0x04 | BootDataVersion | Set to 0x00210001 (BOOTDATA_VERSION_T210) |
0x0534 | 0x04 | BlockSizeLog2 | Always 0x0E |
0x0538 | 0x04 | PageSizeLog2 | Always 0x09 |
0x053C | 0x04 | PartitionSize | Always 0x01000000 |
0x0540 | 0x04 | NumParamSets | Number of device parameter sets (always 0x01) |
0x0544 | 0x04 | DevType | Device type (0x04 == Sdmmc) |
0x0548 | 0x40 | DevParams | Device parameters
0x0548: ClockDivider (0x09 == 24MHz) 0x054C: DataWidth (0x02 == 8Bit) |
0x0588 | 0x04 | NumSdramSets | Number of SDRAM parameter sets (always set to 0, but parameters are used despite this) |
0x058C | 0x768 | SdramParams0 | Default values filled in |
0x0CF4 | 0x768 | SdramParams1 | Default values filled in |
0x145C | 0x768 | SdramParams2 | Default values filled in |
0x1BC4 | 0x768 | SdramParams3 | Default values filled in |
0x232C | 0x04 | BootLoadersUsed | Number of bootloaders installed (always 0x02, maximum is 0x04) |
0x2330 | 0x12C | BootLoader0 | Configuration parameters for bootloader 0 (normal)
0x2330: Version (variable) 0x2334: StartBlock (0x00000040) 0x2338: StartPage (0x00000000) 0x233C: Length (variable) 0x2340: LoadAddress (0x40010000) 0x2344: EntryPoint (0x40010020 for 1.0.0-3.0.2, 0x40010040 for 4.0.0+) 0x2348: Attribute (0x00000000) 0x234C: CryptoHash (empty) 0x235C: RsaPssSig |
0x245C | 0x12C | BootLoader1 | Configuration parameters for bootloader 1 (safe mode)
0x245C: Version (variable) 0x2460: StartBlock (0x00000050) 0x2464: StartPage (0x00000000) 0x2468: Length (variable) 0x246C: LoadAddress (0x40010000) 0x2470: EntryPoint (0x40010020 for 1.0.0-3.0.2, 0x40010040 for 4.0.0+) 0x2474: Attribute (0x00000000) 0x2478: CryptoHash (empty) 0x2488: RsaPssSig |
0x2588 | 0x12C | BootLoader2 | Reserved space for bootloader 2 (unused) |
0x26B4 | 0x12C | BootLoader3 | Reserved space for bootloader 3 (unused) |
0x27E0 | 0x01 | EnableFailBack | Always 0 |
0x27E1 | 0x04 | SecureJtagControl | Always 0 |
0x27E5 | 0x04 | SecProvisioningKeyNumSecure | Used for Factory Secure Provisioning (always 0) |
0x27E9 | 0x12 | Reserved | Always starts with 0x80000000 (NVBOOT padding pattern) |
0x27FB | 0x05 | Padding | Empty |
CustomerData
This data block is ignored by the boot ROM, therefore is available for the programmer to use freely. The Switch uses 0xB0 bytes of this area, at offset 0x0450, to store the active keyblob. All remaining bytes are zero.
The first bootloader validates and decrypts this block for further key generation. The decrypted keyblob payload is as follows.
Offset | Size | Description |
---|---|---|
0x0 | 0x80 | Array of master static key encryption keys |
0x80 | 0x10 | PK11 key |
BootLoader0
The version field controls which keyblob is used, where 0x01 is the first one. See Cryptosystem for the keyblobs used by each system-version.
Mariko
Offset | Size | Field | Description |
---|---|---|---|
0x0000 | 0x0210 | Pcp | BCT public cryptographic parameters
0x0000: KeySize 0x0004: Reserved 0x0010: PublicKeyModulus 0x0110: PublicKeyExponent |
0x0210 | 0x0110 | Signature | BCT cryptographic signature
0x0210: CryptoHash (empty) 0x0220: RsaPssSig |
0x0320 | 0x0160 | Empty | |
0x0480 | 0x2380 | Encrypted BCT data |