diff options
author | Erik Schumacher <erik.schumacher@iris-sensing.com> | 2025-03-27 12:18:28 +0000 |
---|---|---|
committer | Khem Raj <raj.khem@gmail.com> | 2025-03-27 17:05:46 -0700 |
commit | a95982edd2261dccd70900e39293fb9418af7cb7 (patch) | |
tree | 069830ff00523a07fff6300726156204921a4913 | |
parent | 70463638b5f0ca05f68b6e63e469cd335150a863 (diff) | |
download | meta-openembedded-a95982edd2261dccd70900e39293fb9418af7cb7.tar.gz |
image_types_verity.bbclass: Optionally create hash data in separate file
On some setups, the verity partition and the corresponding hash data are
handled separately. To account for this, a HASHDEV_SUFFIX is introduced
to divert the hash data to a separate image artifact. By default, this
suffix is equal to the image suffix, meaning that the hash data is
appended to the verity image, like before.
When the hash data is written to a separate file, the verity image is
padded with zeroes until its size is a multiple of block_size.
Signed-off-by: Erik Schumacher <erik.schumacher@iris-sensing.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r-- | meta-oe/classes/image_types_verity.bbclass | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/meta-oe/classes/image_types_verity.bbclass b/meta-oe/classes/image_types_verity.bbclass index b42217c453..d77bc20a13 100644 --- a/meta-oe/classes/image_types_verity.bbclass +++ b/meta-oe/classes/image_types_verity.bbclass | |||
@@ -26,6 +26,10 @@ | |||
26 | # should be the same blockdevice in the command shown above while <dm_dev_name> | 26 | # should be the same blockdevice in the command shown above while <dm_dev_name> |
27 | # is the name of the to be created dm-verity-device. | 27 | # is the name of the to be created dm-verity-device. |
28 | # | 28 | # |
29 | # By specifying a different VERITY_IMAGE_HASHDEV_SUFFIX, the hash tree data can | ||
30 | # be created in a separate file. In this case, <dev> is just zero padded to a | ||
31 | # multiple of VERITY_BLOCK_SIZE. <hash_dev> will be a separate file. | ||
32 | # | ||
29 | # The root hash is calculated using a salt to make attacks more difficult. Thus, | 33 | # The root hash is calculated using a salt to make attacks more difficult. Thus, |
30 | # please grant each image recipe its own salt which could be generated e.g. via | 34 | # please grant each image recipe its own salt which could be generated e.g. via |
31 | # | 35 | # |
@@ -42,6 +46,7 @@ VERITY_SALT ?= "${CLASS_VERITY_SALT}" | |||
42 | VERITY_BLOCK_SIZE ?= "4096" | 46 | VERITY_BLOCK_SIZE ?= "4096" |
43 | VERITY_IMAGE_FSTYPE ?= "ext4" | 47 | VERITY_IMAGE_FSTYPE ?= "ext4" |
44 | VERITY_IMAGE_SUFFIX ?= ".verity" | 48 | VERITY_IMAGE_SUFFIX ?= ".verity" |
49 | VERITY_IMAGE_HASHDEV_SUFFIX ?= "${VERITY_IMAGE_SUFFIX}" | ||
45 | VERITY_INPUT_IMAGE ?= "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${VERITY_IMAGE_FSTYPE}" | 50 | VERITY_INPUT_IMAGE ?= "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.${VERITY_IMAGE_FSTYPE}" |
46 | 51 | ||
47 | IMAGE_TYPEDEP:verity = "${VERITY_IMAGE_FSTYPE}" | 52 | IMAGE_TYPEDEP:verity = "${VERITY_IMAGE_FSTYPE}" |
@@ -56,6 +61,7 @@ python __anonymous() { | |||
56 | } | 61 | } |
57 | 62 | ||
58 | python do_image_verity () { | 63 | python do_image_verity () { |
64 | import io | ||
59 | import os | 65 | import os |
60 | import subprocess | 66 | import subprocess |
61 | import shutil | 67 | import shutil |
@@ -66,6 +72,9 @@ python do_image_verity () { | |||
66 | verity_image_suffix = d.getVar('VERITY_IMAGE_SUFFIX') | 72 | verity_image_suffix = d.getVar('VERITY_IMAGE_SUFFIX') |
67 | verity = '{}{}'.format(image, verity_image_suffix) | 73 | verity = '{}{}'.format(image, verity_image_suffix) |
68 | 74 | ||
75 | verity_image_hashdev_suffix = d.getVar('VERITY_IMAGE_HASHDEV_SUFFIX') | ||
76 | verity_hashdev = '{}{}'.format(image, verity_image_hashdev_suffix) | ||
77 | |||
69 | # For better readability the parameter VERITY_BLOCK_SIZE is specified in | 78 | # For better readability the parameter VERITY_BLOCK_SIZE is specified in |
70 | # bytes. It must be a multiple of the logical sector size which is 512 bytes | 79 | # bytes. It must be a multiple of the logical sector size which is 512 bytes |
71 | # in Linux. Make sure that this is the case as otherwise the resulting | 80 | # in Linux. Make sure that this is the case as otherwise the resulting |
@@ -87,9 +96,9 @@ python do_image_verity () { | |||
87 | bb.debug(1, f"data_size_blocks: {data_size_blocks}, {data_size_rest}") | 96 | bb.debug(1, f"data_size_blocks: {data_size_blocks}, {data_size_rest}") |
88 | bb.debug(1, f"data_size: {data_size}") | 97 | bb.debug(1, f"data_size: {data_size}") |
89 | 98 | ||
90 | # Create verity image | 99 | if verity == verity_hashdev: |
91 | try: | 100 | # creating self-contained dm-verity image |
92 | output = subprocess.check_output([ | 101 | veritysetup_command = [ |
93 | 'veritysetup', 'format', | 102 | 'veritysetup', 'format', |
94 | '--no-superblock', | 103 | '--no-superblock', |
95 | '--salt={}'.format(salt), | 104 | '--salt={}'.format(salt), |
@@ -98,7 +107,27 @@ python do_image_verity () { | |||
98 | '--hash-block-size={}'.format(block_size), | 107 | '--hash-block-size={}'.format(block_size), |
99 | '--hash-offset={}'.format(data_size), | 108 | '--hash-offset={}'.format(data_size), |
100 | verity, verity, | 109 | verity, verity, |
101 | ]) | 110 | ] |
111 | else: | ||
112 | # creating separate dm-verity and hash device image | ||
113 | veritysetup_command = [ | ||
114 | 'veritysetup', 'format', | ||
115 | '--salt={}'.format(salt), | ||
116 | '--data-blocks={}'.format(data_blocks), | ||
117 | '--data-block-size={}'.format(block_size), | ||
118 | '--hash-block-size={}'.format(block_size), | ||
119 | verity, verity_hashdev, | ||
120 | ] | ||
121 | # veritysetup expects the data device size to be a multiple of block_size | ||
122 | # when creating a separate hashdev file, zero pad verity file if needed | ||
123 | if data_size_rest: | ||
124 | with open(verity, 'rb+') as verityfile: | ||
125 | verityfile.seek(0, io.SEEK_END) | ||
126 | verityfile.write(b'\x00' * (block_size - data_size_rest)) | ||
127 | |||
128 | # Create verity image | ||
129 | try: | ||
130 | output = subprocess.check_output(veritysetup_command) | ||
102 | except subprocess.CalledProcessError as err: | 131 | except subprocess.CalledProcessError as err: |
103 | bb.fatal('%s returned with %s (%s)' % (err.cmd, err.returncode, err.output)) | 132 | bb.fatal('%s returned with %s (%s)' % (err.cmd, err.returncode, err.output)) |
104 | 133 | ||
@@ -128,7 +157,11 @@ python do_image_verity () { | |||
128 | bb.fatal('Unexpected error %s' % err) | 157 | bb.fatal('Unexpected error %s' % err) |
129 | 158 | ||
130 | # Create symlinks | 159 | # Create symlinks |
131 | for suffix in [ verity_image_suffix, '.verity-info', '.verity-params' ]: | 160 | suffix_list = [ verity_image_suffix, '.verity-info', '.verity-params' ] |
161 | if verity != verity_hashdev: | ||
162 | suffix_list.append(verity_image_hashdev_suffix) | ||
163 | |||
164 | for suffix in suffix_list: | ||
132 | try: | 165 | try: |
133 | os.remove(link + suffix) | 166 | os.remove(link + suffix) |
134 | except FileNotFoundError: | 167 | except FileNotFoundError: |