I have recently authenticated my FIT image containing kernel + ramdisk + dtb sucessfully using HAB. Now I have the strange issue that the IVT offset of my image determinded by hab.c and my image signing script are not identical. I think that the IVT estimation using the raw_image_size of the image header fails for FIT images.
In the script, I determine the IVT offset as follows:
IMAGE_SIZE="0x`hexdump -C fitImage | tail -n 1`"
IVT_OFFSET="0x`printf '%08x\n' $(( ($IMAGE_SIZE + 0x1000 - 1) & ~(0x1000 - 1) ))`"
echo $IVT_OFFSET
After signing the FIT image, I determine the new image size again in using the same commands. Afterwards I print the hab_auth_img command like so:
echo "U-Boot shell command to authenticate the image: hab_auth_img $LOAD_ADDR 0x`hexdump -C $IMAGE_NAME | tail -n 1` $IVT_OFFSET"
and get
hab_auth_img 0x44000000 0x02c12f60 0x02c12000
which works to authenticate the image in U-Boot, but the patched bootm command doesnt't work for this case. So I printed the same data in the hab.c like so
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 0c3d8be002..231927b103 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -919,5 +919,8 @@ int authenticate_image(uint32_t ddr_start, uint32_t raw_image_size)
~(ALIGN_SIZE - 1);
bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
+ printf("\nraw_image_size = 0x%08x\n", raw_image_size);
+ printf("hab_auth_img 0x%08x 0x%08x 0x%08x\n", load_addr, bytes, ivt_offset );
+
return imx_hab_authenticate_image(ddr_start, bytes, ivt_offset);
}
and it prints
raw_image_size = 0x02c10c58
hab_auth_img 0x44000000 0x02c13020 0x02c11000
which fails. I realized though that when you adjust the IVT offset to
hab_auth_img 0x44000000 0x02c13020 0x02c12000
the authentication works.
I don't fully understand how the calculation for the IVT offset works and I am assuming that this has been thoroughly tested for all officially supported image types. So to me it is probably the FIT image that is the error. Could it be that the calculation of the raw_image_size does not take all parts of the FIT image into account?
已解决! 转到解答。
I think I found the issue. The patch that I used was using the function image_get_image_size(), which reads the image size from legacy image headers. I exchanged it with fit_get_size(), which did return the same value as the one I hexdumped in my script.
Here is the diff
diff --git a/cmd/bootm.c b/cmd/bootm.c
index bed84bd735..6fcd17eaf5 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -175,7 +175,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_FIT
case IMAGE_FORMAT_FIT:
if (authenticate_image(load_addr,
- image_get_image_size((image_header_t *)load_addr)) != 0) {
+ fit_get_size((void *)load_addr)) != 0) {
printf("Authenticate FIT image Fail, Please check\n");
return 1;
}
I think I found the issue. The patch that I used was using the function image_get_image_size(), which reads the image size from legacy image headers. I exchanged it with fit_get_size(), which did return the same value as the one I hexdumped in my script.
Here is the diff
diff --git a/cmd/bootm.c b/cmd/bootm.c
index bed84bd735..6fcd17eaf5 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -175,7 +175,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_FIT
case IMAGE_FORMAT_FIT:
if (authenticate_image(load_addr,
- image_get_image_size((image_header_t *)load_addr)) != 0) {
+ fit_get_size((void *)load_addr)) != 0) {
printf("Authenticate FIT image Fail, Please check\n");
return 1;
}
I am using an i.MX8 Mini. Why does this differ between boards?
Seems like there really is a difference in the header information of FIT images. Just compared the methods for the normal image and after the FIT generation
❯ echo "0x`hexdump -C Image | tail -n 1`"; echo "0x`od -t x4 -j 0x10 -N 0x4 --endian=little Image | head -n1 | awk '{print $2}'`"
0x01ec9a00
0x01f54000
❯ echo "0x`hexdump -C fitImage | tail -n 1`"; echo "0x`od -t x4 -j 0x10 -N 0x4 --endian=little fitImage | head -n1 | awk '{print $2}'`"
0x02c12f60
0x28000000
Although it is not off by that much in the case I have described yesterday.
I didn't understand the second command when I was writing my scripts, but from the description of a signing script from Boundarydevices it crops the image size from the header rather than using hexdump. I just used hexdump and padded to 4kB, which was easier to understand. Seems like the hab.c is reading the size from the header as well. So the method in my scripts should be the same. I would also rather alter my script than patch the U-Boot code again.