How to authenticate kernel image from u-boot?

Hi all,
I need to sign kernel image with my own secured keys.generally lk bootloader authenticates the kernel.
But here in snappy u-boot loads kernel. so now my question is how to authenticate kernel from u-boot.
does u-boot provides mechanism for signing the kernel.if so,are there any reference documents to do so and android kernel have some mechanisms to sign through android build system but how does linux kernel gets signed?

Thanks
Laxman

it seems such a feature is available in u-boot since 2013.07, so you could theroetically modify uboot.env.in and the uboot.patch of your gadget to enable that feature and make use of it.
(and additionally modify your kernel snap to actually do the signing)

Details are described at:
https://lwn.net/Articles/571031/

Thanks ogra, after reading this i got bit idea of how to do it.

Regards,
Laxman

1 Like

@laxman456 if you are interested you can try my prototype.
It’s all very early stages, but it does check signature for all parts loaded by u-boot

Thanks ondra, will look in to this.

Regards,
Laxman

Hi ondra,
I tried building gadget snap by switching to verified boot branch.getting the below error

In file included from tools/aisimage.c:10:0:
include/image.h:1023:27: fatal error: openssl/evp.h: No such file or directory
compilation terminated.
scripts/Makefile.host:116: recipe for target ‘tools/aisimage.o’ failed
make[1]: *** [tools/aisimage.o] Error 1
make[1]: *** Waiting for unfinished jobs…
In file included from tools/atmelimage.c:11:0:
include/image.h:1023:27: fatal error: openssl/evp.h: No such file or directory
compilation terminated.
scripts/Makefile.host:116: recipe for target ‘tools/atmelimage.o’ failed
make[1]: *** [tools/atmelimage.o] Error 1
Makefile:1234: recipe for target ‘tools’ failed
make: *** [tools] Error 2
Command ‘[’/bin/sh’, ‘/tmp/tmpms4g3qw4’, ‘make’, ‘-j2’, ‘ARCH=arm’, ‘CROSS_COMPILE=arm-linux-gnueabihf-’]’ returned non-zero exit status 2

Regards,
Laxman

its the problem with my build environment. i resolved it.

Thanks

Hi ondra,
Built gadget snap with verified boot returning “Wrong Image Format for bootm command”.

U-Boot 2017.05-00008-g9ed00e4 (Oct 03 2017 - 14:21:25 +0530)
Qualcomm-DragonBoard 410C

DRAM: 986 MiB
MMC: sdhci@07824000: 0, sdhci@07864000: 1
reading uboot.env
In: serial@78b0000
Out: serial@78b0000
Err: serial@78b0000
Hit any key to stop autoboot: 0
ENVCMD
Saving Environment to FAT…
writing uboot.env
FAT: Misaligned buffer address (00000000bd109430)
done
reading dragonboard-kernel_x1.snap/kernel.img
22495232 bytes read in 2518 ms (8.5 MiB/s)
Wrong Image Format for bootm command
ERROR: can’t get kernel image!
dragonboard410c =>

i fear currently only the booti (for uncompressed kernels (the default)) or bootz (for compressed ones) commands are supported with arm64 kernels, we do currently not modify the vmlinuz binary to turn it into a uImage …

Hi ogra,
when i try with booti getting the below error

ENVCMD
reading my-kernel_x1.snap/kernel.img
22495232 bytes read in 2515 ms (8.5 MiB/s)
FDT and ATAGS support not compiled in - hanging

ERROR ### Please RESET the board#

when i try with bootz

ENVCMD
reading my-kernel_x1.snap/kernel.img
22495232 bytes read in 2516 ms (8.5 MiB/s)
Unknown command ‘bootz’ - try ‘help’
dragonboard410c =>

you would have to enable bootz in the u-boot config, but i fear there is more needed to overcome the FDT/ATAGS error …

to enable atags the config option is

#define CONFIG_SETUP_ANY_TAG

but i wouldnt know the address to use for it (perhaps the lk source has some hints where it puts them)

Hi ogra,
with bootz its throwing error as Bad Linux ARM zImage magic!.How to resolve this?

