IVT offset calculation in hab.c fails for FIT images in some cases

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IVT offset calculation in hab.c fails for FIT images in some cases

Jump to solution
1,262 Views
jclsn
Contributor IV

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?

0 Kudos
1 Solution
1,222 Views
jclsn
Contributor IV

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;
                }

 

 

 

View solution in original post

0 Kudos
4 Replies
1,223 Views
jclsn
Contributor IV

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;
                }

 

 

 

0 Kudos
1,260 Views
jclsn
Contributor IV

@BiyongSUN  Any ideas?

0 Kudos
1,243 Views
BiyongSUN
NXP Employee
NXP Employee

I don't know which BSP you are using.

I know the difference is one using fit header information to decide the size. and another using file size(load size) to decide the file size.

0 Kudos
1,235 Views
jclsn
Contributor IV

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.

0 Kudos