I want to leave few comments regarding this promising HAB/AHAB signing layer.
I managed to sign IMX7 u-boot-nand from Yocto with some mods. Issues I found:
- u-boot-nand padding at the end. Old u-boot .bb had padding tasks for NAND variants, log here suggests padding different way. And… signing layer of course doesn’t take it into account.
First of all why padding is required. ROM depending on fuses settings tries to boot different boot image instances. When ECC fatally fails, ROM tries to boot next boot image copy at different address and so on. If you write to NAND less data than specified in image BOOTDATA struct, ECC will fail and ROM will try the next image copy. When HAB is enabled, it increases image size in BOOTDATA by CONFIG_CSF_SIZE, which defaults at 0x2060, expecting signing process will add those 0x2060 bytes at the end. Usually it is smaller. So you either need to fix CONFIG_CSF_SIZE or pad at the end.
This breaks signing layer, because it cat’s signature at the end. So, we need to either unpad image, sign it, and pad again. Or dd into resulting image at CSF offset with conv=notrunc. Both could be fine with EMMC and NAND.
- Another issue is u-boot-hab.inc calls create_csf.sh with IMXBOOT=${UBOOT_BINARY}
u-boot-nand.imx is padded at start to 1k. So either csf whould should “checksum” at offset 1k or instead “checksum” u-boot.imx, which is the same unpadded. In both cases, EMMC and NAND for create_csf.sh could be the same u-boot.${UBOOT_SUFFIX}
This variant of u-boot-hab.inc sign_hab4() helps producing signed and bootable u-boot-nand.imx
sign_habv4() {
if [ ! -e "${TDX_IMX_HAB_CST_BIN}" ]; then
bberror "Could not find CST binary at ${TDX_IMX_HAB_CST_BIN}."
exit 1
fi
for f in "${TDX_IMX_HAB_CST_SRK}" "${TDX_IMX_HAB_CST_CSF_CERT}" \
"${TDX_IMX_HAB_CST_IMG_CERT}" "${TDX_IMX_HAB_CST_SRK_FUSE}"
do
if [ ! -e "${f}" ]; then
bberror "Could not find cert file at ${f}."
exit 1
fi
done
local soc="$1"
if [ -n "${UBOOT_CONFIG}" ]; then
i=0
j=0
for config in ${UBOOT_MACHINE}; do
i=$(expr $i + 1);
for type in ${UBOOT_CONFIG}; do
j=$(expr $j + 1);
if [ $j -eq $i ]; then
# TODO: finish this when working on machines with an SPL
bbnote "Machines with UBOOT_CONFIG set, are not implemented yet."
fi
done
done
else
if echo "${UBOOT_BINARY}" | grep -q "nand" ; then
# Generate CSF alwas refer u-boot-dtb.${UBOOT_SUFFIX} for EMMC and NAND
TDX_IMX_HAB_CST_SRK="${TDX_IMX_HAB_CST_SRK}" \
TDX_IMX_HAB_CST_CSF_CERT="${TDX_IMX_HAB_CST_CSF_CERT}" \
TDX_IMX_HAB_CST_IMG_CERT="${TDX_IMX_HAB_CST_IMG_CERT}" \
TDX_IMX_HAB_CST_BIN="${TDX_IMX_HAB_CST_BIN}" \
IMXBOOT="${B}/u-boot.${UBOOT_SUFFIX}" \
HAB_LOG="${B}/${UBOOT_MAKE_TARGET}.log" \
${WORKDIR}/create_csf.sh -m "${soc}"
# Save unsigned image
cp ${UBOOT_BINARY} ${UBOOT_BINARY}-unsigned
# determine unpadded size assuming IVT is @0x400 and BOOTDATA follows immediately IVT
tmp=$(mktemp)
# extract self pointer
dd if=${UBOOT_BINARY} of=${tmp} bs=1 count=4 skip=1044
self=$(hexdump -e '"%u"' ${tmp})
# extract csf pointer
dd if=${UBOOT_BINARY} of=$tmp bs=1 count=4 skip=1048
csf=$(hexdump -e '"%u"' $tmp)
unsignedsize=$(expr ${csf} - ${self} + 1024)
#copy CSF into image, which is already padded at both ends
dd of=${UBOOT_BINARY} if=${WORKDIR}/csf-uboot.bin seek=1 bs=$unsignedsize conv=notrunc
else
# Generate CSF file
TDX_IMX_HAB_CST_SRK="${TDX_IMX_HAB_CST_SRK}" \
TDX_IMX_HAB_CST_CSF_CERT="${TDX_IMX_HAB_CST_CSF_CERT}" \
TDX_IMX_HAB_CST_IMG_CERT="${TDX_IMX_HAB_CST_IMG_CERT}" \
TDX_IMX_HAB_CST_BIN="${TDX_IMX_HAB_CST_BIN}" \
IMXBOOT="${B}/${UBOOT_BINARY}" \
HAB_LOG="${B}/${UBOOT_MAKE_TARGET}.log" \
${WORKDIR}/create_csf.sh -m "${soc}"
# Save unsigned image
mv ${UBOOT_BINARY} ${UBOOT_BINARY}-unsigned
# Append CSF to image
cat ${UBOOT_BINARY}-unsigned ${WORKDIR}/csf-uboot.bin > ${UBOOT_BINARY}
fi
# Create fuse commands
${WORKDIR}/create_fuse_cmds.sh ${soc} ${TDX_IMX_HAB_CST_SRK_FUSE} ${WORKDIR}/fuse-cmds.txt
fi
}