Bug 15649

Summary: uboot-sign does not produce U-Boot binary with public key
Product: [Build System, Metadata & Runtime] OE-Core Reporter: Clayton Casciato <ccasciato>
Component: configurationAssignee: Unassigned <unassigned>
Status: IN PROGRESS REVIEW --- QA Contact:
Severity: normal    
Priority: Medium CC: denis, kexin.hao, randy.macleod
Version: unspecified   
Target Milestone: Future   
Hardware: BeagleBone   
OS: Multiple   
Whiteboard: NIR 01/10
OS type for building Yocto: --- Type of Regression: ---
Verified: Documentation change: No (bug/feature does not impact docs)

Description Clayton Casciato 2024-11-15 22:21:38 UTC
Reproducible in the master branch (and Scarthgap)

poky/build/conf$ diff local.conf{.sample,}
33c33
< #MACHINE ?= "beaglebone-yocto"
---
> MACHINE ?= "beaglebone-yocto"
39c39
< MACHINE ??= "qemux86-64"
---
> #MACHINE ??= "qemux86-64"
289a290,300
> 
> UBOOT_SIGN_ENABLE = "1"
> UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
> 
> FIT_GENERATE_KEYS = "1"
> UBOOT_SIGN_KEYDIR = "${TOPDIR}"
> UBOOT_SIGN_KEYNAME = "dev"
> 
> KERNEL_IMAGETYPES += " fitImage "
> 
> KERNEL_CLASSES += "kernel-fitimage"

As expected, the public key is in a DTB:

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot-beaglebone-yocto.dtb | tr -d '\n' | grep -o 'key-dev'
key-dev

Unexpectedly, the public key is not in the U-Boot binary:

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot.img | tr -d '\n' | grep -o 'key-dev'

I have a local workaround by bypassing the first logic branch starting with:
if [ "x${UBOOT_SUFFIX}" = "ximg" -o "x${UBOOT_SUFFIX}" = "xrom" ]

In other words, the simple concatenation binary + signed DTB concatenation in this logic branch works as expected:
elif [ -e "${UBOOT_NODTB_BINARY}" -a -e "${UBOOT_DTB_BINARY}" ]; then

Post-patch results:

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot-beaglebone-yocto.dtb | tr -d '\n' | grep -o 'key-dev'
key-dev

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot.img | tr -d '\n' | grep -o 'key-dev'
key-dev
Comment 1 Randy MacLeod 2024-11-21 16:44:30 UTC
Clayton, Can you send a patch to openembedded-core@lists.openembedded.org ?

See: 
   https://docs.yoctoproject.org/dev/contributor-guide/submit-changes.html
Comment 2 Clayton Casciato 2024-11-22 15:07:48 UTC
Hi, Randy!

I've submitted a patch and CC'd a few folks.

https://lists.openembedded.org/g/openembedded-core/message/207623
Comment 4 Denys Dmytriyenko 2024-12-06 22:28:14 UTC
This may fix beaglebone-yocto case, but the change now breaks most of TI platforms in meta-ti that use uboot-sign, rendering them unbootable. Still investigating the actual root-cause...
Comment 6 Randy MacLeod 2024-12-12 16:14:20 UTC
Clayton, 

Will you be able to work with people to revise your patch to avoid the problmes identified?

Thanks,
-- Randy / YP Bug review
Comment 7 Clayton Casciato 2025-01-20 18:47:09 UTC
There have been some significant updates such as the U-Boot upgrade to 2025.01
https://git.openembedded.org/openembedded-core/commit/meta/recipes-bsp/u-boot/u-boot_2025.01.bb?id=e16a24f04b56ca3fec6509a3286e2e3bb5c21c1e

This includes a potentially-relevant change: "Makefile: pass external DTB provided by make variable EXT_DTB to binman"
https://github.com/u-boot/u-boot/commit/f27e83062956c3b09d2ee3ea3b3c815f9d57e42d

Here is U-Boot's "Verified Boot on the Beaglebone Black": https://github.com/u-boot/u-boot/blob/v2025.01/doc/usage/fit/beaglebone_vboot.rst

I'm still seeing the same results:

poky$ git log -1 --oneline
15d005ccbf (HEAD -> master, origin/master, origin/HEAD) test-manual/reproducible-builds: fix reproducible links

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot-beaglebone-yocto.dtb | tr -d '\n' | grep -o 'key-dev'

poky/build/tmp/deploy/images/beaglebone-yocto$ hexdump -e "16 \"%_p\" \"\\n\"" u-boot.img | tr -d '\n' | grep -o 'key-dev'

--

Debugging:

