Open lkernan opened 4 days ago
Thanks for uploading the boot.img
! It looks like it's a u-boot FIT image, not a standard Android boot image. I've never seen this combo of AVB 2.0 + non-Android boot image format before.
It's unlikely I'll add support parsing these boot images. The format is quite a bit more complex to parse than standard Android boot images and it's not very common. The best I could do is maybe add a --skip-ota-certs
option, which in addition to --rootless
, would make avbroot not touch the boot image at all (it would only do AVB and OTA signing).
❯ mkimage -l boot.img
Image contains unit addresses @, this will break signing
FIT description: U-Boot fitImage for Android 147456/4.9/auto2712m1v1-initramfs
Created: Mon Sep 11 03:51:55 2023
Image 0 (kernel@1)
Description: Linux kernel
Created: Mon Sep 11 03:51:55 2023
Type: Kernel Image
Compression: lz4 compressed
Data Size: 11582667 Bytes = 11311.20 KiB = 11.05 MiB
Architecture: ARM
OS: Linux
Load Address: 0x40008000
Entry Point: 0x40008000
Hash algo: sha256
Hash value: dfde18fbb1d1fee962eebad7a548de59ca95e6eaea403792496edbd8ded522a7
Image 1 (ramdisk@1)
Description: Ramdisk Image
Created: Mon Sep 11 03:51:55 2023
Type: RAMDisk Image
Compression: uncompressed
Data Size: 7961761 Bytes = 7775.16 KiB = 7.59 MiB
Architecture: ARM
OS: Linux
Load Address: 0x4a000000
Entry Point: 0x4a000000
Hash algo: sha256
Hash value: def3f7cee122d0951c070626c7ff1d17b6a6d36f06d959ed5aea172fde4f8019
Image 2 (fdt@1)
Description: Flattened Device Tree blob
Created: Mon Sep 11 03:51:55 2023
Type: Flat Device Tree
Compression: uncompressed
Data Size: 98058 Bytes = 95.76 KiB = 0.09 MiB
Architecture: ARM
Load Address: 0x44000000
Hash algo: sha256
Hash value: 1bb0072041178e90ad866eeffa7f6a08b4d57c94f777bec76b44f50e95167778
Default Configuration: 'conf@1'
Configuration 0 (conf@1)
Description: Boot Linux kernel with FDT blob
Kernel: kernel@1
Init Ramdisk: ramdisk@1
FDT: fdt@1
Sign algo: sha256,rsa2048:dev
Sign value: unavailable
Timestamp: unavailable
dumpimage -T flat_dt -p 0 -o kernel boot.img
dumpimage -T flat_dt -p 1 -o ramdisk boot.img
dumpimage -T flat_dt -p 2 -o devicetree boot.img
Thanks, at least for my purposes not touching the boot image at all would work. As long as I can patch the file in /system/bin and put the payload.bin back together.
The whole system has been confusing the heck out of me. Probably not a surprise it's based on a Mediatek SDK.
I'm reluctant to do too much since fastboot and recovery aren't easily accessible either.
I think the uboot console might be on a serial console but that's probably going to require opening the unit.
edit: I did a little more digging and found a mention of this AVB setup in the u-boot docs. https://github.com/u-boot/u-boot/blob/master/doc/android/avb2.rst
Car infotainment systems definitely seem to be quite a bit more... interesting than phones.
I totally get the reluctance to try stuff. I haven't messed with my car's infotainment system because it can only boot into recovery or fastboot with adb reboot
. There's no other physical way to do so, even if disassembled. People who've flashed an unbootable boot.img
have had to manually reflash a working image with a NAND programmer to get things going again.
Please give #367 a try, which adds a new --skip-recovery-ota-cert
option. Prebuilt binaries can be found at the bottom of this page: https://github.com/chenxiaolong/avbroot/actions/runs/11674513228?pr=367
I've given it a try and it looks like it's still trying to do something with the boot.img
leon@cartman:~/Downloads/avbroot$ ./avbroot ota patch --input usb_ota_update.zip --key-ota testkey.x509.key --key-avb testkey.x509.key --cert-ota testkey.x509.crt --rootless --skip-recovery-ota-cert --log-level trace 0.000s DEBUG cli=Cli { command: Ota(OtaCli { command: Patch(PatchCli { input: "usb_ota_update.zip", output: None, key_avb: "testkey.x509.key", key_ota: "testkey.x509.key", cert_ota: "testkey.x509.crt", pass_avb_env_var: None, pass_avb_file: None, pass_ota_env_var: None, pass_ota_file: None, signing_helper: None, replace: [], root: RootGroup { magisk: None, prepatched: None, rootless: true }, magisk_preinit_device: None, magisk_random_seed: None, ignore_magisk_warnings: false, ignore_prepatched_compat: 0, skip_recovery_ota_cert: true, dsu: false, clear_vbmeta_flags: false, zip_mode: Streaming, boot_partition: None }) }), log_level: Level(Trace), log_format: Short } 0.000s WARN Not inserting OTA cert into recovery image; sideloading further updates may fail 0.001s INFO zip{entry="META-INF/com/android/otacert"}: Replacing zip entry: META-INF/com/android/otacert 0.001s INFO zip{entry="care_map.txt"}: Copying zip entry: care_map.txt 0.001s INFO zip{entry="checksoc.txt"}: Copying zip entry: checksoc.txt 0.001s INFO zip{entry="compatibility.zip"}: Copying zip entry: compatibility.zip 0.001s INFO zip{entry="payload.bin"}: Patching zip entry: payload.bin 0.002s INFO zip{entry="payload.bin"}:image{name="system"}: Extracting from original payload: system 1.952s INFO zip{entry="payload.bin"}:image{name="boot"}: Extracting from original payload: boot 1.999s INFO zip{entry="payload.bin"}:image{name="vbmeta"}: Extracting from original payload: vbmeta 2.000s INFO zip{entry="payload.bin"}: Candidate boot images: boot 2.337s ERROR Failed to patch OTA zip
Caused by: 0: Failed to patch payload: payload.bin 1: Failed to patch boot images: boot 2: Boot image error 3: Unknown boot image format leon@cartman:~/Downloads/avbroot$
Ah shoot, yeah, it was still loading boot images even when there was nothing to patch. ce87757fd1041fc4af8facee235e6211424241dd should fix that. New test build: https://github.com/chenxiaolong/avbroot/actions/runs/11686270136?pr=367
Thanks, that got a lot further.
Does that error mean I messed up the keys somewhere?
leon@cartman:~/Downloads/avbroot$ ./avbroot ota patch --input usb_ota_update.zip --key-ota testkey.x509.key --key-avb testkey.x509.key --cert-ota testkey.x509.crt --rootless --skip-recovery-ota-cert 0.000s WARN Not inserting OTA cert into recovery image; sideloading further updates may fail 0.001s INFO Replacing zip entry: META-INF/com/android/otacert 0.001s INFO Copying zip entry: care_map.txt 0.001s INFO Copying zip entry: checksoc.txt 0.001s INFO Copying zip entry: compatibility.zip 0.001s INFO Patching zip entry: payload.bin 0.001s INFO Extracting from original payload: vbmeta 0.002s INFO Extracting from original payload: system 1.880s INFO Extracting from original payload: boot 1.926s INFO Candidate boot images: boot 1.930s INFO Patching system image: system 4.566s INFO Patched otacerts.zip offsets in system: [1474662400..1474663473] 4.566s INFO Patching vbmeta images: vbmeta 4.900s ERROR Failed to patch OTA zip
Caused by: 0: Failed to patch payload: payload.bin 1: RSA public key exponent not supported: 3
Hmm, yeah, it looks like testkey.x509.key
is definitely not the AVB test key they originally used. The AVB 2.0 public key file format physically can't store public keys with an exponent of 3.
I would suggest trying this to determine which AVB test key they used (assuming that they did):
Extract vbmeta.img
from the OTA
Copy the public key used to sign vbmeta.img
:
avbroot avb info -i vbmeta.img
(The field is AvbInfo -> header -> public_key)
Decode the public key from hex to binary:
echo '<public_key value>' | xxd -r -p > avb_pkmd.bin
Convert from the AVB 2.0 format to the standard PKCS8 format:
avbroot key decode-avb -k avb_pkmd.bin -o avb_public.key
Show the modulus value:
openssl rsa -pubin -in avb_public.key -noout -text
Download each of the AVB test keys (testkey_rsa{2048,4096,8192}.pem
) and see if the modulus in:
openssl rsa -in <test key> -noout -text
matches the public key you extracted.
Well I haven't tried using the result yet, but looking good!
avbroot ota patch --input usb_ota_update.zip --key-ota testkey.x509.key --key-avb testkey_rsa2048.key --cert-ota ota.cert --rootless --skip-recovery-ota-cert
←[2m 0.003s←[0m ←[33m WARN←[0m Not inserting OTA cert into recovery image; sideloading further updates may fail ←[2m 0.035s←[0m ←[32m INFO←[0m Replacing zip entry: META-INF/com/android/otacert ←[2m 0.036s←[0m ←[32m INFO←[0m Copying zip entry: care_map.txt ←[2m 0.036s←[0m ←[32m INFO←[0m Copying zip entry: checksoc.txt ←[2m 0.036s←[0m ←[32m INFO←[0m Copying zip entry: compatibility.zip ←[2m 0.037s←[0m ←[32m INFO←[0m Patching zip entry: payload.bin ←[2m 0.039s←[0m ←[32m INFO←[0m Extracting from original payload: system ←[2m 30.722s←[0m ←[32m INFO←[0m Extracting from original payload: boot ←[2m 31.199s←[0m ←[32m INFO←[0m Extracting from original payload: vbmeta ←[2m 31.202s←[0m ←[32m INFO←[0m Candidate boot images: boot ←[2m 31.208s←[0m ←[32m INFO←[0m Patching system image: system ←[2m 49.066s←[0m ←[32m INFO←[0m Patched otacerts.zip offsets in system: [1474662400..1474663473] ←[2m 49.066s←[0m ←[32m INFO←[0m Patching vbmeta images: vbmeta ←[2m 49.073s←[0m ←[32m INFO←[0m Compressing partial image: system: [1474662400..1474663473, 2641915904..2683782144, 2684354496..2684354560] ←[2m 56.079s←[0m ←[32m INFO←[0m Compressing full image: vbmeta ←[2m 56.081s←[0m ←[32m INFO←[0m Generating new OTA payload ←[2m 58.961s←[0m ←[32m INFO←[0m Patching zip entry: payload_properties.txt ←[2m 58.961s←[0m ←[32m INFO←[0m Generating new OTA metadata ←[2m 58.965s←[0m ←[32m INFO←[0m Verifying metadata offsets ←[2m 58.970s←[0m ←[32m INFO←[0m Successfully patched OTA
I'm not sure if I've made another mistake but the system doesn't like the update I generated.
I'm getting the error: Bad payload format -- invalid delta magic.
That was after generating an image like above, except I'd extracted system.img and modified it first.
avbroot ota patch --input usb_ota_update.zip --key-ota testkey.x509.key --key-avb testkey_rsa2048.key --cert-ota testkey.x509.cert --rootless --skip-recovery-ota-cert --replace system system.img
←[2m 0.000s←[0m ←[33m WARN←[0m Not inserting OTA cert into recovery image; sideloading further updates may fail ←[2m 0.004s←[0m ←[32m INFO←[0m Replacing zip entry: META-INF/com/android/otacert ←[2m 0.005s←[0m ←[32m INFO←[0m Copying zip entry: care_map.txt ←[2m 0.005s←[0m ←[32m INFO←[0m Copying zip entry: checksoc.txt ←[2m 0.005s←[0m ←[32m INFO←[0m Copying zip entry: compatibility.zip ←[2m 0.006s←[0m ←[32m INFO←[0m Patching zip entry: payload.bin ←[2m 0.007s←[0m ←[32m INFO←[0m Extracting from original payload: vbmeta ←[2m 0.011s←[0m ←[32m INFO←[0m Opening external image: system: "system.img" ←[2m 0.011s←[0m ←[32m INFO←[0m Extracting from original payload: boot ←[2m 0.331s←[0m ←[32m INFO←[0m Candidate boot images: boot ←[2m 0.337s←[0m ←[32m INFO←[0m Patching system image: system ←[2m 33.200s←[0m ←[32m INFO←[0m Patched otacerts.zip offsets in system: [1474662400..1474663473] ←[2m 33.200s←[0m ←[32m INFO←[0m Patching vbmeta images: vbmeta ←[2m 33.208s←[0m ←[32m INFO←[0m Compressing full image: vbmeta ←[2m 33.210s←[0m ←[32m INFO←[0m Compressing full image: system ←[2m121.090s←[0m ←[32m INFO←[0m Generating new OTA payload ←[2m125.008s←[0m ←[32m INFO←[0m Patching zip entry: payload_properties.txt ←[2m125.009s←[0m ←[32m INFO←[0m Generating new OTA metadata ←[2m125.015s←[0m ←[32m INFO←[0m Verifying metadata offsets ←[2m125.020s←[0m ←[32m INFO←[0m Successfully patched OTA
Nevermind, I just saw issue #328 which had the same problem. Added the --zip-mode seekable and the car accepted the update.
It processed the update but it looks like the AB update did it's job and booted the old one. Will have to dig into that a little more now.
Just to double check: when system.img
was edited, was it re-signed? (eg. doing avbroot avb unpack -i system.img
-> edit raw.img
-> avbroot avb pack -o system.img -k testkey_rsa2048.key
)
You can also verify with avbroot ota verify -i <name>.patched
.
I did the unpack / edit raw.img / repack but I didn't add the -k testkey_rsa2048.key Gave it a try now and it didn't make any difference.
avbroot ota verify doesn't work, it stops as soon as it hits the unknown boot image format.
Ah okay, if avbroot avb pack
didn't fail without -k testkey_rsa2048.key
, it means system.img
isn't signed (instead, its checksum is stored in vbmeta.img
, which is signed).
avbroot ota verify doesn't work, it stops as soon as it hits the unknown boot image format.
Crap, yeah, I'll need to add a flag to skip the otacerts check there.
I did a test with the new version: avbroot ota verify --skip-recovery-ota-cert --input usb_ota_update.zip ←[2m 0.000s←[0m ←[32m INFO←[0m Verifying whole-file signature ←[2m 2.012s←[0m ←[31mERROR←[0m Zip error
Caused by: specified file not found in archive
the file contains the same as usual:
META-INF folder care_map.txt checksoc.txt compatibility.zip payload.bin payload_properties.txt
If it helps, you can get a copy of the ota zip file on Google Drive: https://drive.google.com/file/d/1b8cZUbDz7s_AiolRdLy5s5GEpyAaRG4X/view
Hi, I'm doing some playing around with an OTA image for my cars infotainment unit. It's running Android 9.
avbroot had no problems extracting the boot image, but when I do a boot info command I get the error:
leon@cartman:~/Downloads/avbroot$ ./avbroot boot info -d --log-level trace --input boot.img 0.000s DEBUG cli=Cli { command: Boot(BootCli { command: Info(InfoCli { input: "boot.img" }), quiet: false, debug: true }), log_level: Level(Trace), log_format: Short } 0.000s ERROR Failed to read boot image: "boot.img"
Caused by: Unknown boot image format
I've verified it has extracted the boot image correctly.
My plan is to use the --rootless option since I mainly want to patch a file on the system partition.
The car manufacturer put some firewall commands in to block ADB port 5555 on all interfaces so at the moment we don't have ADB and I need to patch them out.
One thing we do know is that they signed everything with the test-keys so that part is not a concern.
A copy of the boot.img can be found here: https://www.dropbox.com/scl/fi/6edbvsk43gcv17j4kkh51/boot.img?rlkey=pbgktsrbnyidzm7jmh0j5tti3&st=nehlziw7&dl=0