Secure boot and mtk_uartboot

I am totally lost and need some education.

So I have these MT7988D routers with Secure Boot enabled. I can live with that, since Zyxel are chainloading their own application with broken signature verification.

But testing mtk_uartboot for fun, and wanting to see what would happen if it was allowed to run past the panic!("Secure boot enabled.");, I got this:

bjorn@miraculix:/usr/local/src/git/arm-trusted-firmware$ ../mtk_uartboot/target/debug/mtk_uartboot -p  ./build/mt7988/release/bl2.bin -f /tmp/fip --aarch64  -s /dev/ttyUSB3 
mtk_uartboot - 0.1.1
Using serial port: /dev/ttyUSB3
Handshake...
hw code: 0x7988
hw sub code: 0x8a00
hw ver: 0xcb00
sw ver: 0x1
sw ver: 0x1
target config: 0xe1
Baud rate set to 460800
sending payload to 0x201000...
Checksum: 0xa5b8
Setting baudrate back to 115200
Jumping to 0x201000 in aarch64...
Waiting for BL2. Message below:
==================================
NOTICE:  BL2: v2.13.0(release):v2.4-rc0-9074-g78a0dfd927bb
NOTICE:  BL2: Built : 12:36:17, Dec 15 2025
NOTICE:  WDT: Cold boot
NOTICE:  WDT: disabled
NOTICE:  CPU: MT7988
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 1024 MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  LVTS: Enable thermal HW reset
NOTICE:  Starting UART download handshake ...
==================================
BL2 UART DL version: 0x10
Baudrate set to: 921600
FIP sent.
==================================
NOTICE:  Received FIP 0x1758a3 @ 0x40400000 ...
==================================

So what happened here? The FIP is something I pulled from flash, so that's not interesting. But the BL2 was built by me from the mtk ATF repo, with ramboot and download support, and is definitely not signed by anything. At least not anything with a key hash in any efuses.

Why did this work? What is the point of the Secure Boot flag if it isn't enforced?

FWIW, the target config: 0xe1 is something I added when commenting out the panic()s. It's the register value which mtk_uartboot normally would do this on:

       let secure_boot = target_config & 1 != 0;
        let serial_link_authorization = target_config & 2 != 0;
        let download_agent_authorization = target_config & 4 != 0;

and then panic if any of those are true. So secure_boot is the only bit of those which are set here, which might explain why the serial download works?

could be related to what's described in Step 2 of Adding OpenWrt support for Zyxel EX5601-T0 - #1101 by carlicious.

I think this is something else. In my case the zloader is actually a signed FIT image. I can't patch it. The signature is verified by the FIP from Zyxel. This sort of works, so they have learned something :slight_smile:

And I assume that I still can't replace the BL2 on flash without Secure Boot problems. Not sure I want to take the risk verifying that assumption... I don't have any device to spare. Although mtk_uartboot makes a rescue possible in theory.

The question was about the bootrom restrictions with SB enabled. But thinking more about this, it does make sense, doesn't it? There are separat efuses for the uartboot and download features, so a vendor wanting to lock those down can do so. There is nothing lost by making the SB flag apply only to code loaded from flash. Allowing unsigned uartboot doesn't open up any new holes as long as the bootrom enforces signed flash booting. Serial boot from bootrom is an extremely useful safety net, which is even more important with Secure Boot enabled.

If I recall, the bit that enables secure boot verification is separate from the one that disables the bootrom commands and jtag. They (Mediatek) specifically tell you to disable it in the documentation for secure boot for this very reason, so that you don’t end up breaking chain of trust.

Could you copy paste bootrom output from serial so we can verify? It should be a block of text that starts with something like…

F0: 102B 0000

… and goes on until it passes to BL2 etc.

It probably shouldn’t have gone to production with the bootrom commands enabled if they had secure boot on as well, if they were following the SDK documentation?

You wouldn't happen to have a pointer to the meaning of that magic bootrom output? I've been looking for it, without finding anything.

F0: 102B 0000
FA: 1042 0000
FA: 1042 0000 [0200]
F9: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 0600 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [1000]
MK: 0000 0000 [0000]
T0: 0000 01D1 [0101]
Jump to BL
 
NOTICE:  BL2: v2.12.0(release):91f378549
NOTICE:  BL2: Built : 14:16:29, Nov 17 2025
NOTICE:  WDT: [40000000] Software reset (reboot)
NOTICE:  CPU: MT7988
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 1024 MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  LVTS: Enable thermal HW reset
NOTICE:  SPI_NAND parses attributes from parameter page.
NOTICE:  SPI_NAND Detected ID 0xc2
NOTICE:  Page size 4096, Block size 262144, size 536870912
NOTICE:  Initializing NMBM ...
NOTICE:  Signature found at block 2047 [0x1ffc0000]
NOTICE:  First info table with writecount 0 found in block 1920
NOTICE:  Second info table with writecount 0 found in block 1923
NOTICE:  NMBM has been successfully attached in read-only mode
NOTICE:  Verifying BL Anti-Rollback Version ... bl_ar_ver:0>=0+ OK
NOTICE:  Verifying BL Anti-Rollback Version ... bl_ar_ver:0>=0+ OK
NOTICE:  Verifying BL Anti-Rollback Version ... bl_ar_ver:0>=0+ OK
NOTICE:  Verifying BL Anti-Rollback Version ... bl_ar_ver:0>=0+ OK
NOTICE:  Verifying BL Anti-Rollback Version ... bl_ar_ver:0>=0+ OK
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v2.12.0(release):91f378549
NOTICE:  BL31: Built : 14:16:33, Nov 17 2025

There is a slight chance that this is all intentional and will be fixed for production, since this device has a sticker with "sample only". If so, then I guess I am wasting my time.

This appears to indicate you indeed have both bootrom commands and jtag enabled? That’s a bit strange for a secure boot enabled unit.