u-boot with signed FIT images


Greg Malysa
 

Hi all,

I'm working on a system using HAB to verify u-boot and then using a public key included in u-boot's device tree to verify a FIT image before booting, on an imx device. Internally we've developed classes and recipes for completing this process, so now we're looking to push out support to poky or at least fsl/fslc metalayers and wanted to align on the right way to do things before trying to submit patches.

Currently, as I understand it, the uboot-sign class expects a u-boot.dtb to be created, which can then have the public key added by mkimage when it signs the ready FIT image, late in the build process. However, for imx devices, the u-boot target is "u-boot.imx" which already builds the dtb and combines it with the u-boot binary and then assembles an imx image with a make target that ships with u-boot. Thus, there is no u-boot.dtb to store the public key in, and there are no yocoto build tasks for rebuilding the imx image.

Our strategy has been to do this instead:
- Explicitly build the configuration-specific DTB first
- Create a simplified FIT image with a minimal amount of information in it
- Sign this simplified image, storing the public key data in the correct DTB
- Proceed with making the u-boot.imx target, which will then use the DTB with the public key already integrated and also support other follow up processing (such as generating a CSF and signing u-boot.imx for HAB)
- When building the kernel FIT image, sign it with the matching private key, but don't write the public key to any DTBs

One important advantage to me is that this is fully handled by yocto; previous iterations required us to manually create the DTB we intended to use before building anything with yocto, add it to the recipe as an extra file to throw into the build directory, and then prevent u-boot from re-creating it because the public key information would be lost.

A rough diff of the u-boot.inc changes only is included below. This would also need to do things like check if signing is actually requested, however UBOOT_SIGN_ENABLE is already used by uboot-sign.bbclass and will produce incorrect warnings if it is set without additional modifications to the class. uboot-sign, depending entirely on u-boot.dtb, does not do anything in this situation.

So my questions are:

- Does this seem like a sensible approach? Combined with a class based on kernel-fitimage that also does not use u-boot.dtb, this produces the expected result.
- Should this be done in poky or in a freescale layer where it's more appropriate to have imx-specific changes? I don't want to rewrite or patch the basic u-boot build steps in a higher level when they could be made flexible enough at a lower level.
- What other things should be considered?

Additional HAB stuff will be introduced after we sort out signing FIT images.

Thanks,
Greg

