Errors/Confusion with using Verified U-Boot

Hi Everyone, hopefully someone can help me because I’m pulling out my hair over here. I’m trying to get the Unleashed running with verified U-Boot and I’m having some success but I’m seeing some behaviors I can’t explain and it is driving me absolutely insane. Here’s what I’ve done:

I’ve changed my $(fit) target in the main freedom-u-sdk Makefile to insert signature data using mkfile (following these instructions here). So it went from this:

$(fit): $(bbl_bin) $(vmlinux_bin) $(uboot) $(initramfs) $(confdir)/uboot-fit-image.its
    $(uboot_wrkdir)/tools/mkimage -f $(confdir)/uboot-fit-image.its -A riscv -O linux -T flat_dt $@

to this:

$(fit): $(bbl_bin) $(vmlinux_bin) $(uboot) $(initramfs) $(confdir)/uboot-fit-image.its
$(uboot_wrkdir)/tools/mkimage -f $(confdir)/uboot-fit-image.its -k HiFive_U-Boot/keys -A riscv -O linux -T flat_dt $@
$(uboot_wrkdir)/tools/mkimage -A riscv -O linux -T flat_dt -F -k HiFive_U-Boot/keys -K /home/devadmin/freedom-u-sdk/HiFive_U-Boot/arch/riscv/dts/hifive_u540.dtb -r $@
cat work/HiFive_U-Boot/u-boot-nodtb.bin /home/devadmin/freedom-u-sdk/HiFive_U-Boot/arch/riscv/dts/hifive_u540.dtb > work/HiFive_U-Boot/u-boot.bin

Additionally, I edited conf/uboot-fitimage.its to include a signature on the kernel section:

kernel {
                    description = "Linux kernel";
                    data = /incbin/("../work/vmlinux.bin");
                    type = "kernel";
                    arch = "riscv";
                    os = "linux";
                    load = <0x80200000>;
                    compression = "none";
                    hash-1 {
                            algo = "sha256";
                    };
                    signature@1{
                            algo = "sha256,rsa2048";
                            key-name-hint = "dev_key";
                    };
            };

I also added some necessary flags to HiFive_U-Boot/configs/HiFive-U540_regression_defconfig:

CONFIG_FIT=y
CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_RSA=y
CONFIG_ENABLE_VBOOT=y

So these things seems to work fine. I can see the signature being appended and everything looks okay, but this is where I start getting confused. The U-Boot README says to replace the format-boot-loader target in the main Makefile with the following:

.PHONY: format-boot-loader
 format-boot-loader: $(bin)
    @test -b $(DISK) || (echo "$(DISK): is not a block device"; exit 1)
    sgdisk --clear                                                               \
           --new=1:2048:4095   --change-name=1:uboot      --typecode=1:$(FSBL)   \
           --new=2:4096:69631  --change-name=2:bootloader --typecode=2:$(BBL)   \
           --new=3:264192:     --change-name=3:root       --typecode=3:$(LINUX) \
       $(DISK)
 @sleep 1
 ifeq ($(DISK)p1,$(wildcard $(DISK)p1))
    @$(eval PART1 := $(DISK)p1)
    @$(eval PART2 := $(DISK)p2)
    @$(eval PART3 := $(DISK)p3)
 else ifeq ($(DISK)s1,$(wildcard $(DISK)s1))
    @$(eval PART1 := $(DISK)s1)
    @$(eval PART2 := $(DISK)s2)
    @$(eval PART3 := $(DISK)s3)
 else ifeq ($(DISK)1,$(wildcard $(DISK)1))
    @$(eval PART1 := $(DISK)1)
    @$(eval PART2 := $(DISK)2)
    @$(eval PART3 := $(DISK)3)
 else
    @echo Error: Could not find bootloader partition for $(DISK)
@exit 1

endif

dd if=/{Path_To}/freedom-u-sdk/work/u-boot.bin of=$(PART1) bs=4096

dd if=/{Path_To}/freedom-u-sdk/work/bbl.bin of=$(PART2) bs=4096

mke2fs -t ext3 $(PART3)

So when I build the target and then call “make format-boot-loader” it seems to load everything okay:

