I am struggling to get the kernel verification by HABv4 to work. I have read
and
https://boundarydevices.com/high-assurance-boot-hab-i-mx8m-edition/#kernel_auth
as well as
https://boundarydevices.com/high-assurance-boot-hab-dummies/#kernel_auth
which all pretty much do the same thing.
All the guides are done either with uncompressed or zImages. What I have is a uImage that was already generated with
mkimage -A arm64 -O linux -T kernel -C none -a 0x40480000 -e 0x40480000 -
n "Kernel" -d Image uImage
which has the same load address as shown in the guides, whereas the uncompresed image has
mkimage -l Image
GP Header: Size 4d5a0091 LoadAddr ff3f5a14
so I assume taking the uImage is correct. First I get the size of the image by doing a
hexdump -C uImage | tail -n 1
01ec9a40
the suggested
od -x -j 0x10 -N 0x4 --endian=little Image
0000020 00004840
0000024
does not give the the right image size.
Then I pad the image to: 4096 * (( 0x01ec9a40 / 4096) + 1 ) = 0x1eca000
objcopy -I binary -O binary --pad-to=0x1ECA000 --gap-fill=0x00 uImage uImage-pad.bin
I have added the calculated size from above to the load address of the image in the genIVT.pl
#! /usr/bin/perl -w
use strict;
open(my $out, '>:raw', 'ivt.bin') or die "Unable to open: $!";
print $out pack("V", 0x412000D1); # Signature
print $out pack("V", 0x40480000); # Load Address (*load_address)
print $out pack("V", 0x0); # Reserved
print $out pack("V", 0x0); # DCD pointer
print $out pack("V", 0x0); # Boot Data
print $out pack("V", 0x4234A000); # Self Pointer (*ivt)
print $out pack("V", 0x4234A020); # CSF Pointer (*csf)
print $out pack("V", 0x0); # Reserved
close($out);
and concatenate the generated ivt.bin to the padded image.
The I use the Code Signing Tool with the following csf.txt
[Header]
Version = 4.3
Hash Algorithm = sha256
Engine Configuration = 0
Certificate Format = X509
Signature Format = CMS
Engine = CAAM
[Install SRK]
# Index of the key location in the SRK table to be installed
File = "../crts/SRK_1_2_3_4_table.bin"
Source index = 0
[Install CSFK]
# Key used to authenticate the CSF data
File = "../crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem"
[Authenticate CSF]
[Unlock]
Engine = CAAM
Features = MID
[Install Key]
# Key slot index used to authenticate the key to be installed
Verification index = 0
# Target key slot in HAB key store where key will be installed
Target Index = 2
# Key to install
File = "../crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem"
[Authenticate Data]
# Key slot index used to authenticate the image data
Verification index = 2
# Authenticate Start Address, Offset, Length and file
Blocks = 0x40480000 0x00000000 0x1eca020 "uImage-pad-ivt.bin"
Everything seems to be correct to me. When I boot the image I do get a HAB event though.
Authenticate image from DDR location 0x40480000...
hab exit function fail
Secure boot enabled
HAB Configuration: 0xcc, HAB State: 0x99
--------- HAB Event 1 -----------------
event data:
0xdb 0x00 0x24 0x43 0x33 0x30 0xee 0x1d
0x00 0x08 0x00 0x02 0x00 0x00 0x00 0x00
0x55 0x55 0x00 0x02 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x02 0x06
STS = HAB_FAILURE (0x33)
RSN = HAB_ENG_FAIL (0x30)
CTX = HAB_CTX_EXIT (0xEE)
ENG = HAB_ENG_CAAM (0x1D)
Authenticate uImage Fail, Please check
Error loading the OS
I have no idea what this means. I had a look at the C code
int imx_hab_authenticate_image(uint32_t ddr_start,
uint32_t image_size,
uint32_t ivt_offset)
{
ulong load_addr = 0;
size_t bytes;
ulong ivt_addr = 0;
int result = 1;
ulong start;
struct ivt *ivt;
enum hab_status status;
if (!imx_hab_is_enabled())
puts("hab fuse not enabled\n");
printf("\nAuthenticate image from DDR location 0x%x...\n",
ddr_start);
hab_caam_clock_enable(1);
/* Calculate IVT address header */
ivt_addr = (ulong) (ddr_start + ivt_offset);
ivt = (struct ivt *)ivt_addr;
/* Verify IVT header bugging out on error */
if (!validate_ivt(ivt))
goto hab_authentication_exit;
start = ddr_start;
bytes = image_size;
/* Verify CSF */
if (!csf_is_valid(ivt, start, bytes))
goto hab_authentication_exit;
if (hab_rvt_entry() != HAB_SUCCESS) {
puts("hab entry function fail\n");
goto hab_exit_failure_print_status;
}
status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes);
if (status != HAB_SUCCESS) {
printf("HAB check target 0x%08x-0x%08lx fail\n",
ddr_start, ddr_start + (ulong)bytes);
goto hab_exit_failure_print_status;
}
#ifdef DEBUG
printf("\nivt_offset = 0x%x, ivt addr = 0x%lx\n", ivt_offset, ivt_addr);
printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
ivt->dcd, ivt->csf);
puts("Dumping IVT\n");
print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0);
puts("Dumping CSF Header\n");
print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0);
#if !defined(CONFIG_SPL_BUILD)
get_hab_status();
#endif
puts("\nCalling authenticate_image in ROM\n");
printf("\tivt_offset = 0x%x\n", ivt_offset);
printf("\tstart = 0x%08lx\n", start);
printf("\tbytes = 0x%x\n", bytes);
#endif
#ifndef CONFIG_ARM64
/*
* If the MMU is enabled, we have to notify the ROM
* code, or it won't flush the caches when needed.
* This is done, by setting the "pu_irom_mmu_enabled"
* word to 1. You can find its address by looking in
* the ROM map. This is critical for
* authenticate_image(). If MMU is enabled, without
* setting this bit, authentication will fail and may
* crash.
*/
/* Check MMU enabled */
if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
if (is_mx6dq()) {
/*
* This won't work on Rev 1.0.0 of
* i.MX6Q/D, since their ROM doesn't
* do cache flushes. don't think any
* exist, so we ignore them.
*/
if (!is_mx6dqp())
writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
} else if (is_mx6sdl()) {
writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
} else if (is_mx6sl()) {
writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
}
}
#endif
load_addr = (ulong) hab_rvt_authenticate_image( HAB_CID_UBOOT,
ivt_offset,
(void **)&start,
(size_t *)&bytes, NULL);
if (hab_rvt_exit() != HAB_SUCCESS) {
puts("hab exit function fail\n");
load_addr = 0;
}
hab_exit_failure_print_status:
#if !defined(CONFIG_SPL_BUILD)
get_hab_status();
#endif
hab_authentication_exit:
if (load_addr != 0 || !imx_hab_is_enabled())
result = 0;
return result;
}
which does not provide much info apart from that it is failing.
Do I have signed the data correctly? I mean, I am getting a HAB event at least. This is Android btw, could there be an issue with the CAAM and TEE?
已解决! 转到解答。
@Yuri : Sorry for letting of some steam the other day. I have already read all of the links you sent me. Meanwhile I could also fix it. The issue was that I wasn't using the size of the uImage-padded-ivt.bin in the csf_additional_images.txt
@Yuri : Sorry for letting of some steam the other day. I have already read all of the links you sent me. Meanwhile I could also fix it. The issue was that I wasn't using the size of the uImage-padded-ivt.bin in the csf_additional_images.txt
I just typed a reply and got errors when posting it. This has happened many times now. Other times it wants me to correct HTML errors, which are supposed to be highlighted, but they aren't. Please fix your forum!
@jclsn
Hello,
use "i.MX Android Security User’s Guide"
https://www.nxp.com/docs/en/user-guide/IMX_ANDROID_SECURITY_USERS_GUIDE.pdf
Regards,
Yuri.