Is it possible to get rid of image signature check in U-Boot?

Hello,

I have Acer W6d router, it has 4GB eMMC, there are "kernel" and "rootfs" partitions referred as slot 0 and "kernel1" and "rootfs1" partitions referred as slot 1. In U-Boot, there is an environment variable that decides from which slot system boots up:

dual_boot.current_slot=0

When system is running on slot 0, during the upgrade, new fw is put into slot 1 partitions and in order to boot into new fw, dual_boot.current_slot variable is set to 1 and system boots with new fw.

Currently, I have stock fw (based on openWrt 21.02) in slot 1 and vanilla OpenWrt 23.05.2 in slot 0.

When I try to boot OpenWrt from slot 0, it fails, because signature check fails and router starts to load stock fw from slot 1

Trying to boot from image slot 0
Reading from 0x880000 to 0x40000000, size 0x200 ... OK
Reading from 0x880000 to 0x40000000, size 0x39e7ec ... OK
## Checking hash(es) for FIT Image at 40000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+
Reading from 0x2880000 to 0x4039e7ec, size 0x200 ... OK
Reading from 0x2880000 to 0x4039e7ec, size 0x5de0b0 ... OK
No rootfs node found in FIT image!
Error: rootfs verification failed
Firmware integrity verification failed
Failed to boot from current image slot, error -74
Saving Environment to MMC... Writing to MMC(0)... OK
Trying to boot from image slot 1
Reading from 0x22880000 to 0x40000000, size 0x200 ... OK
Reading from 0x22880000 to 0x40000000, size 0x363cdb ... OK
## Checking hash(es) for FIT Image at 40000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+
Reading from 0x24880000 to 0x40363cdc, size 0x200 ... OK
Reading from 0x24880000 to 0x40363cdc, size 0x2a96c83 ... OK
   Hash(es) for rootfs: crc32+ sha1+
Firmware integrity verification passed

In order to avoid signature check, it is needed to interrupt autoboot (via serial connection with TTL USB adapter), enter U-Boot command line and execute the following commands that read image from eMMC:

// boot without signature check
mmc read 0x40000000 0x00004400 0x0010000
fdt addr $(fdtcontroladdr)
fdt rm /signature
bootm 0x40000000

According to OpenWrt installation instructions from git commit for Acer A6, environment variable bootcmd (default boot command) can be set to include above steps:

setenv bootcmd 'mmc read 0x40000000 0x00004400 0x0010000; fdt addr $(fdtcontroladdr); fdt rm /signature; bootm 0x40000000';
saveenv

Howeveer, first entry which is selected if autoboot process is not interrupted, is mtkboardboot command, because it is the default U-Boot entry as defined by U-Boot environment variables:

bootmenu_0=Startup system (Default)=mtkboardboot
bootmenu_1=Upgrade firmware=mtkupgrade fw
bootmenu_2=Upgrade ATF BL2=mtkupgrade bl2
bootmenu_3=Upgrade ATF FIP=mtkupgrade fip
bootmenu_4=Upgrade eMMC partition table=mtkupgrade gpt
bootmenu_5=Upgrade single image=mtkupgrade simg
bootmenu_6=Load image=mtkload

It is possible to change this entry from U-Boot to include boot command (that would use instructions from bootcmd env variable) instead of mtkboardboot:

MT7986> setenv bootmenu_0 'Startup system (Default)=boot'
MT7986> saveenv
Saving Environment to MMC... Writing to MMC(0)... OK
MT7986>

After such change and execution of 'bootmenu' command that starts U-Boot menu and selecting first entry 'Startup system (Default)', system executes 'bootcmd' command, it reads eMMC memory and boots without signature check.

Unfortunately, after router restart, first default entry (bootmenu_0 U-variable) is reset to mtkboardboot:

bootmenu_0=Startup system (Default)=mtkboardboot

I tried to setup 'preboot' environment variable (it can contain script which is executed before autoboot) to change bootmenu_0 entry to 'boot' insstead of mtkboardboot, but it looks that 'preboot' variable is not used by stock U-Boot from Acer, it is not present after system restart - according to information that I have found, it is used if CONFIG_USE_PREBOOT=y - looks that this was not set during stock U-Boot build.