devadmin@xubuntu1604:~/freedom-u-sdk$ sudo make DISK=/dev/sdb format-boot-loader KBUILD_VERBOSE=1
sgdisk --clear \
	--new=1:2048:4095   --change-name=1:uboot      --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47   \
	--new=2:4096:69631  --change-name=2:bootloader --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985   \
	--new=3:264192:     --change-name=3:root       --typecode=3:0FC63DAF-8483-4772-8E79-3D69D8477DE4 \
		/dev/sdb
Setting name!
partNum is 0
REALLY setting name!
Setting name!
partNum is 1
REALLY setting name!
Setting name!
partNum is 2
REALLY setting name!
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
/sbin/partprobe
dd if=/home/devadmin/freedom-u-sdk/work/HiFive_U-Boot/u-boot.bin of=/dev/sdb1 bs=4096
120+1 records in
120+1 records out
493181 bytes (493 kB, 482 KiB) copied, 0.0294419 s, 16.8 MB/s
dd if=/home/devadmin/freedom-u-sdk/work/bbl.bin of=/dev/sdb2 bs=4096
18+1 records in
18+1 records out
74266 bytes (74 kB, 73 KiB) copied, 0.059587 s, 1.2 MB/s
mke2fs -t ext3 /dev/sdb3
mke2fs 1.42.13 (17-May-2015)
/dev/sdb3 contains a ext2 file system
	last mounted on Fri Apr  5 09:56:46 2019
Proceed anyway? (y,n) y

Filesystem too small for a journal
Discarding device blocks: done                            
Creating filesystem with 480 1k blocks and 64 inodes

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

My problem at this point is that when I boot from the SD card (skipping the boot process that is in there currently) the hash verification of the ramdisk fails:

U-Boot 2018.09-gca05d26-dirty (Apr 05 2019 - 11:36:09 -0400)

DRAM:  2 GiB
MMC:
In:    serial
Out:   serial
Err:   serial
Net:   gmac0
Hit any key to stop autoboot:  0
MMC_SPI: 0 at 0:1 hz 20000000 mode 0

Partition Map for MMC device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00000800      0x00000fff      "uboot"
        attrs:  0x0000000000000000
        type:   5b193300-fc78-40cd-8002-e86c45580b47
        guid:   054cd6e2-1e7f-47a2-a3db-66036d3bf1be
  2     0x00001000      0x00010fff      "bootloader"
        attrs:  0x0000000000000000
        type:   2e54b353-1271-4842-806f-e436d6af6985
        guid:   7e216960-57bb-483a-985c-503e91c3a41b
  3     0x00040800      0x00ecdfde      "root"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
        type:   linux
        guid:   f6fb1dd2-e3c4-4eeb-9e85-7448f87b0091
** Unrecognized filesystem type **
## Info: input data size = 787 = 0x313
running boot2...
## Error: "boot2" not defined
HiFive-Unleashed # iminfo

## Checking Image at a0000000 ...
   FIT description: U-boot FIT image for HiFive Unleashed
    Image 0 (bbl)
     Description:  BBL/SBI/riscv-pk
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0xa00000d4
     Data Size:    74266 Bytes = 72.5 KiB
     Architecture: RISC-V
     OS:           Linux
     Load Address: 0x80000000
     Entry Point:  0x80000000
     Hash algo:    sha256
     Hash value:   8a13913e602e33fc48b51c87a792f719fcdd939b6d3221823af7a245a2a
0b854
    Image 1 (kernel)
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0xa00123e8
     Data Size:    10781356 Bytes = 10.3 MiB
     Architecture: RISC-V
     OS:           Linux
     Load Address: 0x80200000
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   eee5427def0c852f6c3ea0ff9eeeda46255f92db0fc3f3bc3b3ea3037c9
3994f
     Sign algo:    sha256,rsa2048:dev_key
     Sign value:   308bf1c535bd50a3c473af2e2175202cbd5e473051790f1c51f611ad635
