avbtool: add_hash_footer: Add --calc_max_image_size option. am: bf56245c7a
am: e8b1ab9613
Change-Id: If53b4a20dc5aa248c1cc690a0230f243372cd13d
diff --git a/README.md b/README.md
index 3e60e37..51ccf54 100644
--- a/README.md
+++ b/README.md
@@ -316,7 +316,8 @@
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image] \
[--signing_helper /path/to/external/signer] \
- [--append_to_release_string STR]
+ [--append_to_release_string STR] \
+ [--calc_max_image_size]
An integrity footer containing the root digest and salt for a hashtree
for a partition can be added to an existing image as follows. The
@@ -334,7 +335,8 @@
[--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image] \
[--do_not_generate_fec] [--fec_num_roots FEC_NUM_ROOTS] \
[--signing_helper /path/to/external/signer] \
- [--append_to_release_string STR]
+ [--append_to_release_string STR] \
+ [--calc_max_image_size]
The size of an image with integrity footers can be changed using the
`resize_image` command:
@@ -354,8 +356,13 @@
image being operated on.
To calculate the maximum size of an image that will fit in a partition
-of a given size after having used the `avbtool add_hashtree_footer`
-command on it, use the `--calc_max_image_size` option:
+of a given size after having used the `avbtool add_hash_footer` or
+`avbtool add_hashtree_footer` commands on it, use the
+`--calc_max_image_size` option:
+
+ $ avbtool add_hash_footer --partition_size $((10*1024*1024)) \
+ --calc_max_image_size
+ 10416128
$ avbtool add_hashtree_footer --partition_size $((10*1024*1024)) \
--calc_max_image_size
diff --git a/avbtool b/avbtool
index 1b459f7..d5fda77 100755
--- a/avbtool
+++ b/avbtool
@@ -2050,9 +2050,6 @@
instructions. There is one for when hashtree is not disabled and one for
when it is.
- Raises:
- AvbError: If |image| doesn't have a hashtree descriptor.
-
"""
c = 'dm="1 vroot none ro 1,'
@@ -2491,8 +2488,8 @@
public_key_metadata_path, rollback_index, flags, props,
props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper,
- release_string, append_to_release_string,
+ include_descriptors_from_image, calc_max_image_size,
+ signing_helper, release_string, append_to_release_string,
output_vbmeta_image, do_not_append_vbmeta_image):
"""Implementation of the add_hash_footer on unsparse images.
@@ -2515,6 +2512,9 @@
dm-verity kernel cmdline from.
include_descriptors_from_image: List of file objects for which
to insert descriptors from.
+ calc_max_image_size: Don't store the footer - instead calculate the
+ maximum image size leaving enough room for metadata with the
+ given |partition_size|.
signing_helper: Program which signs a hash and return signature.
release_string: None or avbtool release string.
append_to_release_string: None or string to append.
@@ -2524,6 +2524,17 @@
Raises:
AvbError: If an argument is incorrect.
"""
+ # First, calculate the maximum image size such that an image
+ # this size + metadata (footer + vbmeta struct) fits in
+ # |partition_size|.
+ max_metadata_size = self.MAX_VBMETA_SIZE + self.MAX_FOOTER_SIZE
+ max_image_size = partition_size - max_metadata_size
+
+ # If we're asked to only calculate the maximum image size, we're done.
+ if calc_max_image_size:
+ print '{}'.format(max_image_size)
+ return
+
image = ImageHandler(image_filename)
if partition_size % image.block_size != 0:
@@ -2546,12 +2557,6 @@
# If anything goes wrong from here-on, restore the image back to
# its original size.
try:
- # First, calculate the maximum image size such that an image
- # this size + metadata (footer + vbmeta struct) fits in
- # |partition_size|.
- max_metadata_size = self.MAX_VBMETA_SIZE + self.MAX_FOOTER_SIZE
- max_image_size = partition_size - max_metadata_size
-
# If image size exceeds the maximum image size, fail.
if image.image_size > max_image_size:
raise AvbError('Image size of {} exceeds maximum image '
@@ -3265,12 +3270,18 @@
required=True)
sub_parser.add_argument('--partition_name',
help='Partition name',
- required=True)
+ default=None)
sub_parser.add_argument('--hash_algorithm',
help='Hash algorithm to use (default: sha256)',
default='sha256')
sub_parser.add_argument('--salt',
help='Salt in hex (default: /dev/urandom)')
+ sub_parser.add_argument('--calc_max_image_size',
+ help=('Don\'t store the footer - '
+ 'instead calculate the maximum image size '
+ 'leaving enough room for metadata with '
+ 'the given partition size.'),
+ action='store_true')
sub_parser.add_argument('--output_vbmeta_image',
help='Also write vbmeta struct to file',
type=argparse.FileType('wb'))
@@ -3518,7 +3529,8 @@
def add_hash_footer(self, args):
"""Implements the 'add_hash_footer' sub-command."""
args = self._fixup_common_args(args)
- self.avb.add_hash_footer(args.image.name, args.partition_size,
+ self.avb.add_hash_footer(args.image.name if args.image else None,
+ args.partition_size,
args.partition_name, args.hash_algorithm,
args.salt, args.chain_partition, args.algorithm,
args.key,
@@ -3527,7 +3539,7 @@
args.kernel_cmdline,
args.setup_rootfs_from_kernel,
args.include_descriptors_from_image,
- args.signing_helper,
+ args.calc_max_image_size, args.signing_helper,
args.internal_release_string,
args.append_to_release_string,
args.output_vbmeta_image,
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index 6cb9ac0..9d53f6c 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -663,6 +663,40 @@
EXPECT_COMMAND(0, "rm -f %s.sparse", partition_path.value().c_str());
}
+TEST_F(AvbToolTest, AddHashFooterCalcMaxImageSize) {
+ const size_t partition_size = 10 * 1024 * 1024;
+ base::FilePath output_path = testdir_.Append("max_size.txt");
+
+ EXPECT_COMMAND(0,
+ "./avbtool add_hash_footer "
+ "--partition_size %zd "
+ "--calc_max_image_size > %s",
+ partition_size,
+ output_path.value().c_str());
+ std::string max_image_size_data;
+ EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
+ EXPECT_EQ("10416128\n", max_image_size_data);
+ size_t max_image_size = atoll(max_image_size_data.c_str());
+
+ // Metadata takes up 68 KiB.
+ EXPECT_EQ(68 * 1024ULL, partition_size - max_image_size);
+
+ // Check that we can add a hash footer for an image this size for
+ // such a partition size.
+ base::FilePath boot_path = GenerateImage("boot", max_image_size);
+ EXPECT_COMMAND(0,
+ "./avbtool add_hash_footer"
+ " --image %s"
+ " --partition_name boot"
+ " --partition_size %zd"
+ " --salt deadbeef"
+ " --algorithm SHA512_RSA4096 "
+ " --key test/data/testkey_rsa4096.pem"
+ " --internal_release_string \"\"",
+ boot_path.value().c_str(),
+ partition_size);
+}
+
void AvbToolTest::AddHashtreeFooterTest(bool sparse_image) {
const size_t rootfs_size = 1028 * 1024;
const size_t partition_size = 1536 * 1024;