poky$ git diff
diff --git a/meta/classes-recipe/uboot-sign.bbclass b/meta/classes-recipe/uboot-sign.bbclass
index a17be745ce..7feefe52c3 100644
--- a/meta/classes-recipe/uboot-sign.bbclass
+++ b/meta/classes-recipe/uboot-sign.bbclass
@@ -101,6 +101,7 @@ python() {
 }
 
 concat_dtb() {
+       set -x
        type="$1"
        binary="$2"
 
@@ -139,6 +140,7 @@ concat_dtb() {
                        bbwarn "Failure while adding public key to u-boot binary. Verified boot won't be available."
                fi
        fi
+       set +x
 }
 
 deploy_dtb() {

--

Select snippets from work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/temp/log.do_uboot_assemble_fitimage:

DEBUG: Executing shell function do_uboot_assemble_fitimage
+ type=
+ binary=u-boot.img
+ [ -e u-boot.dtb ]
+ uboot-mkimage -D -I dts -O dtb -p 2000 -F -k [SNIP]/poky/build -K u-boot.dtb -r [SNIP]/poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/build/fitImage-linux
Failed to add verification data for 'signature-1' signature node in 'conf-am335x-bone.dtb' configuration node
[...]
Signature written to '[SNIP]/poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/build/fitImage-linux', node '/configurations/conf-am335x-bonegreen.dtb/signature-1'
Public key written to 'u-boot.dtb', node '/signature/key-dev'
+ uboot-fit_check_sign -k u-boot.dtb -f [SNIP]/poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/build/fitImage-linux
Signature check OK
Verifying Hash Integrity for node 'conf-am335x-bone.dtb'... sha256,rsa2048:dev+
[...]
Could not find subimage node type 'ramdisk'
+ cp u-boot.dtb u-boot.dtb-signed
[...]
+ [ 0 != 1 ]
+ [ ximg = ximg -o ximg = xrom ]
+ [ -e u-boot.dtb ]
+ oe_runmake EXT_DTB=u-boot.dtb-signed all
+ oe_runmake_call EXT_DTB=u-boot.dtb-signed all
[...]
  cat u-boot.dtb-signed > dts/dt.dtb
  ./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x80800000 -e 0x80800000 -p 0x0 -n "U-Boot 2025.01 for am335x board" -E  -b arch/arm/dts/am335x-evm.dtb -b arch/arm/dts/am335x-bone.dtb -b arch/arm/dts/am335x-sancloud-bbe.dtb -b arch/arm/dts/am335x-sancloud-bbe-lite.dtb -b arch/arm/dts/am335x-sancloud-bbe-extended-wifi.dtb -b arch/arm/dts/am335x-boneblack.dtb -b arch/arm/dts/am335x-evmsk.dtb -b arch/arm/dts/am335x-bonegreen.dtb -b arch/arm/dts/am335x-icev2.dtb -b arch/arm/dts/am335x-pocketbeagle.dtb  -d u-boot-nodtb.bin u-boot.img >/dev/null  && cat /dev/null
  cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin
  cp u-boot-dtb.bin u-boot.bin
[...]
  cp dts/dt.dtb u-boot.dtb
  ./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x80800000 -e 0x80800000 -p 0x0 -n "U-Boot 2025.01 for am335x board" -E  -b arch/arm/dts/am335x-evm.dtb -b arch/arm/dts/am335x-bone.dtb -b arch/arm/dts/am335x-sancloud-bbe.dtb -b arch/arm/dts/am335x-sancloud-bbe-lite.dtb -b arch/arm/dts/am335x-sancloud-bbe-extended-wifi.dtb -b arch/arm/dts/am335x-boneblack.dtb -b arch/arm/dts/am335x-evmsk.dtb -b arch/arm/dts/am335x-bonegreen.dtb -b arch/arm/dts/am335x-icev2.dtb -b arch/arm/dts/am335x-pocketbeagle.dtb  -d u-boot-nodtb.bin u-boot-dtb.img >/dev/null  && cat /dev/null
  [SNIP]/poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/git/scripts/check-of.sh .config [SNIP]/poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/git/scripts/of_allowlist.txt
+ [ -n u-boot.img ]
+ cp u-boot.img u-boot-.img
+ set +x
DEBUG: Shell function do_uboot_assemble_fitimage finished

Interesting findings:
1. "Failed to add verification data for 'signature-1' signature node in 'conf-am335x-bone.dtb' configuration node"
2. The type is passed as "", which causes this line: "+ cp u-boot.img u-boot-.img"
3. This looks promising:
cat u-boot.dtb-signed > dts/dt.dtb
cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin
cp dts/dt.dtb u-boot.dtb

From poky/build/tmp/work/beaglebone_yocto-poky-linux-gnueabi/u-boot/2025.01/build:
How many top-level results?
$ find . -maxdepth 1 -type f | xargs hexdump -e "16 \"%_p\" \"\\n\"" | tr -d '\n' | grep -o 'key-dev' | uniq -c
      4 key-dev

Which ones?
$ hexdump -e "16 \"%_p\" \"\\n\"" {u-boot.dtb,u-boot.dtb-signed,u-boot-dtb.bin,u-boot.bin} | tr -d '\n' | grep -o 'key-dev' | uniq -c
      4 key-dev