avbtool: Add --print_required_libavb_version option.
This can be used with make_vbmeta_image, add_hash_footer, and
add_hashtree_footer to figure out what will be put in the
required_libavb_version_{major, minor} fields in the VBMeta
struct. This is useful if you also want to store this value in a file
inside system.img before adding a hashtree and integrity data to it.
Right now "1.0" will be printed out since we're still at 1.0. In the
future this may get more complicated.
As with --calc_max_image_size the caller is supposed to pass all the
same options (except --output and --image) that they would pass when
not using the option. This is because options will influence what
minimum libavb version will be required - for example, if using an
algorithm introduced post-1.0 this would be expressed with the
--algorithm option.
Bug: 62077941
Test: New unit test and all unit tests pass.
Change-Id: I97a26f5b51eb4a8c63ca7903a406b174eb88bacb
diff --git a/README.md b/README.md
index 459308a..df6218f 100644
--- a/README.md
+++ b/README.md
@@ -284,7 +284,9 @@
* The feature is used if - and only if - suitable commands/options are
passed to `avbtool`.
* The `required_version_minor` field is set to the bumped value if -
- and only if - the feature is used.
+ and only if - the feature is used. Also add tests to check that the
+ correct value is output when `--print_required_libavb_version` is
+ used.
If `AVB_VERSION_MINOR` has already been bumped since the last release
there is obviously no need to bump it again.
@@ -294,21 +296,22 @@
The content for the vbmeta partition can be generated as follows:
$ avbtool make_vbmeta_image \
- --output OUTPUT \
+ [--output OUTPUT] \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--include_descriptors_from_image /path/to/image.bin] \
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--chain_partition part_name:rollback_index_location:/path/to/key1.bin] \
[--signing_helper /path/to/external/signer] \
+ [--print_required_libavb_version] \
[--append_to_release_string STR]
An integrity footer containing the hash for an entire partition can be
added to an existing image as follows:
$ avbtool add_hash_footer \
- --image IMAGE \
--partition_name PARTNAME --partition_size SIZE \
+ [--image IMAGE] \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--hash_algorithm HASH_ALG] [--salt HEX] \
@@ -316,6 +319,7 @@
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image] \
[--signing_helper /path/to/external/signer] \
+ [--print_required_libavb_version] \
[--append_to_release_string STR] \
[--calc_max_image_size]
@@ -324,8 +328,8 @@
hashtree is also appended to the image.
$ avbtool add_hashtree_footer \
- --image IMAGE \
--partition_name PARTNAME --partition_size SIZE \
+ [--image IMAGE] \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--hash_algorithm HASH_ALG] [--salt HEX] [--block_size SIZE] \
@@ -335,6 +339,7 @@
[--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] \
+ [--print_required_libavb_version] \
[--append_to_release_string STR] \
[--calc_max_image_size]
@@ -368,6 +373,18 @@
--calc_max_image_size
10330112
+To calculate the required libavb version that would be put in the
+vbmeta struct when using `make_vbmeta_image`, `add_hash_footer`, and
+`add_hashtree_footer` commands use the
+`--print_required_libavb_version` option:
+
+ $ avbtool make_vbmeta_image \
+ --algorithm SHA256_RSA2048 --key /path/to/key.pem \
+ --include_descriptors_from_image /path/to/boot.img \
+ --include_descriptors_from_image /path/to/system.img \
+ --print_required_libavb_version
+ 1.0
+
The `--signing_helper` option can be used in `make_vbmeta_image`,
`add_hash_footer` and `add_hashtree_footer` commands to specify any
external program for signing hashes. The data to sign (including
diff --git a/avbtool b/avbtool
index 5df31b4..75bae27 100755
--- a/avbtool
+++ b/avbtool
@@ -2336,7 +2336,8 @@
setup_rootfs_from_kernel,
include_descriptors_from_image, signing_helper,
release_string,
- append_to_release_string):
+ append_to_release_string,
+ print_required_libavb_version):
"""Implements the 'make_vbmeta_image' command.
Arguments:
@@ -2355,11 +2356,22 @@
signing_helper: Program which signs a hash and return signature.
release_string: None or avbtool release string to use instead of default.
append_to_release_string: None or string to append.
+ print_required_libavb_version: True to only print required libavb version.
Raises:
AvbError: If a chained partition is malformed.
"""
+ # If we're asked to calculate minimum required libavb version, we're done.
+ #
+ # NOTE: When we get to 1.1 and later this will get more complicated.
+ if print_required_libavb_version:
+ print '1.0'
+ return
+
+ if not output:
+ raise AvbError('No output file given')
+
descriptors = []
ht_desc_to_setup = None
vbmeta_blob = self._generate_vbmeta_blob(
@@ -2694,7 +2706,8 @@
setup_rootfs_from_kernel,
include_descriptors_from_image, calc_max_image_size,
signing_helper, release_string, append_to_release_string,
- output_vbmeta_image, do_not_append_vbmeta_image):
+ output_vbmeta_image, do_not_append_vbmeta_image,
+ print_required_libavb_version):
"""Implementation of the add_hash_footer on unsparse images.
Arguments:
@@ -2724,10 +2737,19 @@
append_to_release_string: None or string to append.
output_vbmeta_image: If not None, also write vbmeta struct to this file.
do_not_append_vbmeta_image: If True, don't append vbmeta struct.
+ print_required_libavb_version: True to only print required libavb version.
Raises:
AvbError: If an argument is incorrect.
"""
+
+ # If we're asked to calculate minimum required libavb version, we're done.
+ #
+ # NOTE: When we get to 1.1 and later this will get more complicated.
+ if print_required_libavb_version:
+ print '1.0'
+ return
+
# First, calculate the maximum image size such that an image
# this size + metadata (footer + vbmeta struct) fits in
# |partition_size|.
@@ -2862,7 +2884,8 @@
include_descriptors_from_image,
calc_max_image_size, signing_helper,
release_string, append_to_release_string,
- output_vbmeta_image, do_not_append_vbmeta_image):
+ output_vbmeta_image, do_not_append_vbmeta_image,
+ print_required_libavb_version):
"""Implements the 'add_hashtree_footer' command.
See https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity for
@@ -2900,10 +2923,19 @@
append_to_release_string: None or string to append.
output_vbmeta_image: If not None, also write vbmeta struct to this file.
do_not_append_vbmeta_image: If True, don't append vbmeta struct.
+ print_required_libavb_version: True to only print required libavb version.
Raises:
AvbError: If an argument is incorrect.
"""
+
+ # If we're asked to calculate minimum required libavb version, we're done.
+ #
+ # NOTE: When we get to 1.1 and later this will get more complicated.
+ if print_required_libavb_version:
+ print '1.0'
+ return
+
digest_size = len(hashlib.new(name=hash_algorithm).digest())
digest_padding = round_to_pow2(digest_size) - digest_size
@@ -3404,6 +3436,11 @@
metavar='IMAGE',
action='append',
type=argparse.FileType('rb'))
+ sub_parser.add_argument('--print_required_libavb_version',
+ help=('Don\'t store the footer - '
+ 'instead calculate the required libavb '
+ 'version for the given options.'),
+ action='store_true')
# These are only allowed from top-level vbmeta and boot-in-lieu-of-vbmeta.
sub_parser.add_argument('--chain_partition',
help='Allow signed integrity-data for partition',
@@ -3458,8 +3495,7 @@
help='Makes a vbmeta image.')
sub_parser.add_argument('--output',
help='Output file name',
- type=argparse.FileType('wb'),
- required=True)
+ type=argparse.FileType('wb'))
self._add_common_args(sub_parser)
sub_parser.set_defaults(func=self.make_vbmeta_image)
@@ -3470,8 +3506,7 @@
type=argparse.FileType('rab+'))
sub_parser.add_argument('--partition_size',
help='Partition size',
- type=parse_number,
- required=True)
+ type=parse_number)
sub_parser.add_argument('--partition_name',
help='Partition name',
default=None)
@@ -3517,8 +3552,7 @@
type=argparse.FileType('rab+'))
sub_parser.add_argument('--partition_size',
help='Partition size',
- type=parse_number,
- required=True)
+ type=parse_number)
sub_parser.add_argument('--partition_name',
help='Partition name',
default=None)
@@ -3731,7 +3765,8 @@
args.include_descriptors_from_image,
args.signing_helper,
args.internal_release_string,
- args.append_to_release_string)
+ args.append_to_release_string,
+ args.print_required_libavb_version)
def append_vbmeta_image(self, args):
"""Implements the 'append_vbmeta_image' sub-command."""
@@ -3755,7 +3790,8 @@
args.internal_release_string,
args.append_to_release_string,
args.output_vbmeta_image,
- args.do_not_append_vbmeta_image)
+ args.do_not_append_vbmeta_image,
+ args.print_required_libavb_version)
def add_hashtree_footer(self, args):
"""Implements the 'add_hashtree_footer' sub-command."""
@@ -3783,7 +3819,8 @@
args.internal_release_string,
args.append_to_release_string,
args.output_vbmeta_image,
- args.do_not_append_vbmeta_image)
+ args.do_not_append_vbmeta_image,
+ args.print_required_libavb_version)
def erase_footer(self, args):
"""Implements the 'erase_footer' sub-command."""
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index f1c1831..e8470d7 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -1849,6 +1849,44 @@
pk8192_path.value().c_str());
}
+TEST_F(AvbToolTest, PrintRequiredLibavbVersion) {
+ base::FilePath output_path = testdir_.Append("versions.txt");
+
+ const size_t boot_partition_size = 16 * 1024 * 1024;
+ EXPECT_COMMAND(0,
+ "./avbtool add_hash_footer"
+ " --rollback_index 0"
+ " --partition_name boot"
+ " --partition_size %zd"
+ " --salt deadbeef"
+ " --internal_release_string \"\""
+ " --print_required_libavb_version >> %s",
+ boot_partition_size,
+ output_path.value().c_str());
+
+ const size_t system_partition_size = 10 * 1024 * 1024;
+ EXPECT_COMMAND(0,
+ "./avbtool add_hashtree_footer --salt d00df00d "
+ "--partition_size %zd --partition_name system "
+ "--internal_release_string \"\""
+ " --print_required_libavb_version >> %s",
+ system_partition_size,
+ output_path.value().c_str());
+
+ EXPECT_COMMAND(0,
+ "./avbtool make_vbmeta_image "
+ "--algorithm SHA256_RSA2048 "
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\""
+ " --print_required_libavb_version >> %s",
+ output_path.value().c_str());
+
+ // Check that "1.0\n" was printed for all three invocations.
+ std::string versions;
+ ASSERT_TRUE(base::ReadFileToString(output_path, &versions));
+ EXPECT_EQ(versions, std::string("1.0\n1.0\n1.0\n"));
+}
+
TEST_F(AvbToolTest, MakeAtxPikCertificate) {
base::FilePath subject_path = testdir_.Append("tmp_subject");
ASSERT_TRUE(base::WriteFile(subject_path, "fake PIK subject", 16));