Line 4: |
Line 4: |
| | | |
| = Format = | | = Format = |
| + | == Erista == |
| This package is distributed as a plaintext initial bootloader (package1ldr) and a secondary encrypted blob ("PK11"). Execution starts at plaintext package1ldr which will set up hardware, generate keys and decrypt the next stage. | | This package is distributed as a plaintext initial bootloader (package1ldr) and a secondary encrypted blob ("PK11"). Execution starts at plaintext package1ldr which will set up hardware, generate keys and decrypt the next stage. |
− |
| |
− | == Package1ldr ==
| |
− | The code for this stage is stored in plaintext inside the package. By looking into the BCT's bootloader0_info (normal) or bootloader1_info (safe mode), the boot ROM starts executing this stage at address 0x40010020 in IRAM (0x40010040 for 4.0.0+).
| |
| | | |
| === Header === | | === Header === |
Line 18: |
Line 16: |
| | 0x0 | | | 0x0 |
| | 0x4 | | | 0x4 |
− | | Package1ldr hash (first four bytes of SHA256(package1ldr)). | + | | Package1ldr hash (first four bytes of SHA256(package1ldr)) |
| |- | | |- |
| | 0x4 | | | 0x4 |
| | 0x4 | | | 0x4 |
− | | Secure Monitor hash (first four bytes of SHA256(secure_monitor)). | + | | Secure Monitor hash (first four bytes of SHA256(secure_monitor)) |
| |- | | |- |
| | 0x8 | | | 0x8 |
| | 0x4 | | | 0x4 |
− | | NX Bootloader hash (first four bytes of SHA256(nx_bootloader)). | + | | NX Bootloader hash (first four bytes of SHA256(nx_bootloader)) |
| |- | | |- |
| | 0xC | | | 0xC |
Line 41: |
Line 39: |
| |} | | |} |
| | | |
− | === Initialization === | + | === Package1ldr === |
| + | The code for this stage is stored in plaintext inside the package. By looking into the BCT's bootloader0_info (normal) or bootloader1_info (safe mode), the boot ROM starts executing this stage at address 0x40010020 in IRAM (0x40010040 for 4.0.0+). |
| + | |
| + | ==== Initialization ==== |
| The stack pointer is set. | | The stack pointer is set. |
| | | |
Line 55: |
Line 56: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | === Main === | + | ==== Main ==== |
| The bootloader poisons the exception vectors, cleans up memory (.bss and init_array), sets up hardware devices (including the security engine and fuses), does all the necessary checks, generates keys and finally decrypts and executes the next stage. | | The bootloader poisons the exception vectors, cleans up memory (.bss and init_array), sets up hardware devices (including the security engine and fuses), does all the necessary checks, generates keys and finally decrypts and executes the next stage. |
| | | |
Line 303: |
Line 304: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | ==== Panic ==== | + | ===== Panic ===== |
| If a panic occurs, all sensitive memory contents are cleared, the security engine and fuse programming are disabled and the boot processor is left in a halted state. | | If a panic occurs, all sensitive memory contents are cleared, the security engine and fuse programming are disabled and the boot processor is left in a halted state. |
| | | |
Line 328: |
Line 329: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | ==== Anti-downgrade ==== | + | ===== Anti-downgrade ===== |
| See [[Fuses#Anti-downgrade|Anti-downgrade]]. | | See [[Fuses#Anti-downgrade|Anti-downgrade]]. |
| | | |
− | ==== Memory controllers ==== | + | ===== Memory controllers ===== |
| After disabling fuse programming, the bootloader configures the EMC and MEM/MC. It additionally disables QSPI resets and programs a special aperture designed for AHB redirected access to IRAM. | | After disabling fuse programming, the bootloader configures the EMC and MEM/MC. It additionally disables QSPI resets and programs a special aperture designed for AHB redirected access to IRAM. |
| | | |
Line 387: |
Line 388: |
| [6.2.0+] MC_IRAM_TOM is now set to 0x80000000 to allow TSEC to access IRAM and all MMIO. | | [6.2.0+] MC_IRAM_TOM is now set to 0x80000000 to allow TSEC to access IRAM and all MMIO. |
| | | |
− | ==== Key generation ==== | + | ===== Key generation ===== |
| After the security engine is ready and before decrypting the next stage, the bootloader initializes and generates several keys into hardware keyslots. | | After the security engine is ready and before decrypting the next stage, the bootloader initializes and generates several keys into hardware keyslots. |
| For more details on the Switch's cryptosystem, please see [[Cryptosystem|this page]]. | | For more details on the Switch's cryptosystem, please see [[Cryptosystem|this page]]. |
Line 393: |
Line 394: |
| [6.2.0+] The key generation process was moved into an encrypted [[TSEC]] payload. | | [6.2.0+] The key generation process was moved into an encrypted [[TSEC]] payload. |
| | | |
− | ===== Selection ===== | + | ====== Selection ====== |
| Depending on [[Fuses#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]] and [[Fuses#FUSE_SPARE_BIT_5|FUSE_SPARE_BIT_5]] different static seeds are selected for key generation. | | Depending on [[Fuses#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]] and [[Fuses#FUSE_SPARE_BIT_5|FUSE_SPARE_BIT_5]] different static seeds are selected for key generation. |
| | | |
Line 484: |
Line 485: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | ===== generate_retail_keys ===== | + | ====== generate_retail_keys ====== |
| In order to generate retail keys, the bootloader starts by initializing TSEC and grabbing it's [[TSEC#TSEC_key_generation|device key]]. Using static seeds and the SBK, the keyblob injected into the BCT's [[BCT#customer_data|customer_data]] is validated and decrypted. The resulting keys will then be used to generate the master static key and the master device key. | | In order to generate retail keys, the bootloader starts by initializing TSEC and grabbing it's [[TSEC#TSEC_key_generation|device key]]. Using static seeds and the SBK, the keyblob injected into the BCT's [[BCT#customer_data|customer_data]] is validated and decrypted. The resulting keys will then be used to generate the master static key and the master device key. |
| | | |
Line 602: |
Line 603: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | ===== generate_debug_keys ===== | + | ====== generate_debug_keys ====== |
| In order to generate debug keys, the bootloader only uses static seeds, the SBK and the SSK. | | In order to generate debug keys, the bootloader only uses static seeds, the SBK and the SSK. |
| | | |
Line 670: |
Line 671: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | == Package1 (PK11) == | + | === Package1 (PK11) === |
| This blob is stored encrypted inside the package and is decrypted by package1ldr. | | This blob is stored encrypted inside the package and is decrypted by package1ldr. |
| | | |
− | === Encryption === | + | ==== Encryption ==== |
| The encrypted blob is prepended with it's CTR and total image size. After checking the image's size against an hardcoded value (can change on firmware updates), the image is AES-CTR decrypted and the keyslot used for decryption is immediately cleared. | | The encrypted blob is prepended with it's CTR and total image size. After checking the image's size against an hardcoded value (can change on firmware updates), the image is AES-CTR decrypted and the keyslot used for decryption is immediately cleared. |
| | | |
Line 721: |
Line 722: |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | === Header === | + | ==== Header ==== |
| When decrypted, the blob is encapsulated in the following header. | | When decrypted, the blob is encapsulated in the following header. |
| | | |
Line 765: |
Line 766: |
| What each section is used for may vary per system-version. | | What each section is used for may vary per system-version. |
| | | |
− | === Section 0 === | + | ==== Section 0 ==== |
| This section contains the warmboot binary. | | This section contains the warmboot binary. |
| | | |
− | === Section 1 === | + | ==== Section 1 ==== |
| This section contains the NX bootloader, which is run after the initial bootloader in package1. | | This section contains the NX bootloader, which is run after the initial bootloader in package1. |
| | | |
− | === Section 2 === | + | ==== Section 2 ==== |
| This section contains the Secure Monitor binary. | | This section contains the Secure Monitor binary. |
| | | |
− | = Changelog = | + | == Mariko == |
− | == 2.0.0 ==
| + | This package is now distributed in a custom, signed and encrypted format. |
− | * The encrypted binaries' order and calculation for next stage's entrypoint was changed.
| |
| | | |
− | Old layout (before 2.0.0):
| + | {| class="wikitable" border="1" |
− | 1.- PK11 header
| + | |- |
− | 2.- Secure Monitor blob
| + | ! Offset |
− | 3.- NX bootloader blob
| + | ! Size |
− | 4.- Warmboot blob
| + | ! Description |
− | | + | |- |
− | NX bootloader entrypoint is calculated as: | + | | 0x0 |
− | 0x40013FE0 + 0x20 + 0x20 + NX bootloader blob's offset + Secure Monitor blob's size
| + | | 0x110 |
− | | + | | Cryptographic signature |
− | New layout (2.0.0+):
| + | 0x0000: CryptoHash (empty) |
− | 1.- PK11 header
| + | 0x0010: RsaPssSig |
− | 2.- Warmboot blob
| + | |- |
− | 3.- NX bootloader blob
| + | | 0x110 |
− | 4.- Secure Monitor blob
| + | | 0x20 |
− |
| + | | Unknown (random block?) |
− | NX bootloader entrypoint is calculated as:
| + | |- |
− | 0x40013FE0 + 0x20 + 0x20 + NX bootloader blob's offset + Warmboot blob's size
| + | | 0x130 |
− | | + | | 0x20 |
− | * Some AES-ECB decryption related code was refactored.
| + | | SHA256 hash over package1 data |
− | | + | |- |
− | == 3.0.0 ==
| + | | 0x150 |
− | * The functions set_se_addr() and check_se_status() are now called right after enabling the security engine clocks and resets.
| + | | 0x4 |
− | See [[Switch_System_Flaws#Stage_1_Bootloader]].
| + | | Version |
− | | + | |- |
− | * Keyslot 0x0A is now used instead of keyslot 0x0D for generating the master_device_key.
| + | | 0x154 |
| + | | 0x4 |
| + | | Length |
| + | |- |
| + | | 0x158 |
| + | | 0x4 |
| + | | LoadAddress |
| + | |- |
| + | | 0x15C |
| + | | 0x4 |
| + | | EntryPoint |
| + | |- |
| + | | 0x160 |
| + | | 0x10 |
| + | | Unknown (empty) |
| + | |- |
| + | | 0x170 |
| + | | Variable |
| + | | Package1 data |
| + | 0x0170: Header |
| + | 0x0190: Body (encrypted) |
| + | |} |