8cd99157c7c16591e0071882ee42b9cfe4f2b5eec73d747ebbdbf33ddb4650099fca6923ba7715
feb772982599de8eef3c57b8d8f25cbaff7ff62cc0bf986abf22a6c6d770e9dc07300a4561c4e5
08d0e6feaed5b39d800417fd2c6f0d7ca4f1021d20781465c6f1ddbce447d1a6dc440944c5c4f3
c1a7d9eda1ee654f7e066d4949000b3661c79c9bfead6656f0a17771f8b0f488e10b896897debd
8d755ee9991926a83ba8d00e9da38c3ae192063ac479687ecfb112d3dd4b04759e5a3bef20d3bb
90be8fc2b36ee31fc224b11ada9cd146f113194a4069d65c183824faba05f10
    Image 2 (ramdisk)
     Description:  buildroot initramfs
     Type:         RAMDisk Image
     Compression:  gzip compressed
     Data Start:   0xa0a5a918
     Data Size:    4467438 Bytes = 4.3 MiB
     Architecture: RISC-V
     OS:           Linux
     Load Address: 0x82000000
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   6a4e77f29bc9566b97f63b8bfe3e7e810969215b323daee7cc057e8f282
4869c
    Image 3 (fdt)
     Description:  unavailable
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0xa0e9d4d0
     Data Size:    15765 Bytes = 15.4 KiB
     Architecture: RISC-V
     Load Address: 0x81f00000
     Hash algo:    sha256
     Hash value:   90317bc02979b1681313c8df7f992801eeecc0600ae9e6d4e0f37ab5d1c
6bbbb
    Default Configuration: 'config-1'
    Configuration 0 (config-1)
     Description:  HiFive Unleashed with BBL
     Kernel:       bbl
     FDT:          fdt
     Loadables:    kernel
                   ramdisk
## Checking hash(es) for FIT Image at a0000000 ...
  value:
779e0d0460b8ee835dcd2585870f1ebf59110469b0eed9adf90d1dc42ed80f3f
fit_value:
6a4e77f29bc9566b97f63b8bfe3e7e810969215b323daee7cc057e8f2824869c error!
Bad hash value for 'hash-1' hash node in 'ramdisk' image node
Bad hash in FIT image!
HiFive-Unleashed #                                

So you’ll see above a couple things. First, the “** Unrecognized filesystem type **” which I believe is okay because the boot instructions are left over from the default file system structure?

Second, obviously the hash computed at boot time doesn’t match the hash value computed when the image was made. Even doing a hash of the initramfs.cpio.gz file that is loaded into this section on my local machine yields the one in the image:

devadmin@xubuntu1604:~/freedom-u-sdk$ sha256sum work/initramfs.cpio.gz
6a4e77f29bc9566b97f63b8bfe3e7e810969215b323daee7cc057e8f2824869c  work/initramfs.cpio.gz

So I have no idea why its being computed incorrectly later on. I’m thinking its probably not a coincidence that the first hash being computed after the section with the signature appended to it is the first one that fails?

Finally - continuing on with the UBoot instructions, I try and boot the kernel following this advice from the UBoot README:

### Boot Linux from SD card

Enter below commands on serial terminal

        # mmc_spi 1 20000000 0
        # mmc read 0x80000000 0x1000 0x10000
        # go 0x80000000

Which, um… kinda works?

HiFive-Unleashed # mmc_spi 1 20000000 0
MMC_SPI: 1 at 0:1 hz 20000000 mode 0
HiFive-Unleashed # mmc read 0x80000000 0x1000 0x10000

MMC read: dev # 0, block # 4096, count 65536 ... 65536 blocks read: OK
HiFive-Unleashed # go 0x80000000
## Starting application at 0x80000000 ...
bbl loader

                SIFIVE, INC.

         5555555555555555555555555
        5555                   5555
       5555                     5555
      5555                       5555
     5555       5555555555555555555555
    5555       555555555555555555555555
   5555                             5555
  5555                               5555
 5555                                 5555
5555555555555555555555555555          55555
 55555           555555555           55555
   55555           55555           55555
     55555           5           55555
       55555                   55555
         55555               55555
           55555           55555
             55555       55555
               55555   55555
                 555555555
                   55555
                     5

           SiFive RISC-V Core IP
TTThhhTihiisi sssi   si siib ssbblb  'lbbs' sbbd lludmu''mmssym_y  p_ddapyauul
ymmolaommdayy.d .__  ppT oTaa oyybo ollbooota doaa.td  r . eT aaol    bkToroeo
eta r la nboke oetrrl ne,ae l ar,rle ar elekc ckooeennrrfninfegeilu,rgl eu,r e
b rcbreoln
           efwbciigtobuhnlr et
                              f hwibeb gilfut
                                             lwahrig et h- t -bhtwhiebet l hf-

