diff options
-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: |