diff mbox series

[OpenWrt-Devel,07/11] include/image.mk: add support for building a dm-verity enabled squashfs image

Message ID 20190311162028.13172-8-thomas.petazzoni@bootlin.com
State Superseded
Headers show
Series Proposal for dm-verity support | expand

Commit Message

Thomas Petazzoni March 11, 2019, 4:20 p.m. UTC
This commit adds a new TARGET_ROOTFS_SQUASHFS_HASHED option that asks
OpenWRT to generate a squashfs image suitable for usage with
dm-verity. The squashfs image is produced, and then passed through
"cryptsetup format" which appends the hash tree to the image.

The output of "cryptsetup format" is passed to a custom script that
parses that output and generates a U-Boot script that defines U-Boot
variables describing the different aspects of the dm-verity
volume. Such values are necessary to be able to build the kernel
command line to mount the dm-verity volume as the root filesystem.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
 config/Config-images.in                   |  4 +++
 include/image.mk                          | 12 +++++++
 scripts/prepare-dm-verity-uboot-script.sh | 41 +++++++++++++++++++++++
 3 files changed, 57 insertions(+)
 create mode 100755 scripts/prepare-dm-verity-uboot-script.sh

Comments

Hauke Mehrtens March 25, 2019, 5:21 p.m. UTC | #1
On 3/11/19 5:20 PM, Thomas Petazzoni wrote:
> This commit adds a new TARGET_ROOTFS_SQUASHFS_HASHED option that asks
> OpenWRT to generate a squashfs image suitable for usage with
> dm-verity. The squashfs image is produced, and then passed through
> "cryptsetup format" which appends the hash tree to the image.
> 
> The output of "cryptsetup format" is passed to a custom script that
> parses that output and generates a U-Boot script that defines U-Boot
> variables describing the different aspects of the dm-verity
> volume. Such values are necessary to be able to build the kernel
> command line to mount the dm-verity volume as the root filesystem.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> ---
>  config/Config-images.in                   |  4 +++
>  include/image.mk                          | 12 +++++++
>  scripts/prepare-dm-verity-uboot-script.sh | 41 +++++++++++++++++++++++
>  3 files changed, 57 insertions(+)
>  create mode 100755 scripts/prepare-dm-verity-uboot-script.sh
> 
> diff --git a/config/Config-images.in b/config/Config-images.in
> index 6fa9a67cb6..95a8af8502 100644
> --- a/config/Config-images.in
> +++ b/config/Config-images.in
> @@ -152,6 +152,10 @@ menu "Target Images"
>  			default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
>  			default 256
>  
> +		config TARGET_ROOTFS_SQUASHFS_HASHED
> +			bool "hash with veritysetup"
> +			depends on TARGET_ROOTFS_SQUASHFS
> +
>  	menuconfig TARGET_ROOTFS_UBIFS
>  		bool "ubifs"
>  		default y if USES_UBIFS
> diff --git a/include/image.mk b/include/image.mk
> index f2a85f6feb..718d3780c9 100644
> --- a/include/image.mk
> +++ b/include/image.mk
> @@ -87,6 +87,7 @@ endif
>  JFFS2_BLOCKSIZE ?= 64k 128k
>  
>  fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
> +fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS_HASHED) += squashfs-hashed
>  fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
>  fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
>  fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
> @@ -207,6 +208,17 @@ define Image/mkfs/squashfs
>  		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
>  endef
>  
> +define Image/mkfs/squashfs-hashed
> +	$(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mkfs_target_dir,$(1)) $@ \

Why don't you just call Image/mkfs/squashfs here and then do the
additional veritysetup?

> +		-noappend -root-owned \
> +		-comp $(SQUASHFSCOMP) $(SQUASHFSOPT) \
> +		-processors 1 \
> +		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))

Setting SOURCE_DATE_EPOCH is not needed any more.

> +	filesize=`stat -c "%s" $@` ; \
> +	$(STAGING_DIR_HOST)/bin/veritysetup format --hash-offset=$${filesize} $@ $@ \
> +		| $(TOPDIR)/scripts/prepare-dm-verity-uboot-script.sh > $@-dm-verity-uboot-script.txt
> +endef
> +
>  # $(1): board name
>  # $(2): rootfs type
>  # $(3): kernel image
> diff --git a/scripts/prepare-dm-verity-uboot-script.sh b/scripts/prepare-dm-verity-uboot-script.sh
> new file mode 100755
> index 0000000000..846e52b989
> --- /dev/null
> +++ b/scripts/prepare-dm-verity-uboot-script.sh
> @@ -0,0 +1,41 @@
> +#!/bin/bash
> +
> +while read line; do
> +	key=$(echo ${line} | cut -f1 -d':')
> +	value=$(echo ${line} | cut -f2 -d':')
> +
> +	case "${key}" in
> +	"UUID")
> +		UUID=${value}
> +		;;
> +	"Data blocks")
> +		DATA_BLOCKS=${value}
> +		;;
> +	"Data block size")
> +		DATA_BLOCK_SIZE=${value}
> +		;;
> +	"Hash block size")
> +		HASH_BLOCK_SIZE=${value}
> +		;;
> +	"Hash algorithm")
> +		HASH_ALG=${value}
> +		;;
> +	"Salt")
> +		SALT=${value}
> +		;;
> +	"Root hash")
> +		ROOT_HASH=${value}
> +		;;
> +	esac
> +done
> +
> +SECTORS=$((${DATA_BLOCKS} * 8))
> +
> +echo setenv verity_sectors $((${DATA_BLOCKS} * 8))
> +echo setenv verity_data_blocks ${DATA_BLOCKS}
> +echo setenv verity_hash_start $((${DATA_BLOCKS} + 1))
> +echo setenv verity_data_block_sz ${DATA_BLOCK_SIZE}
> +echo setenv verity_hash_block_sz ${HASH_BLOCK_SIZE}
> +echo setenv verity_hash_alg ${HASH_ALG}
> +echo setenv verity_salt ${SALT}
> +echo setenv verity_root_hash ${ROOT_HASH}
>
Thomas Petazzoni March 25, 2019, 6 p.m. UTC | #2
Hello Hauke,

