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.
By design, the 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.
During boot, the boot ROM parses the appropriate BCT from eMMC storage and stores a copy of it in IRAM at address 0x40000000.
Structure
Below is the BCT structure used by the Switch, which is a minimal variation of the Tegra 210 BCT format.
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 object 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 empty. |
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. Set to 0x04 (dev_type_sdmmc). |
0x0548 | 0x40 | DevParams | Device parameters
0x0548: sdmmc_clock_divider (0x09 == 24MHz) 0x054C: sdmmc_data_width (0x02 == sdmmc_data_width_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. Not part of BCT data. |
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.