flpwlaagyai lgt-o-ah wd -i=Ptt-AhhwT-Hpie,at  ytlfhhol-eandpa =Pgraey Abl-Tuoi
aH-ld,wd=  iPbttAbhleTh.nH-  Arp,lea tbeutyrihlnladoet anibvb delr=P.A leTAybH
l,tu, ei
        trhnbleabdnt i lrvb eeblcbuyali,l
                                         .ndb   bblbAb ellc.at  neuA lbsrteene
 ruadnst aetdiii nvviene l lfyf,iiy
                                   rr,bmbw
                                          mlawbr ecbaral-en- o obncnel alyuny
sme  odmbd eieo n db yfeu i sardmebdwdyian  rgiae nd -defodviirincmnlew-argtye
 r emd-eoeo dnenvo lidbeycys e
                               afdm-odotri nrdageen  d eeeb xvtinyeco ren-adat
delr esdpe
          ia ynnflogoodaer d s daena
                                    v nfiecxodetr -etru rnsaeaelne    npoaQedy
ExelsotM
        aeUfd r'oansrnadl    a-upsabneyi  lQoeoEaxsMdUt  'eaasr nnn-addbli   o
p-usa yskaleenodar  d Q-nkeEaelMnr nodUep 'lt isuoo spntse-i. bo
                                                                n
                                                                 iQs oE.
                                                                          Ms
                                                                             U
  c ha' ons sce dhn- o s{-be
                            kin   oe{ sr
                                           n   ea    lnr  di s co  vpr-ikt,sei
kcrvneo,ernkle snro.enpetl
                          li-
                             -osn sts ta.r
                                          a t
                                             r   = ct  h < pc=oah syolse<oenpa
nd a _{y{s
          t
            la  or t a > d ;
                               _  rs    ti   s a rcr tvi >r;s,i
                                                               cks c evv r,, k
 kne eer n lrer-nli-sesecltnvd,a- rk=stt  ea=<rr t<np pea=a yyl<ll-poaaeoydnal
_osddat_ eanrd=dt_ >>;;<s

                         pt    aa  ry  } lt; o>

                                                aP ;ordwi_see
                                                             rnc dv>o, fk;fe
                                                                            r
   n                                                                       

So obviously something is wrong there, but is it related to the hashing problem? Please help!

The u-boot doc link points at a commercial site, which makes me think the entire message is spam, i.e. an SEO attempt, though an unusually verbose and convincing one.

I don’t know anything about boot loaders, but I can explain this part
TTThhhTihiisi sssi si siib ssbblb ‘lbbs’ sbbd lludmu’'mmssym_y p_ddapyauul
This is the message “This is the bbl dummy payload.” being printed by all four cores at the same time, which means all four cores are trying to run a bbl that doesn’t have a vmlinux payload. Also, the “bbl loader” message before the SiFive logo suggests that you aren’t running u-boot, but rather bbl directly, which is likely wrong.

The HiFive u-boot repo mentions flipping one of the switches on your board. Did you remember to do that? I think you might get this error if you forgot to flip the switch.

You will probably have more luck filing issues in github projects, like the sifive/HiFive_U-Boot project, than asking questions here.

I think the Verified Boot link in there is legit (although the link appears to be broken now) because the same guy had posted on stack overflow before following up later with that article he wrote.

That’s interesting about the 4 cores loading the bbl image. Part of the problem I’m having here is that I’m not super well versed in how boards this complex boot in general - I usually work with much smaller ones that couldn’t run a version of Linux in a million years. I think I’m right in guessing that the order is supposed to go U-Boot -> BBL -> Linux kernel? That’s what it appears the Makefile is trying to do in the format-boot-loader section - it’s creating three partitions, one each for the u-boot image, bbl and finally a ext3 partition I assume is supposed to be for the Linux kernel but as far as I can tell it never loads anything into that partition.

What is confusing to me is that the format-boot-loader section that the U-Boot documentation had me replace seems to make a lot more sense to me and I don’t understand why it says I have to replace it:

.PHONY: format-boot-loader
format-boot-loader: $(bbl_bin) $(uboot) $(fit) $(vfat_image)
	@test -b $(DISK) || (echo "$(DISK): is not a block device"; exit 1)
	/sbin/sgdisk --clear  \
		--new=1:$(VFAT_START):$(VFAT_END)  --change-name=1:"Vfat Boot"	--typecode=1:$(VFAT)   \
		--new=2:264192:$(DEMO_END) --change-name=2:root	--typecode=2:$(LINUX) \
		--new=3:$(UBOOT_START):$(UBOOT_END)   --change-name=3:uboot	--typecode=3:$(UBOOT) \
		--new=4:$(UENV_START):$(UENV_END)  --change-name=4:uboot-env	--typecode=4:$(UBOOTENV) \
		$(DISK)
	-/sbin/partprobe
	@sleep 1
ifeq ($(DISK)p1,$(wildcard $(DISK)p1))
	@$(eval PART1 := $(DISK)p1)
	@$(eval PART2 := $(DISK)p2)
	@$(eval PART3 := $(DISK)p3)
	@$(eval PART4 := $(DISK)p4)
else ifeq ($(DISK)s1,$(wildcard $(DISK)s1))
	@$(eval PART1 := $(DISK)s1)
	@$(eval PART2 := $(DISK)s2)
	@$(eval PART3 := $(DISK)s3)
	@$(eval PART4 := $(DISK)s4)
else ifeq ($(DISK)1,$(wildcard $(DISK)1))
	@$(eval PART1 := $(DISK)1)
	@$(eval PART2 := $(DISK)2)
	@$(eval PART3 := $(DISK)3)
	@$(eval PART4 := $(DISK)4)
else
	@echo Error: Could not find bootloader partition for $(DISK)
	@exit 1
endif
	dd if=/home/devadmin/freedom-u-sdk/work/HiFive_U-Boot/u-boot.bin of=$(PART3) bs=4096
	dd if=$(vfat_image) of=$(PART1) bs=4096 

That creates 4 partitions, but only loads in u-boot and the vfat_image, which is a .fit containing the bbl, the linux kernel, a ramdisk section (?) and an ftd section (?).

This is so confusing!

Regarding the flipping of the switches on the board - I did do that pretty early on in this process as nothing works at all until you do that.

Finally, the sifive HiFive_UBoot project is fork of a fork so I can’t create issues directly on it and the original repo is a ghosttown. I did see someone posted an issue asking for help with secure boot on the freedom-u-sdk github last week but never got any responses.

Sorry I’m all over the place here, just trying to sort out everything and I guess writing it out as I do it is helping me a bit.

@nbegley can paste a link to the freedom-u-sdk github issue, I probably missed it in all the other stuff I am trying to track. The HiFive-U-Boot repo is pretty much a dead end, as it has no history, and I’m working on porting it over to upstream U-boot (see https://github.com/tmagik/freedom-u-sdk/tree/dev/u-boot ) and the https://github.com/sifive/u-boot/tree/sandbox u-boot code.

You can also file issues on sifive/Hifive-u-boot now, although I am mostly going to respond with ‘try it on the new development u-boot code’

Sure, here you go https://github.com/sifive/freedom-u-sdk/issues/96

To be clear, that isn’t me but I would also be interested in seeing something that explored verified boot a little bit more in depth. There’s so many moving parts here between the its, dts, dtb, u-boot, bbl, uenv, ramdisk, etc that its hard for people new to this eco system to keep everything straight.

Okay, here’s a question that is a little more narrow and pointed than my previous scrawling ones: where is the board loading u-boot from when I use the original format-boot-loader? If I completely delete my u-boot.bin file and rebuild it and program it to my SD card using format-boot-loader, u-boot loads but with a timestamp from last week:

HiFive-Unleashed # version
U-Boot 2018.09-gca05d26-dirty (Apr 02 2019 - 14:10:52 -0400)

riscv64-buildroot-linux-gnu-gcc.br_real (Buildroot 2019.02-07449-g4eddd28) 8.3.0
GNU ld (GNU Binutils) 2.30
HiFive-Unleashed #  

I can even completely erase the SD card, comment out the line that programs the u-boot.bin file to the card and still boot u-boot with that exact same timestamp! Where is that u-boot image coming from and why does it seem to be completely ignoring the version programmed to the disk?

Its only when I use the format-boot-loader specified in the U-Boot README that it actually starts using the u-boot image i built. To me the two targets are remarkably similar:

	dd if=work/HiFive_U-Boot/u-boot.bin of=$(PART1) bs=4096

vs

	dd if=$(uboot) of=$(PART3) bs=4096

Where $(uboot) resolves to the exact same path

You may have found a bug in the makefile scripts.

The $(PART1) seems suspicious, since that’s the way it used to work until I added the uEnv.txt and made the U-boot partition the 3rd partition. Maybe you’ve got two partitions with the same GUID code, and it’s just booting the first one?

I don’t understand why ‘make DISK=/dev/sdd format-boot-loader’ wouldn’t have just overwritten the partition, unless it’s getting an error buried in the makefile output.

So, just to close this out in case someone else comes by at some point in the future and happens to have the same problem the problem I was seeing with the u-boot constantly reloading an old version: I’m not sure exactly how it happened, but I believe you were right tmagik about there being two u-boot GUID partitions on the SD card.

I found the only reliable way to avoid it happening was to completely format the card before programming. In my case I used the Ubuntu Disk utility. I wound up not using the format-boot-loader that is detailed in the U-Boot README file and instead just elected to use the default one so that I can boot the kernel directly from the SD card instead of having to load it through tftp.

I think I spoke a bit too soon! I’m still having one last issue that is unrelated to my original issues but still related to my general confusion of verified U-boot.

I’m successfully inserting signatures into my fit image but my problem now is that when I try and load my dtb file with my rsa2048 public key embedded into it onto the board, I can never seem to get the damn dtb on there that actually has the public key!

So here is what I’m doing. First, here is my Makefile lines again generating my fit image / inserting my public key into the DTB file / packaging up the dtb into the u-boot image (in that order):

$(uboot_wrkdir)/tools/mkimage -f $(confdir)/uboot-fit-image.its -k HiFive_U-Boot/keys -A riscv -O linux -T flat_dt $@
$(uboot_wrkdir)/tools/mkimage -A riscv -O linux -T flat_dt -F -k HiFive_U-Boot/keys -K /home/devadmin/freedom-u-sdk/work/HiFive_U-Boot/arch/riscv/dts/hifive_u540.dtb $@
cat work/HiFive_U-Boot/u-boot-nodtb.bin /home/devadmin/freedom-u-sdk/work/HiFive_U-Boot/arch/riscv/dts/hifive_u540.dtb &gt; work/u-boot.bin

I’ve verified through fdtdump on the dtb file that it is indeed embedding my public key information in there.

Now, I believe that uEnv.txt is looking within the fit image for the DTB file (aka FDT section) because we have the following lines in uEnv.txt:

# Use the FDT in the FIT image..
#setupfdt1=fdt addr ${fdtaddr}; fdt resize; fdt chosen; fdt move ${fdtaddr} ${newfdt}

#use FDT that came with uboot
#setupfdt1=fdt addr ${newfdt}; fdt resize; fdt chosen; fdt move ${fdtaddr} ${newfdt}

#Use fit image, but don't call fdt move  (TODO: understand later)
setupfdt1=fdt addr ${newfdt}; fdt resize; fdt chosen

Now, if i comment out the last setupfdt1 and use instead the 2nd one it can’t find the public key in the FDT

Loading loadables from FIT Image at a0000000 …

Trying ‘kernel’ loadables subimage
Description: Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0xa00123e8
Data Size: 10781356 Bytes = 10.3 MiB
Architecture: RISC-V
OS: Linux
Load Address: 0x80200000
Entry Point: unavailable
Hash algo: sha256
Hash value: eee5427def0c852f6c3ea0ff9eeeda46255f92db0fc3f3bc3b3ea3037c93994f
Sign algo: sha256,rsa2048:dev_key
Sign value: 308bf1c535bd50a3c473af2e2175202cbd5e473051790f1c51f611ad6358cd99157c7c16591e0071882ee42b9cfe4f2b5eec73
d747ebbdbf33ddb4650099fca6923ba7715feb772982599de8eef3c57b8d8f25cbaff7ff62cc0bf986abf22a6c6d770e9dc07300a4561c4e508d0e6fe
aed5b39d800417fd2c6f0d7ca4f1021d20781465c6f1ddbce447d1a6dc440944c5c4f3c1a7d9eda1ee654f7e066d4949000b3661c79c9bfead6656f0a
17771f8b0f488e10b896897debd8d755ee9991926a83ba8d00e9da38c3ae192063ac479687ecfb112d3dd4b04759e5a3bef20d3bb90be8fc2b36ee31f
c224b11ada9cd146f113194a4069d65c183824faba05f10
Verifying Hash Integrity … ****** fit_image_verify_required_sigs
****** No signature node found
sha256value:
eee5427def0c852f6c3ea0ff9eeeda46255f92db0fc3f3bc3b3ea3037c93994f
fit_value:
eee5427def0c852f6c3ea0ff9eeeda46255f92db0fc3f3bc3b3ea3037c93994f+ ********* fit image check sig!
********* Fit image setup verify!!!
sha256,rsa2048:dev_key
********* about to get hash
********* finished getting hash
********* About to call into verify okay?
Verifying signature starting with 0x30 0x8b
Looking for node signature
rsa_verify: No signature node found
****** FAILED VERIFICATION!

  • OK

Here is the printout of the commnd “fdt print” after I’ve called “fdt addr ${newaddr}” myself in the console:

HiFive-Unleashed # fdt print
/ {
#address-cells = <0x00000002>;
#size-cells = <0x00000002>;
compatible = “sifive,fu540g”, “sifive,fu500”;
model = “sifive,hifive-unleashed-a00”;
aliases {
serial0 = “/soc/serial@10010000”;
serial1 = “/soc/serial@10011000”;
};
firmware {
sifive,fsbl = “YYYY-MM-DD”;
}; .

So the signature node isn’t there!

It also doesn’t work when the FDT is supposedly being used from the fit image either, even though that file’s its file is pointing at the same DTB file i’m inserting the public key into.

Can anyone help? I just want to do verified boot with rsa!

Try uncommenting this one… notice the ${fdtaddr} and where it’s set elsewhere in the file… that needs to match the address you gave it in $(confdir)/uboot-fit-image.its.

# Use the FDT in the FIT image..
#setupfdt1=fdt addr ${fdtaddr}; fdt resize; fdt chosen; fdt move ${fdtaddr} ${newfdt}

This is going to be a bit of a mess until I get https://github.com/sifive/u-boot/tree/sandbox working and can start upstreaming the patches

No dice, still seems to be loading the DTB from somewhere else although I couldn’t tell you where. I did notice that in freedom-u-sdk/HiFive_U-Boot/board/SiFive/HiFive-U540/HiFive-U540.c there’s a line copying the FDT from somewhere to 0xF0000000:

gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);

printf("Copying FDT from %p to F000000 with size %d\n", (void*)gd->fdt_blob, gd->fdt_size);//000000000805c230

memcpy((void *)HIFIVE_FDT_BASE, gd->fdt_blob, gd->fdt_size);

HIFIVE_FDT_BASE is set to 0xF0000000 and the print of the fdt_blob pointer is 0x000000000805c240.

I’m also now getting some space errors right before the kernel starts booting - not sure if that’s related:

WARNING: could not set bootargs FDT_ERR_NOSPACE.
libfdt fdt_setprop(): FDT_ERR_NOSPACE
libfdt fdt_setprop(): FDT_ERR_NOSPACE
libfdt fdt_setprop(): FDT_ERR_NOSPACE
chosen {
riscv,kernel-start = <0x00000000 0x80200000>;
};
libfdt fdt_setprop(): FDT_ERR_NOSPACE
libfdt fdt_setprop(): FDT_ERR_NOSPACE
chosen {
riscv,kernel-start = <0x00000000 0x80200000>;
};
Loading Kernel Image … OK
Booting kernel in
2
1
0

Try running the set of commands in uEnv.txt manually and see which one triggers the ‘FDT_ERR_NOSPACE’

There might be a need for some extra ‘fdt resize’ options somewhere, it looks like it’s trying to set the riscv,kernel-end option and running out of space in the device tree.

Okay! Last post about this particular issue (I’m about to create a different thread about something else!).

I still don’t have a great understanding of everything but I figured i’ll post what I found and what I did.

Originally I was trying to use the FDT that was in image.fit but after I started looking into it it just seemed more work than I wanted. U-Boot by default seems to want to use the FDT embedded in its own image and it doesn’t seem worth fighting it on that. If one was interested in going down the path of excluding the FDT from U-Boot there are some config variables you can adjust to accomplish this. Here is the relevant part of the README:

  • Device tree:
    CONFIG_OF_CONTROL
    If this variable is defined, U-Boot will use a device tree
    to configure its devices, instead of relying on statically
    compiled #defines in the board file. This option is
    experimental and only available on a few boards. The device
    tree is available in the global data as gd->fdt_blob.

    U-Boot needs to get its device tree from somewhere. This can
    be done using one of the three options below:
    
    CONFIG_OF_EMBED
    If this variable is defined, U-Boot will embed a device tree
    binary in its image. This device tree file should be in the
    board directory and called <soc>-<board>.dts. The binary file
    is then picked up in board_init_f() and made available through
    the global data structure as gd->fdt_blob.
    
    CONFIG_OF_SEPARATE
    If this variable is defined, U-Boot will build a device tree
    binary. It will be called u-boot.dtb. Architecture-specific
    code will locate it at run-time. Generally this works by:
    
    	cat u-boot.bin u-boot.dtb >image.bin
    
    and in fact, U-Boot does this for you, creating a file called
    u-boot-dtb.bin which is useful in the common case. You can
    still use the individual files if you need something more
    exotic.
    
    CONFIG_OF_BOARD
    If this variable is defined, U-Boot will use the device tree
    provided by the board at runtime instead of embedding one with
    the image. Only boards defining board_fdt_blob_setup() support
    this option (see include/fdtdec.h file).
    

However, I didn’t go too far down this path as it seemed like U-Boot couldn’t “see” the fit image until after it had already been loaded and it had me fiddling with the boot order (see CONFIG_EXTRA_ENV_SETTINGS in HiFive-U540.h, CONFIG_BOOTCOMMAND in HiFive-U540_regression_defconfig, and uEnv.txt) and I just didn’t want to dive too much into that given how little I understand of the whole process.

Instead I decided to focus on understanding the boot process a little better and try and work out where exactly U-Boot was pulling the FDT from and why it didn’t contain my RSA key information. So I would start up the board, immediately cancel out of the boot process and enter the various commands manually (again, see the files listed in the last paragraph for the commands executed starting with CONFIG_BOOTCOMMAND which starts the whole process off). When I got to the step that was loading the FDT, I printed out ${fdtcontroladdr} which gave me an address that looked an awful lot like it was part of the U-Boot image.

Originally I thought that by inserting my keys into the DTB file and then concatenating that DTB with u-boot-nodtb.bin (see my original post) I was effectively doing what the Makefile does automatically for u-boot.bin but what I found (and can’t explain) is that no matter what I did it was acting as if u-boot-nodtb.bin already had the DTB file embedded in it. It was almost as if I was appending another copy of the DTB (the one containing my keys) to the end of the already existing DTB but U-Boot - having already been compiled at this point - had already been setup to look at the first DTB in the binary, completely ignoring the DTB containing the keys. That’s just a guess.

So how do we get the keys into the original DTB before it gets inserted into u-boot.bin? What I did was probably not the right way to do it and definitely not very graceful, but I inserted the following lines into the HiFive_U-Boot makefile in the already existing $(DTB) section:

$(DTB): $(dtb_depends)
ifeq ($(EXT_DTB),)
	$(Q)$(MAKE) $(build)=$(ARCH_PATH) $@
endif
    #Added the following two lines:
    	${PATH_TO_YOUR_freedom-u-sdk}/work/HiFive_U-Boot/tools/mkimage -f ${PATH_TO_YOUR_freedom-u-sdk}/conf/uboot-fit-image.its -k ${PATH_TO_YOUR_freedom-u-sdk}/HiFive_U-Boot/keys -A riscv -O linux -T flat_dt image.fit
    	${PATH_TO_YOUR_freedom-u-sdk}/work/HiFive_U-Boot/tools/mkimage -A riscv -O linux -T flat_dt -F -k ${PATH_TO_YOUR_freedom-u-sdk}/HiFive_U-Boot/keys -K $@ image.fit
    	$(Q)test -e $@ || (						\
    	echo >&2;							\
    	echo >&2 "Device Tree Source is not correctly specified.";	\
    	echo >&2 "Please define 'CONFIG_DEFAULT_DEVICE_TREE'";		\
    	echo >&2 "or build with 'DEVICE_TREE=<device_tree>' argument";	\
    	echo >&2;							\
    	/bin/false)

So this uses the mkimage tool to insert the keys into the DTB immediately after it is constructed so we’re guaranteed to get the correct version into our U-Boot binary.