One again, thanks for the review!

On Mon, 25 Mar 2019 18:21:56 +0100
Hauke Mehrtens <hauke@hauke-m.de> wrote:

> >  fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
> > +fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS_HASHED) += squashfs-hashed
> >  fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
> >  fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
> >  fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
> > @@ -207,6 +208,17 @@ define Image/mkfs/squashfs
> >  		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
> >  endef
> >  
> > +define Image/mkfs/squashfs-hashed
> > +	$(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mkfs_target_dir,$(1)) $@ \  
> 
> Why don't you just call Image/mkfs/squashfs here and then do the
> additional veritysetup?

Because Image/mkfs/squashfs passes the -nopad option, causing the image
to not be 4 KB-padded, while "veritysetup format" needs a 4KB-padded
image, which is what mksquashfs does by default when -nopad is *not*
passed. An alternate solution is to use Image/mkfs/squashfs, and then
pad the image separately.

> > +		-noappend -root-owned \
> > +		-comp $(SQUASHFSCOMP) $(SQUASHFSOPT) \
> > +		-processors 1 \
> > +		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))  
> 
> Setting SOURCE_DATE_EPOCH is not needed any more.

Ah, indeed, it has been dropped from Image/mkfs/squashfs. Allowed me to
discover the squashfskit fork of squashfs-tools, which I wasn't aware
of.

Thanks,

Thomas
diff mbox series

Patch

diff --git a/config/Config-images.in b/config/Config-images.in
index 6fa9a67cb6..95a8af8502 100644
--- a/config/Config-images.in
+++ b/config/Config-images.in
@@ -152,6 +152,10 @@  menu "Target Images"
 			default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
 			default 256
 
+		config TARGET_ROOTFS_SQUASHFS_HASHED
+			bool "hash with veritysetup"
+			depends on TARGET_ROOTFS_SQUASHFS
+
 	menuconfig TARGET_ROOTFS_UBIFS
 		bool "ubifs"
 		default y if USES_UBIFS
diff --git a/include/image.mk b/include/image.mk
index f2a85f6feb..718d3780c9 100644
--- a/include/image.mk
+++ b/include/image.mk
@@ -87,6 +87,7 @@  endif
 JFFS2_BLOCKSIZE ?= 64k 128k
 
 fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
+fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS_HASHED) += squashfs-hashed
 fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
 fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
 fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
@@ -207,6 +208,17 @@  define Image/mkfs/squashfs
 		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
 endef
 
+define Image/mkfs/squashfs-hashed
+	$(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mkfs_target_dir,$(1)) $@ \
+		-noappend -root-owned \
+		-comp $(SQUASHFSCOMP) $(SQUASHFSOPT) \
+		-processors 1 \
+		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
+	filesize=`stat -c "%s" $@` ; \
+	$(STAGING_DIR_HOST)/bin/veritysetup format --hash-offset=$${filesize} $@ $@ \
+		| $(TOPDIR)/scripts/prepare-dm-verity-uboot-script.sh > $@-dm-verity-uboot-script.txt
+endef
+
 # $(1): board name
 # $(2): rootfs type
 # $(3): kernel image
diff --git a/scripts/prepare-dm-verity-uboot-script.sh b/scripts/prepare-dm-verity-uboot-script.sh
new file mode 100755
index 0000000000..846e52b989
--- /dev/null
+++ b/scripts/prepare-dm-verity-uboot-script.sh
@@ -0,0 +1,41 @@ 
+#!/bin/bash
+
+while read line; do
+	key=$(echo ${line} | cut -f1 -d':')
+	value=$(echo ${line} | cut -f2 -d':')
+
+	case "${key}" in
+	"UUID")
+		UUID=${value}
+		;;
+	"Data blocks")
+		DATA_BLOCKS=${value}
+		;;
+	"Data block size")
+		DATA_BLOCK_SIZE=${value}
+		;;
+	"Hash block size")
+		HASH_BLOCK_SIZE=${value}
+		;;
+	"Hash algorithm")
+		HASH_ALG=${value}
+		;;
+	"Salt")
+		SALT=${value}
+		;;
+	"Root hash")
+		ROOT_HASH=${value}
+		;;
+	esac
+done
+
+SECTORS=$((${DATA_BLOCKS} * 8))
+
+echo setenv verity_sectors $((${DATA_BLOCKS} * 8))
+echo setenv verity_data_blocks ${DATA_BLOCKS}
+echo setenv verity_hash_start $((${DATA_BLOCKS} + 1))
+echo setenv verity_data_block_sz ${DATA_BLOCK_SIZE}
+echo setenv verity_hash_block_sz ${HASH_BLOCK_SIZE}
+echo setenv verity_hash_alg ${HASH_ALG}
+echo setenv verity_salt ${SALT}
+echo setenv verity_root_hash ${ROOT_HASH}