diff --git a/u-boot.inc.fragment b/u-boot.inc.fragment
--- a/u-boot.inc.fragment
+++ b/u-boot.inc.fragment
@@ -1,3 +1,44 @@
+sits_emit() {
+    cat << EOF > ${WORKDIR}/simple.its
+/dts-v1/;
+
+/ {
+    description = "U-Boot Simple fitImage";
+    #address-cells = <1>;
+    images {
+        dummy@1 {
+            description = "dummy";
+            data = [00];
+            type = "kernel";
+            arch = "arm";
+            os = "linux";
+            compression = "none";
+            load = <0x80008000>;
+            entry = <0x80008000>;
+            hash@1 {
+                algo = "sha1";
+            };
+        };
+    };
+    configurations {
+        default = "conf@1";
+        conf@1 {
+            description = "dummy";
+            dummy = "dummy@1";
+            hash@1 {
+                    algo = "sha1";
+            };
+            signature@1 {
+                algo = "sha1,rsa2048";
+                key-name-hint = "${UBOOT_SIGN_KEYNAME}";
+                sign-images = "dummy";
+            };
+        };
+    };
+};
+EOF
+}
+
 do_compile () {
     if [ "${@bb.utils.filter('DISTRO_FEATURES', 'ld-is-gold', d)}" ]; then
         sed -i 's/$(CROSS_COMPILE)ld$/$(CROSS_COMPILE)ld.bfd/g' ${S}/config.mk
@@ -23,6 +64,19 @@ do_compile () {
                 if [ $j -eq $i ]
                 then
                     oe_runmake -C ${S} O=${B}/${config} ${config}
+                    oe_runmake -C ${S} O=${B}/${config} dtbs
+
+                    sits_emit
+                    uboot-mkimage -D "${UBOOT_MKIMAGE_DTCOPTS}" \
+                        -f ${WORKDIR}/simple.its ${B}/simpleFitImage
+                    uboot-mkimage -D "${UBOOT_MKIMAGE_DTCOPTS}" \
+                        -F -k ${UBOOT_SIGN_KEYDIR} \
+                        -K ${B}/${config}/dts/dt.dtb \
+                        -r ${B}/simpleFitImage
+
+                    rm ${WORKDIR}/simple.its
+                    rm ${B}/simpleFitImage
+
                     oe_runmake -C ${S} O=${B}/${config} ${UBOOT_MAKE_TARGET}
                     for binary in ${UBOOT_BINARIES}; do
                         k=$(expr $k + 1);

--
Greg Malysa
Timesys Corporation


Otavio Salvador
 

Hello Greg,

(adding Tom Rini on Cc)

On Tue, Dec 17, 2019 at 9:54 PM Greg Malysa <greg.malysa@timesys.com> wrote:
I'm working on a system using HAB to verify u-boot and then using a public key included in u-boot's device tree to verify a FIT image before booting, on an imx device. Internally we've developed classes and recipes for completing this process, so now we're looking to push out support to poky or at least fsl/fslc metalayers and wanted to align on the right way to do things before trying to submit patches.
Awesome.

Currently, as I understand it, the uboot-sign class expects a u-boot.dtb to be created, which can then have the public key added by mkimage when it signs the ready FIT image, late in the build process. However, for imx devices, the u-boot target is "u-boot.imx" which already builds the dtb and combines it with the u-boot binary and then assembles an imx image with a make target that ships with u-boot. Thus, there is no u-boot.dtb to store the public key in, and there are no yocoto build tasks for rebuilding the imx image.
It depends. When using an U-Boot with SPL this is split as well.

...
So my questions are:

- Does this seem like a sensible approach? Combined with a class based on kernel-fitimage that also does not use u-boot.dtb, this produces the expected result.
- Should this be done in poky or in a freescale layer where it's more appropriate to have imx-specific changes? I don't want to rewrite or patch the basic u-boot build steps in a higher level when they could be made flexible enough at a lower level.
- What other things should be considered?
It'd be good to ensure we support U-Boot with and without SPL so we
are generic to both use cases.

I think we should first make a working prototype and then see how to
better upstream this. Did you try SPL as well?

--
Otavio Salvador O.S. Systems
http://www.ossystems.com.br http://code.ossystems.com.br
Mobile: +55 (53) 9 9981-7854 Mobile: +1 (347) 903-9750


Greg Malysa
 

Hi Otavio,

> It'd be good to ensure we support U-Boot with and without SPL so we
> are generic to both use cases.

> I think we should first make a working prototype and then see how to
> better upstream this. Did you try SPL as well?

I have not tried SPL yet, but I've made arrangements today to get a board plus BSP that already uses SPL with kernel signing from another project here so that I don't have to bring it up first, and I will review the implementation. I'll post a rough prototype as soon as I have something that works for both.

What's the best way to share this prototype? I could just fork poky to make changes in and then put together a small manifest + metalayer on top with machine/image definitions and config to illustrate how to use it?  I've got some imx6 and imx7 hardware to test the results with as well.

Thanks,
Greg


Otavio Salvador
 

On Wed, Dec 18, 2019 at 9:43 PM Greg Malysa <greg.malysa@timesys.com> wrote:
...
What's the best way to share this prototype? I could just fork poky to make changes in and then put together a small manifest + metalayer on top with machine/image definitions and config to illustrate how to use it? I've got some imx6 and imx7 hardware to test the results with as well.
A fork would work.

--
Otavio Salvador O.S. Systems
http://www.ossystems.com.br http://code.ossystems.com.br
Mobile: +55 (53) 9 9981-7854 Mobile: +1 (347) 903-9750