Line 199: |
Line 199: |
| Stored inside the first bootloader, this firmware binary is split into 4 blobs (names are unofficial): [[#Boot|Boot]] (unencrypted and unauthenticated code), [[#KeygenLdr|KeygenLdr]] (unencrypted and authenticated code), [[#Keygen|Keygen]] (encrypted and authenticated code) and [[#Key data|key data]]. | | Stored inside the first bootloader, this firmware binary is split into 4 blobs (names are unofficial): [[#Boot|Boot]] (unencrypted and unauthenticated code), [[#KeygenLdr|KeygenLdr]] (unencrypted and authenticated code), [[#Keygen|Keygen]] (encrypted and authenticated code) and [[#Key data|key data]]. |
| | | |
− | [6.2.0+] There are now 6 blobs (names are unofficial): [[#Boot|Boot]] (unencrypted and unauthenticated code), [[#Loader|Loader]] (unencrypted and unauthenticated code), [[#KeygenLdr|KeygenLdr]] (unencrypted and authenticated code), [[#Keygen|Keygen]] (encrypted and authenticated code), [[#Payload|Payload]] (part unencrypted and unauthenticated code, part encrypted and authenticated code) and [[#Key data|key data]]. | + | [6.2.0+] There are now 2 new blobs (names are unofficial): [[#SecureBootLdr|SecureBootLdr]] (unencrypted and unauthenticated code), [[#SecureBoot|SecureBoot]] (part unencrypted and unauthenticated code, part encrypted and authenticated code) and [[#Key data|key data]]. |
| | | |
| Firmware can be disassembled with [http://envytools.readthedocs.io/en/latest/ envytools'] [https://github.com/envytools/envytools/tree/master/envydis envydis]: | | Firmware can be disassembled with [http://envytools.readthedocs.io/en/latest/ envytools'] [https://github.com/envytools/envytools/tree/master/envydis envydis]: |
Line 211: |
Line 211: |
| Before returning, this stage writes back to the host (using MMIO registers) and sets the key used by the first bootloader. | | Before returning, this stage writes back to the host (using MMIO registers) and sets the key used by the first bootloader. |
| | | |
− | [6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#Loader|Loader]]. | + | [6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#SecureBoot|SecureBootLdr]]. |
| | | |
| === Initialization === | | === Initialization === |
Line 327: |
Line 327: |
| return boot_res; | | return boot_res; |
| | | |
− | [6.2.0+] Falcon reads the [[#Key data|key data]] and jumps to [[#Loader|Loader]]. | + | [6.2.0+] Falcon reads the [[#Key data|key data]] and jumps to [[#SecureBootLdr|SecureBootLdr]]. |
| u8 key_data_buf[0x84]; | | u8 key_data_buf[0x84]; |
| | | |
Line 912: |
Line 912: |
| This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC key. | | This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC key. |
| | | |
− | == Loader == | + | == SecureBootLdr == |
| This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions). | | This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions). |
− | After the TSEC key has been generated, execution returns to this stage which then parses and executes [[#Payload|Payload]]. | + | After the TSEC key has been generated, execution returns to this stage which then parses and executes [[#SecureBoot|SecureBoot]]. |
| | | |
| === Main === | | === Main === |
Line 987: |
Line 987: |
| u32 blob0_size = *(u32 *)(key_data_buf + 0x70); | | u32 blob0_size = *(u32 *)(key_data_buf + 0x70); |
| | | |
− | // Read the Payload blob's Falcon header from memory | + | // Read the SecureBoot blob's Falcon header from memory |
| u32 blob4_flcn_hdr_addr = (((blob0_size + blob1_size) + 0x100) + blob2_size); | | u32 blob4_flcn_hdr_addr = (((blob0_size + blob1_size) + 0x100) + blob2_size); |
| read_code(flcn_hdr_buf, blob4_flcn_hdr_addr, 0x18); | | read_code(flcn_hdr_buf, blob4_flcn_hdr_addr, 0x18); |
Line 996: |
Line 996: |
| u32 flcn_hdr_size = *(u32 *)(flcn_hdr_buf + 0x0C); | | u32 flcn_hdr_size = *(u32 *)(flcn_hdr_buf + 0x0C); |
| | | |
− | // Read the Payload blob's Falcon OS header from memory | + | // Read the SecureBoot blob's Falcon OS header from memory |
| u32 blob4_flcn_os_hdr_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_hdr_size); | | u32 blob4_flcn_os_hdr_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_hdr_size); |
| read_code(flcn_os_hdr_buf, blob4_flcn_os_hdr_addr, 0x10); | | read_code(flcn_os_hdr_buf, blob4_flcn_os_hdr_addr, 0x10); |
Line 1,006: |
Line 1,006: |
| u32 flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); | | u32 flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); |
| | | |
− | // Read the Payload blob's Falcon OS image from memory | + | // Read the SecureBoot blob's Falcon OS image from memory |
| u32 blob4_flcn_os_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size); | | u32 blob4_flcn_os_addr = ((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size); |
| read_code(boot_base_addr, blob4_flcn_os_hdr_addr, flcn_os_size); | | read_code(boot_base_addr, blob4_flcn_os_hdr_addr, flcn_os_size); |
| | | |
− | // Upload the Payload's Falcon OS image boot stub code segment into Falcon's CODE region | + | // Upload the SecureBoot's Falcon OS image boot stub code segment into Falcon's CODE region |
| u32 blob4_flcn_os_boot_virt_addr = 0; | | u32 blob4_flcn_os_boot_virt_addr = 0; |
| u32 blob4_flcn_os_boot_size = 0x100; | | u32 blob4_flcn_os_boot_size = 0x100; |
Line 1,018: |
Line 1,018: |
| flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); | | flcn_os_size = *(u32 *)(flcn_os_hdr_buf + 0x04); |
| | | |
− | // Upload the Payload blob's Falcon OS encrypted image code segment into Falcon's CODE region | + | // Upload the SecureBoot blob's Falcon OS encrypted image code segment into Falcon's CODE region |
| u32 blob4_flcn_os_img_virt_addr = 0x100; | | u32 blob4_flcn_os_img_virt_addr = 0x100; |
| u32 blob4_flcn_os_img_size = (flcn_os_size - 0x100); | | u32 blob4_flcn_os_img_size = (flcn_os_size - 0x100); |
Line 1,033: |
Line 1,033: |
| u32 flcn_os_code_size = *(u32 *)(flcn_os_hdr_buf + 0x08); | | u32 flcn_os_code_size = *(u32 *)(flcn_os_hdr_buf + 0x08); |
| | | |
− | // Read the Payload blob's falcon OS image's hash from memory | + | // Read the SecureBoot blob's falcon OS image's hash from memory |
| u32 blob4_flcn_os_img_hash_addr = (((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size) + flcn_os_code_size); | | u32 blob4_flcn_os_img_hash_addr = (((((blob0_size + blob1_size) + 0x100) + blob2_size) + flcn_code_hdr_size) + flcn_os_code_size); |
| read_code(0, blob4_flcn_os_img_hash_addr, 0x10); | | read_code(0, blob4_flcn_os_img_hash_addr, 0x10); |
Line 1,044: |
Line 1,044: |
| u32 data_addr = 0x10; | | u32 data_addr = 0x10; |
| | | |
− | // Clear all data except the first 0x10 bytes (Payload blob's Falcon OS image's hash) | + | // Clear all data except the first 0x10 bytes (SecureBoot blob's Falcon OS image's hash) |
| for (int data_word_count = 0x04; data_word_count < data_seg_size; data_word_count++) | | for (int data_word_count = 0x04; data_word_count < data_seg_size; data_word_count++) |
| { | | { |
Line 1,065: |
Line 1,065: |
| csigclr(); | | csigclr(); |
| | | |
− | // Jump to Payload | + | // Jump to SecureBoot |
| exec_payload(); | | exec_payload(); |
| | | |
| return 0xB0B0B0B0; | | return 0xB0B0B0B0; |
| | | |
− | == Payload == | + | == SecureBoot == |
− | This stage prepares the stack then authenticates, decrypts and executes the Payload blob's Falcon OS image. | + | This stage prepares the stack then authenticates, decrypts and executes the SecureBoot blob's Falcon OS image. |
| | | |
| === Main === | | === Main === |
Line 1,082: |
Line 1,082: |
| *(u32 *)sp = data_seg_size; | | *(u32 *)sp = data_seg_size; |
| | | |
− | // Jump to the Payload blob's Falcon OS image boot stub | + | // Jump to the SecureBoot blob's Falcon OS image boot stub |
| exec_flcn_os_boot(); | | exec_flcn_os_boot(); |
| | | |
Line 1,132: |
Line 1,132: |
| *(u8 *)flags_ie1 = 0; | | *(u8 *)flags_ie1 = 0; |
| | | |
− | // Jump to the Payload blob's Falcon OS image | + | // Jump to the SecureBoot blob's Falcon OS image |
| exec_flcn_os_img(); | | exec_flcn_os_img(); |
| | | |
Line 1,187: |
Line 1,187: |
| | 0x7C | | | 0x7C |
| | 0x04 | | | 0x04 |
− | | [6.2.0+] blob3 ([[#Loader|Loader]]) size | + | | [6.2.0+] blob3 ([[#SecureBootLdr|SecureBootLdr]]) size |
| |- | | |- |
| | 0x80 | | | 0x80 |
| | 0x04 | | | 0x04 |
− | | [6.2.0+] blob4 ([[#Payload|Payload]]) size | + | | [6.2.0+] blob4 ([[#SecureBoot|SecureBoot]]) size |
| |} | | |} |