PROBLEM:
The problem is that after each router restart, bootmenu_0 environment variable in U-Boot is reset / gets back to mtkboardboot causing that next boot will be with signature check, it will fail for vanilla OpenWrt and stock firmware from another slot will be booted. It looks that variable bootmenu_0=Startup system (Default)=mtkboardboot is part of default stock U-Boot environment (created during U-Boot build) and any user changes to this variable will be overwritten after the restart.

QUESTION:
Is there any way to overcome it? Other way than connecting laptop with USB TTL adapter and interrupting autoboot via serial connection for every router restart and manually executing 'mmc read' to boot without signature check?

I know that U-Boot is not part of OpenWrt, but I decided to give a try with this post hoping that there is someone who could help. Maybe there is an U-Boot Specialist here who could help solving that puzzle :slight_smile:

Thanks in advance,
Przemek

1 Like

Let me answer to myself - in order to get rid of signature check, new U-Boot that such check does not perform needs to be installed.

However in this particular case (Acer W6/W6d routers), it is not possible to replace stock U-Boot, because Acer enabled full-chain secure boot - that means BL2 preloader is signed and will be verified by BootROM and it is not possible to replace stock BL2 bootloader without signing it with the same RSA private key as Acer is using.

MediaTek does not provide command in U-Boot console to check if Secure Boot is enabled (in case of Qualcomm it would be 'is_sec_boot_enabled'), below log indicates that:

NOTICE: Verifying BL Anti-Rollback Version ... bl_ar_ver:0=0+ OK

BootROM and BL2 doesn't provide indication about whether secure boot is enabled, but according to above BL2 boot log, secure boot is the prerequisite for anti-rollback and since anti-rollback is enabled, secure boot must also be enabled.

Full bootlog:

F0: 102B 0000
FA: 1040 0000
FA: 1040 0000 [0200]
F9: 103F 0000
F3: 1006 0033 [0200]
F3: 4001 00E0 [0200]
F3: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 2400 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [2000]
T0: 0000 0276 [010F]
Jump to BL

NOTICE:  BL2: v2.6(release):de65b3e9d-dirty
NOTICE:  BL2: Built : 15:22:40, Oct 28 2022
NOTICE:  WDT: disabled
NOTICE:  CPU: MT7986 (2000MHz)
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 1024MB
NOTICE:  EMI: complex R/W mem test passed
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.6(release):de65b3e9d-dirty
NOTICE:  BL31: Built : 15:22:47, Oct 28 2022


U-Boot 2022.07-rc3 (Oct 28 2022 - 15:21:39 +0800), Build: jenkins-YX6_MT7986-AX7800-294

CPU:   MediaTek MT7986
Model: mt7986-rfb
DRAM:  1 GiB
Core:  68 devices, 19 uclasses, devicetree: separate
MMC:   mmc@11230000: 0
Setting bus to 0
Loading Environment from MMC... OK
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:   eth0: ethernet@15100000
mtkautoboot gpio_reset:1

  *** U-Boot Boot Menu ***

      1. Startup system (Default)
      2. Upgrade firmware
      3. Upgrade ATF BL2
      4. Upgrade ATF FIP
      5. Upgrade eMMC partition table
      6. Upgrade single image
      7. Load image
      0. U-Boot console


  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit
Hit any key to stop autoboot:  0
MT7986> setenv dual_boot.current_slot 0
MT7986> mtkboardboot
Trying to boot from image slot 0
Reading from 0x880000 to 0x40000000, size 0x200 ... OK
Reading from 0x880000 to 0x40000000, size 0x3bb1c0 ... OK
## Checking hash(es) for FIT Image at 40000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+
Reading from 0x2880000 to 0x403bb1c0, size 0x200 ... OK
Reading from 0x2880000 to 0x403bb1c0, size 0x1180ecc ... OK
No rootfs node found in FIT image!
Error: rootfs verification failed
Firmware integrity verification failed
Failed to boot from current image slot, error -74
Saving Environment to MMC... Writing to MMC(0)... OK
Trying to boot from image slot 1
Reading from 0x22880000 to 0x40000000, size 0x200 ... OK
Reading from 0x22880000 to 0x40000000, size 0x363cdb ... OK
## Checking hash(es) for FIT Image at 40000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+
Reading from 0x24880000 to 0x40363cdc, size 0x200 ... OK
Reading from 0x24880000 to 0x40363cdc, size 0x2c21c5f ... OK
   Hash(es) for rootfs: crc32+ sha1+