reading my-kernel_x1.snap/kernel.img
22495232 bytes read in 2515 ms (8.5 MiB/s)
Bad Linux ARM zImage magic!

what exactly does the file command tell you about this file ?

Hi,
kernel.img: MS-DOS executable, MZ for MS-DOS

the above problem is observed when i switched to verified boot branch in u-boot.

board is booting normally with master branch of u-boot.

there is a difference in uboot.env.in of both branches.

in verified boot branch uboot.env.in has–>snappy_boot=…run mmcargs; bootm ${linux_itb_addr}#config@1

and in master branch uboot.env.in has–>…run mmcargs; booti ${linux_addr}#config@1

is this the problem with uboot.env.in?

well, booti means “boot raw image” (which your file above seems to be), while bootz means “boot compressed image” (plain vmlinuz file and used everywhere else in our setup) and bootm means “boot application image from memory” which means you need to create a uImage file fom the kernel binary by using mkimage from the u-boot tree.

u-boot checks the file magic before calling the boot{i,m,z} command and will refuse to execute something that does not fit the specific boot command.

If bootm is a requirement for authenticated boot you need to change your kernel snap build to actually produce a uImage file as kernel.img…

well, Thanks for the info.

is adding the below part correct in kernel snapcraft.yaml?

install:
mkimage -A arm -O linux -T kernel -C none -a 0x81000000 -e 0x83000000 -n “Linux kernel” -d parts/kernel/build/arch/arm64/boot/Image parts/kernel/build/arch/arm64/boot/uImage

if so will above change reflect in parts/kernel/install/kernel.img?

or can you kindly provide details of how to do it?

you need something like a mv uImage kernel.img after generating the file so the snap will use it … but yeah, something like this would be required, though i am not 100% sure if the dragonboard u-boot even supports booting uImages, it might need more patching …

(alternatively re-working the patch to apply to booti instead of bootm might be another option)

ya with booti FDT and ATAGS error is coming.so as you said i tried to enable atags.

Makefile has —>obj-$(CONFIG_CMD_BOOTI) += bootm.o

so i modified arch/arm/lib/bootm.c as

DECLARE_GLOBAL_DATA_PTR;
+#define CONFIG_SETUP_ANY_TAG

+#ifdef CONFIG_SETUP_ANY_TAG
static struct tag *params;
+#endif

static ulong get_sp(void)
{
@@ -103,6 +107,7 @@ static void announce_and_cleanup(int fake)
cleanup_before_linux();
}

+#ifdef CONFIG_SETUP_ANY_TAG
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *)bd->bi_boot_params;
@@ -204,6 +209,8 @@ static void setup_end_tag(bd_t *bd)

__weak void setup_board_tags(struct tag **in_params) {}

+#endif

but i got the same error.
is this correct?

you mean the “bad magic one” ?
the use of an uImage should sohave solved that (but again i dont know if the dragonboard is even capable of using this, that would be a question for 96boards)

Hi @laxman456
sorry for late response.
If you want to use verified boot option, you also need to tweak kernel snap so it used fit image. What you are seeing here is bootm expecting fit image and you feeding it with just kernel image……
So I guess part which you are missing is rebuilding kernel snap. If you have used my verified boot branch, this will force u-boot to accept only signed fit images, as security measure.
So if you will pair this with default dragboard kernel snap it will fail badly.
You can use my reference kernel snap from here https://code.launchpad.net/~ondrak/ondras-snaps/+git/linux-kernel/+ref/snapdragon
Or just pull snap from https://code.launchpad.net/~ondrak/+snap/snapdragon-kernel-src and sign image inside. If you use unsigned one, you should see u-boot complaining about wrong signature……

Remember for both gadget and kernel snap. If you build those on LP it will not have your keys
So either you repack/sign gadget once it’s build, or you build them locally where you have your keys.
Process is a bit cumbersome for adding secret to u-boot, as you need to actually sign fit image, though its fine to signed fit image which will include fake image files inside. You can see I’m doing this un gadget snapcraft.yaml
Let me know if this make sense, I hope to have some time in next few days to assist you if this does not work for you

1 Like