diff --git a/board/common/Config.in b/board/common/Config.in index abb65c7a..08fc9839 100644 --- a/board/common/Config.in +++ b/board/common/Config.in @@ -1,5 +1,10 @@ + menu "Images" +comment "DDI Based" +source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ddi/Config.in" + +comment "ITB Based" source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rootfs/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in" diff --git a/board/common/image/image-ddi/Config.in b/board/common/image/image-ddi/Config.in new file mode 100644 index 00000000..c2f2a8ba --- /dev/null +++ b/board/common/image/image-ddi/Config.in @@ -0,0 +1,33 @@ +menuconfig IMAGE_DDI + bool "Discoverable Disk Image (DDI)" + select BR2_TARGET_ROOTFS_SQUASHFS + select BR2_PACKAGE_HOST_GENIMAGE + help + Create a Discoverable Disk Image containing: + - SquashFS of the root filesystem + - dm-verity hash tree of the root filesystem + - DDI compliant JSON signature object of the hash tree + + https://uapi-group.org/specifications/specs/discoverable_disk_image/ + +config IMAGE_DDI_KEY + string "signing key" + depends on IMAGE_DDI + default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key" + help + Path to the private RSA key, in PKCS#8 format, used to sign + the dm-verity hash tree. + +config IMAGE_DDI_CERT + string "signing cert" + depends on IMAGE_DDI + default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt" + help + Path to the X509 certificate whose associated public key can + validate the authenticity of the generated signature. + + The SHA256 fingerprint of this certificate is recorded + alongside the standard PKCS#7 signature in the JSON object, + which can be useful to locate corresponding key on systems + that lack full X509 parsing capabilities. + diff --git a/board/common/image/image-ddi/generate.sh b/board/common/image/image-ddi/generate.sh new file mode 100755 index 00000000..e7116023 --- /dev/null +++ b/board/common/image/image-ddi/generate.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# Generate the DDI in two phases. First we create the verity hash tree +# and signature, then we collect them together with the rootfs in the +# ddi. The reason for this is that genimage (at least up to v19) can +# not infer the size of a partition if the image to be placed in it is +# created by the same genimage instance. With the two-phase approach, +# we work around that problem and can create a DDI without any wasted +# space. + +set -e + +rm -rf "${WORKDIR}"/tmp +mkdir -p "${WORKDIR}"/tmp "${WORKDIR}"/verity + +cat <"${WORKDIR}"/genimage-verity.cfg +image rootfs.verity { + verity { + image = "rootfs.squashfs" + } +} + +image rootfs.verity-sig { + verity-sig { + image = "rootfs.verity" + cert = "${CERT}" + key = "${KEY}" + } +} + +config {} +EOF + +genimage \ + --loglevel 1 \ + --tmppath "${WORKDIR}"/tmp \ + --rootpath "${WORKDIR}" \ + --inputpath "${BINARIES_DIR}" \ + --outputpath "${WORKDIR}"/verity \ + --config "${WORKDIR}"/genimage-verity.cfg + +case "${BR2_ARCH}" in + "x86_64") + arch=x86-64 + ;; + *) + echo "ERROR: missing mapping from ${BR2_ARCH} to genimage arch" >&2 + exit 1 + ;; +esac + +cat <"${WORKDIR}"/genimage-ddi.cfg +image ${ARTIFACT}.raw { + hdimage { + partition-table-type = "gpt" + } + + partition root { + partition-type-uuid = "root-${arch}" + image = "rootfs.squashfs" + } + partition root-verity { + partition-type-uuid = "root-${arch}-verity" + image = "${WORKDIR}/verity/rootfs.verity" + } + partition root-verity-sig { + partition-type-uuid = "root-${arch}-verity-sig" + image = "${WORKDIR}/verity/rootfs.verity-sig" + } +} + +config {} +EOF + +genimage \ + --loglevel 1 \ + --tmppath "${WORKDIR}"/tmp \ + --rootpath "${WORKDIR}" \ + --inputpath "${BINARIES_DIR}" \ + --outputpath "${BINARIES_DIR}" \ + --config "${WORKDIR}"/genimage-ddi.cfg diff --git a/board/common/image/image-ddi/genimage.cfg b/board/common/image/image-ddi/genimage.cfg new file mode 100644 index 00000000..e89dc3ac --- /dev/null +++ b/board/common/image/image-ddi/genimage.cfg @@ -0,0 +1,32 @@ +image rootfs.verity { + verity { + image = "rootfs.squashfs" + } +} + +image rootfs.verity-sig { + verity-sig { + image = "rootfs.verity" + cert = "@CERT@" + key = "@KEY@" + } +} + +image @ARTIFACT@.raw { + hdimage { + partition-table-type = "gpt" + } + + partition root { + partition-type-uuid = "root-@ARCH@" + image = "rootfs.squashfs" + } + partition root-verity { + partition-type-uuid = "root-@ARCH@-verity" + image = "rootfs.verity" + } + partition root-verity-sig { + partition-type-uuid = "root-@ARCH@-verity-sig" + image = "rootfs.verity-sig" + } +} \ No newline at end of file diff --git a/board/common/image/image-ddi/image-ddi.mk b/board/common/image/image-ddi/image-ddi.mk new file mode 100644 index 00000000..2ffc6a47 --- /dev/null +++ b/board/common/image/image-ddi/image-ddi.mk @@ -0,0 +1,10 @@ +################################################################################ +# +# image-ddi +# +################################################################################ + +IMAGE_DDI_DEPENDENCIES := host-genimage rootfs-squashfs +IMAGE_DDI_CONFIG_VARS := KEY CERT + +$(eval $(ix-image)) diff --git a/board/common/image/ix-image.mk b/board/common/image/ix-image.mk index 2da7cc2f..ba23dcd8 100644 --- a/board/common/image/ix-image.mk +++ b/board/common/image/ix-image.mk @@ -10,6 +10,7 @@ $(1): $$($(2)_DEPENDENCIES) PKGDIR=$$($(2)_DIR) \ WORKDIR=$$(BUILD_DIR)/$(1) \ BINARIES_DIR=$$(BINARIES_DIR) \ + BR2_ARCH=$$(BR2_ARCH) \ BR2_EXTERNAL_INFIX_PATH=$$(BR2_EXTERNAL_INFIX_PATH) \ ARTIFACT=$$(INFIX_ARTIFACT) \ COMPATIBLE=$$(INFIX_COMPATIBLE) \