Firmware integrity verification passed
## Loading kernel from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Verifying Hash Integrity ... sha1,rsa2048:fit_key+ OK
   Trying 'kernel-1' kernel subimage
     Description:  ARM64 OpenWrt Linux-5.4.225
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x460000e8
     Data Size:    3527936 Bytes = 3.4 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x48080000
     Entry Point:  0x48080000
     Hash algo:    crc32
     Hash value:   b79241c0
     Hash algo:    sha1
     Hash value:   c250b70c33a7ba40d9e41f3c86424494eb35122d
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Verifying Hash Integrity ... sha1,rsa2048:fit_key+ OK
   Trying 'fdt-1' fdt subimage
     Description:  ARM64 OpenWrt mt7986a-ax7800-2500wan-emmc-rfb-sb device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x4635d73c
     Data Size:    24376 Bytes = 23.8 KiB
     Architecture: AArch64
     Hash algo:    crc32
     Hash value:   4d93a7d1
     Hash algo:    sha1
     Hash value:   15ac1ac045311cadcb019095e8fafee5a4361971
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x4635d73c
   Uncompressing Kernel Image
   Loading Device Tree to 000000007f7ee000, end 000000007f7f6f37 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.4.225 (jenkins@BU10-bl2-Jenkins) (gcc version 8.4.0 (OpenWrt GCC 8.4.0 r0-c7f996bcb)) #0 SMP Fri Feb 24 07:03:21 2023
[    0.000000] Machine model: MediaTek MT7986a RFB
[    0.000000] earlycon: uart8250 at MMIO32 0x0000000011002000 (options '')
[    0.000000] printk: bootconsole [uart8250] enabled
[    0.000000] On node 0 totalpages: 261136
[    0.000000]   DMA32 zone: 4096 pages used for memmap
[    0.000000]   DMA32 zone: 0 pages reserved
[    0.000000]   DMA32 zone: 261136 pages, LIFO batch:63
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.0
[    0.000000] percpu: Embedded 20 pages/cpu s44376 r8192 d29352 u81920
[    0.000000] pcpu-alloc: s44376 r8192 d29352 u81920 alloc=20*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] CPU features: kernel page table isolation disabled by kernel configuration
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 257040
[    0.000000] Kernel command line: console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000 root=/dev/dm-0 rootwait rootfstype=squashfs,f2fs boot_param.no_split_rootfs_data boot_param.boot_kernel_part=PARTUUID=a975393e-a9bc-491f-8133-aeecf6075307 boot_param.boot_rootfs_part=PARTUUID=32798804-a1a7-4f95-ad5a-48939498675b boot_param.upgrade_kernel_part=PARTUUID=971f7556-ef1a-44cd-8b28-0cf8100b9c7e boot_param.upgrade_rootfs_part=PARTUUID=309a3e76-270b-41b2-b5d5-ed8154e7542b boot_param.env_part=PARTUUID=19a4763a-6b19-4a4b-a0c4-8cc34f4c2ab9 boot_param.rootfs_data_part=PARTUUID=5881ba72-d78f-4cbb-8fef-871aeb4b8eef boot_param.boot_image_slot=1 boot_param.upgrade_image_slot=0 boot_param.dual_boot dm-mod.create="dm-verity,,,ro,0 90384 verity 1 PARTUUID=32798804-a1a7-4f95-ad5a-48939498675b PARTUUID=32798804-a1a7-4f95-ad5a-48939498675b 4096 4096 11298 11299 sha256 4fae638245f52ce6e50b59eeec848e7439099179727213572aae4cedcbc9359f 212a5d7279e56d3b74df6346a8a8c4a4f7b5596e15fb2eb97f14e7a99c62
[    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 1013392K/1044544K available (7294K kernel code, 544K rwdata, 2084K rodata, 448K init, 291K bss, 31152K reserved, 0K cma-reserved)

More info about Secure Boot:
Secure Boot

Discussion in Acer W6 thread:
Acer Predator W6 with OpenWrt

Cheers,
Przemek

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.