Snap for 6439596 from ab84f1361f164e2ff20564d2d2595497ddf80ce5 to qt-aml-tzdata-release
Change-Id: Ie91f99ce4f905f8ecdcab123ea0fe07962f9c38f
diff --git a/Android.bp b/Android.bp
index 097d80a..7245161 100644
--- a/Android.bp
+++ b/Android.bp
@@ -107,10 +107,7 @@
],
host_supported: true,
recovery_available: true,
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
target: {
linux: {
srcs: ["libavb/avb_sysdeps_posix.c"],
@@ -131,10 +128,7 @@
"avb_sources",
],
recovery_available: true,
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
shared_libs: ["libbase"],
static_libs: ["libfs_mgr"],
cflags: [
@@ -163,10 +157,7 @@
cc_library_host_static {
name: "libavb_ab_host",
defaults: ["avb_defaults"],
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
cflags: [
"-fno-stack-protector",
"-DAVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED",
@@ -177,10 +168,7 @@
cc_library_host_static {
name: "libavb_atx_host",
defaults: ["avb_defaults"],
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
cflags: [
"-fno-stack-protector",
],
@@ -190,20 +178,14 @@
cc_library_host_static {
name: "libavb_host_sysdeps",
defaults: ["avb_defaults"],
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
srcs: ["libavb/avb_sysdeps_posix.c"],
}
cc_library_host_static {
name: "libavb_things_example",
defaults: ["avb_defaults"],
- header_libs: [
- "avb_headers",
- ],
- export_header_lib_headers: ["avb_headers"],
+ export_include_dirs: ["."],
srcs: ["examples/things/avb_atx_slot_verify.c"],
}
@@ -279,15 +261,3 @@
],
srcs: ["boot_control/boot_control_avb.c"],
}
-
-cc_library_headers {
- name: "avb_headers",
- host_supported: true,
- recovery_available: true,
- export_include_dirs: ["."],
- target: {
- windows: {
- enabled: true,
- },
- },
-}
diff --git a/README.md b/README.md
index b01acee..fbee3f5 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,6 @@
+ [Persistent Digests](#Persistent-Digests)
+ [Updating Stored Rollback Indexes](#Updating-Stored-Rollback-Indexes)
+ [Recommended Bootflow](#Recommended-Bootflow)
- + [Booting Into Recovery](#Booting-Into-Recovery)
+ [Handling dm-verity Errors](#Handling-dm_verity-Errors)
+ [Android Specific Integration](#Android-Specific-Integration)
+ [Device Specific Notes](#Device-Specific-Notes)
@@ -165,24 +164,6 @@
known good operating systems which, if found, provides additional assurance
about the device the application is running on.
-For [factory images of Pixel 3 and later
-devices](https://developers.google.com/android/images), the
-`pixel_factory_image_verify.py` located in `tools/transparency` is a convenience
-tool for downloading, verifying and calcuating VBMeta Digests.
-
- $ pixel_factory_image_verify.py https://dl.google.com/dl/android/aosp/image.zip
- Fetching file from: https://dl.google.com/dl/android/aosp/image.zip
- Successfully downloaded file.
- Successfully unpacked factory image.
- Successfully unpacked factory image partitions.
- Successfully verified VBmeta.
- Successfully calculated VBMeta Digest.
- The VBMeta Digest for factory image is: 1f329b20a2dd69425e7a29566ca870dad51d2c579311992d41c9ba9ba05e170e
-
-If the given argument is not an URL it considered to be a local file:
-
- $ pixel_factory_image_verify.py image.zip
-
# Tools and Libraries
This section contains information about the tools and libraries
@@ -422,7 +403,6 @@
[--append_to_release_string STR] \
[--calc_max_image_size] \
[--do_not_use_ab] \
- [--no_hashtree] \
[--use_persistent_digest]
The size of an image with integrity footers can be changed using the
@@ -442,18 +422,6 @@
also specify that the vbmeta struct and footer not be added to the
image being operated on.
-The hashtree and FEC data in an image can be zeroed out with the following
-command:
-
- $ avbtool zero_hashtree --image IMAGE
-
-This is useful for trading compressed image size for having to reculculate the
-hashtree and FEC at runtime. If this is done the hashtree and FEC data is set
-to zero except for the first eight bytes which are set to the magic
-`ZeRoHaSH`. Either the hashtree or FEC data or both may be zeroed this way
-so applications should check for the magic both places. Applications can
-use the magic to detect if recalculation is needed.
-
To calculate the maximum size of an image that will fit in a partition
of a given size after having used the `avbtool add_hash_footer` or
`avbtool add_hashtree_footer` commands on it, use the
@@ -479,12 +447,6 @@
--print_required_libavb_version
1.0
-Alternatively, `--no_hashtree` can be used with `avbtool add_hashtree_footer`
-command. If `--no_hashtree` is given, the hashtree blob is omitted and only
-its descriptor is added to the vbmeta struct. The descriptor says the size
-of hashtree is 0, which tells an application the need to recalculate
-hashtree.
-
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
@@ -602,8 +564,8 @@
`system.img`, a kernel-cmdline descriptor for setting up `dm-verity`
for `system.img` and append a hash-tree to `system.img`. If the build
system is set up such that one or many of `vendor.img` / `product.img`
-/ `system_ext.img` / `odm.img` are being built, the hash-tree for each
-of them will also be appended to the image respectively, and their
+/ `odm.img` / `product_services.img` are being built, the hash-tree for
+each of them will also be appended to the image respectively, and their
hash-tree descriptors will be included into `vbmeta.img` accordingly.
By default, the algorithm `SHA256_RSA4096` is used with a test key
@@ -631,20 +593,20 @@
partitions without changing the top-level `vbmeta` partition. For example,
the following variables create `vbmeta_system.img` as a chained `vbmeta`
image that contains the hash-tree descriptors for `system.img` and
-`system_ext.img`. `vbmeta_system.img` itself will be signed by the specified
-key and algorithm.
+`product_services.img`. `vbmeta_system.img` itself will be signed by the
+specified key and algorithm.
- BOARD_AVB_VBMETA_SYSTEM := system system_ext
+ BOARD_AVB_VBMETA_SYSTEM := system product_services
BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
-Note that the hash-tree descriptors for `system.img` and `system_ext.img`
-will be included only in `vbmeta_system.img`, but not `vbmeta.img`. With
-the above setup, partitions `system.img`, `system_ext.img` and
-`vbmeta_system.img` can be updated independently - but as a group - of the
-rest of the partitions, *or* as part of the traditional updates that
-update all the partitions.
+Note that the hash-tree descriptors for `system.img` and
+`product_services.img` will be included only in `vbmeta_system.img`, but
+not `vbmeta.img`. With the above setup, partitions `system.img`,
+`product_services.img` and `vbmeta_system.img` can be updated
+independently - but as a group - of the rest of the partitions, *or* as
+part of the traditional updates that update all the partitions.
Currently build system supports building chained `vbmeta` images of
`vbmeta_system.img` (`BOARD_AVB_VBMETA_SYSTEM`) and `vbmeta_vendor.img`
@@ -925,19 +887,6 @@
be used to convey that the device is UNLOCKED (lightbars, LEDs,
etc.).
-### Booting Into Recovery
-
-On Android devices not using A/B, the `recovery` partition usually isn't
-updated along with other partitions and therefore can't be referenced
-from the main `vbmeta` partition.
-
-It's still possible to use AVB to protect this partition (and others)
-by signing these partitions and passing the
-`AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION` flag to `avb_slot_verify()`.
-In this mode, the key used to sign each requested partition is verified
-by the `validate_public_key_for_partition()` operation which is also
-used to return the rollback index location to be used.
-
## Handling dm-verity Errors
By design, hashtree verification errors are detected by the HLOS and
diff --git a/avbtool b/avbtool
index 92c024c..610cf19 100755
--- a/avbtool
+++ b/avbtool
@@ -1121,7 +1121,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1130,7 +1130,6 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
@@ -1208,7 +1207,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1217,7 +1216,6 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
@@ -1371,7 +1369,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1380,13 +1378,11 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
"""
if self.partition_name == '':
- image_filename = image_containing_descriptor.filename
image = image_containing_descriptor
else:
image_filename = os.path.join(image_dir, self.partition_name + image_ext)
@@ -1410,22 +1406,17 @@
# ... also check that the on-disk hashtree matches
image.seek(self.tree_offset)
hash_tree_ondisk = image.read(self.tree_size)
- is_zeroed = (self.tree_size == 0) or (hash_tree_ondisk[0:8] == 'ZeRoHaSH')
- if is_zeroed and accept_zeroed_hashtree:
- print ('{}: skipping verification since hashtree is zeroed and --accept_zeroed_hashtree was given'
- .format(self.partition_name))
- else:
- if hash_tree != hash_tree_ondisk:
- sys.stderr.write('hashtree of {} contains invalid data\n'.
- format(image_filename))
- return False
- print ('{}: Successfully verified {} hashtree of {} for image of {} bytes'
- .format(self.partition_name, self.hash_algorithm, image.filename,
- self.image_size))
+ if hash_tree != hash_tree_ondisk:
+ sys.stderr.write('hashtree of {} contains invalid data\n'.
+ format(image_filename))
+ return False
# TODO: we could also verify that the FEC stored in the image is
# correct but this a) currently requires the 'fec' binary; and b)
# takes a long time; and c) is not strictly needed for
# verification purposes as we've already verified the root hash.
+ print ('{}: Successfully verified {} hashtree of {} for image of {} bytes'
+ .format(self.partition_name, self.hash_algorithm, image.filename,
+ self.image_size))
return True
@@ -1535,7 +1526,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1544,13 +1535,11 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
"""
if self.partition_name == '':
- image_filename = image_containing_descriptor.filename
image = image_containing_descriptor
else:
image_filename = os.path.join(image_dir, self.partition_name + image_ext)
@@ -1647,7 +1636,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1656,7 +1645,6 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
@@ -1751,7 +1739,7 @@
return bytearray(ret)
def verify(self, image_dir, image_ext, expected_chain_partitions_map,
- image_containing_descriptor, accept_zeroed_hashtree):
+ image_containing_descriptor):
"""Verifies contents of the descriptor - used in verify_image sub-command.
Arguments:
@@ -1760,7 +1748,6 @@
expected_chain_partitions_map: A map from partition name to the
tuple (rollback_index_location, key_blob).
image_containing_descriptor: The image the descriptor is in.
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
Returns:
True if the descriptor verifies, False otherwise.
@@ -2099,63 +2086,6 @@
# And cut...
image.truncate(new_image_size)
- def zero_hashtree(self, image_filename):
- """Implements the 'zero_hashtree' command.
-
- Arguments:
- image_filename: File to zero hashtree and FEC data from.
-
- Raises:
- AvbError: If there's no footer in the image.
- """
-
- image = ImageHandler(image_filename)
-
- (footer, _, descriptors, _) = self._parse_image(image)
-
- if not footer:
- raise AvbError('Given image does not have a footer.')
-
- # Search for a hashtree descriptor to figure out the location and
- # size of the hashtree and FEC.
- ht_desc = None
- for desc in descriptors:
- if isinstance(desc, AvbHashtreeDescriptor):
- ht_desc = desc
- break
-
- if not ht_desc:
- raise AvbError('No hashtree descriptor was found.')
-
- zero_ht_start_offset = ht_desc.tree_offset
- zero_ht_num_bytes = ht_desc.tree_size
- zero_fec_start_offset = None
- zero_fec_num_bytes = 0
- if ht_desc.fec_offset > 0:
- if ht_desc.fec_offset != ht_desc.tree_offset + ht_desc.tree_size:
- raise AvbError('Hash-tree and FEC data must be adjacent.')
- zero_fec_start_offset = ht_desc.fec_offset
- zero_fec_num_bytes = ht_desc.fec_size
- zero_end_offset = zero_ht_start_offset + zero_ht_num_bytes + zero_fec_num_bytes
- image.seek(zero_end_offset)
- data = image.read(image.image_size - zero_end_offset)
-
- # Write zeroes all over hashtree and FEC, except for the first eight bytes
- # where a magic marker - ZeroHaSH - is placed. Place these markers in the
- # beginning of both hashtree and FEC. (That way, in the future we can add
- # options to 'avbtool zero_hashtree' so as to zero out only either/or.)
- #
- # Applications can use these markers to detect that the hashtree and/or
- # FEC needs to be recomputed.
- image.truncate(zero_ht_start_offset)
- data_zeroed_firstblock = 'ZeRoHaSH' + '\0'*(image.block_size - 8)
- image.append_raw(data_zeroed_firstblock)
- image.append_fill('\0\0\0\0', zero_ht_num_bytes - image.block_size)
- if zero_fec_start_offset:
- image.append_raw(data_zeroed_firstblock)
- image.append_fill('\0\0\0\0', zero_fec_num_bytes - image.block_size)
- image.append_raw(data)
-
def resize_image(self, image_filename, partition_size):
"""Implements the 'resize_image' command.
@@ -2290,8 +2220,7 @@
if num_printed == 0:
o.write(' (none)\n')
- def verify_image(self, image_filename, key_path, expected_chain_partitions, follow_chain_partitions,
- accept_zeroed_hashtree):
+ def verify_image(self, image_filename, key_path, expected_chain_partitions, follow_chain_partitions):
"""Implements the 'verify_image' command.
Arguments:
@@ -2300,7 +2229,6 @@
expected_chain_partitions: List of chain partitions to check or None.
follow_chain_partitions: If True, will follows chain partitions even when not
specified with the --expected_chain_partition option
- accept_zeroed_hashtree: If True, don't fail if hashtree or FEC data is zeroed out.
"""
expected_chain_partitions_map = {}
if expected_chain_partitions:
@@ -2366,14 +2294,13 @@
.format(desc.partition_name, desc.rollback_index_location,
hashlib.sha1(desc.public_key).hexdigest()))
else:
- if not desc.verify(image_dir, image_ext, expected_chain_partitions_map, image,
- accept_zeroed_hashtree):
+ if not desc.verify(image_dir, image_ext, expected_chain_partitions_map, image):
raise AvbError('Error verifying descriptor.')
# Honor --follow_chain_partitions - add '--' to make the output more readable.
if isinstance(desc, AvbChainPartitionDescriptor) and follow_chain_partitions:
print '--'
chained_image_filename = os.path.join(image_dir, desc.partition_name + image_ext)
- self.verify_image(chained_image_filename, key_path, None, False, accept_zeroed_hashtree)
+ self.verify_image(chained_image_filename, key_path, None, False)
def calculate_vbmeta_digest(self, image_filename, hash_algorithm, output):
@@ -3246,7 +3173,7 @@
release_string, append_to_release_string,
output_vbmeta_image, do_not_append_vbmeta_image,
print_required_libavb_version,
- use_persistent_root_digest, do_not_use_ab, no_hashtree):
+ use_persistent_root_digest, do_not_use_ab):
"""Implements the 'add_hashtree_footer' command.
See https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity for
@@ -3288,7 +3215,6 @@
print_required_libavb_version: True to only print required libavb version.
use_persistent_root_digest: Use a persistent root digest on device.
do_not_use_ab: The partition does not use A/B.
- no_hashtree: Do not append hashtree. Set size in descriptor as zero.
Raises:
AvbError: If an argument is incorrect.
@@ -3311,13 +3237,11 @@
# vbmeta struct) fits in |partition_size|. We use very conservative figures
# for metadata.
if partition_size > 0:
- max_tree_size = 0
+ (_, max_tree_size) = calc_hash_level_offsets(
+ partition_size, block_size, digest_size + digest_padding)
max_fec_size = 0
- if not no_hashtree:
- (_, max_tree_size) = calc_hash_level_offsets(
- partition_size, block_size, digest_size + digest_padding)
- if generate_fec:
- max_fec_size = calc_fec_data_size(partition_size, fec_num_roots)
+ if generate_fec:
+ max_fec_size = calc_fec_data_size(partition_size, fec_num_roots)
max_metadata_size = (max_fec_size + max_tree_size +
self.MAX_VBMETA_SIZE +
self.MAX_FOOTER_SIZE)
@@ -3410,9 +3334,6 @@
# Generate HashtreeDescriptor with details about the tree we
# just generated.
- if no_hashtree:
- tree_size = 0
- hash_tree = bytearray()
ht_desc = AvbHashtreeDescriptor()
ht_desc.dm_verity_version = 1
ht_desc.image_size = image.image_size
@@ -3437,10 +3358,7 @@
# Generate FEC codes, if requested.
if generate_fec:
- if no_hashtree:
- fec_data = bytearray()
- else:
- fec_data = generate_fec_data(image_filename, fec_num_roots)
+ fec_data = generate_fec_data(image_filename, fec_num_roots)
padding_needed = (round_to_multiple(len(fec_data), image.block_size) -
len(fec_data))
fec_data_with_padding = fec_data + '\0'*padding_needed
@@ -3541,7 +3459,7 @@
hasher = hashlib.sha256()
hasher.update(usage)
signed_data.extend(hasher.digest())
- if subject_key_version is None:
+ if not subject_key_version:
subject_key_version = int(time.time())
signed_data.extend(struct.pack('<Q', subject_key_version))
signature = bytearray()
@@ -4093,9 +4011,6 @@
sub_parser.add_argument('--setup_as_rootfs_from_kernel',
action='store_true',
help='Adds kernel cmdline for setting up rootfs')
- sub_parser.add_argument('--no_hashtree',
- action='store_true',
- help='Do not append hashtree')
self._add_common_args(sub_parser)
self._add_common_footer_args(sub_parser)
sub_parser.set_defaults(func=self.add_hashtree_footer)
@@ -4111,14 +4026,6 @@
action='store_true')
sub_parser.set_defaults(func=self.erase_footer)
- sub_parser = subparsers.add_parser('zero_hashtree',
- help='Zero out hashtree and FEC data.')
- sub_parser.add_argument('--image',
- help='Image with a footer',
- type=argparse.FileType('rwb+'),
- required=True)
- sub_parser.set_defaults(func=self.zero_hashtree)
-
sub_parser = subparsers.add_parser('extract_vbmeta_image',
help='Extracts vbmeta from an image with a footer.')
sub_parser.add_argument('--image',
@@ -4179,9 +4086,6 @@
help=('Follows chain partitions even when not '
'specified with the --expected_chain_partition option'),
action='store_true')
- sub_parser.add_argument('--accept_zeroed_hashtree',
- help=('Accept images where the hashtree or FEC data is zeroed out'),
- action='store_true')
sub_parser.set_defaults(func=self.verify_image)
sub_parser = subparsers.add_parser(
@@ -4437,17 +4341,12 @@
args.do_not_append_vbmeta_image,
args.print_required_libavb_version,
args.use_persistent_digest,
- args.do_not_use_ab,
- args.no_hashtree)
+ args.do_not_use_ab)
def erase_footer(self, args):
"""Implements the 'erase_footer' sub-command."""
self.avb.erase_footer(args.image.name, args.keep_hashtree)
- def zero_hashtree(self, args):
- """Implements the 'zero_hashtree' sub-command."""
- self.avb.zero_hashtree(args.image.name)
-
def extract_vbmeta_image(self, args):
"""Implements the 'extract_vbmeta_image' sub-command."""
self.avb.extract_vbmeta_image(args.output, args.image.name,
@@ -4469,8 +4368,7 @@
"""Implements the 'verify_image' sub-command."""
self.avb.verify_image(args.image.name, args.key,
args.expected_chain_partition,
- args.follow_chain_partitions,
- args.accept_zeroed_hashtree)
+ args.follow_chain_partitions)
def calculate_vbmeta_digest(self, args):
"""Implements the 'calculate_vbmeta_digest' sub-command."""
diff --git a/libavb/avb_cmdline.c b/libavb/avb_cmdline.c
index f87e18c..bf10865 100644
--- a/libavb/avb_cmdline.c
+++ b/libavb/avb_cmdline.c
@@ -97,15 +97,7 @@
}
}
- /* It's possible there is no _PARTUUID for replacement above.
- * Duplicate cmdline to ret for additional substitutions below.
- */
- if (ret == NULL) {
- ret = avb_strdup(cmdline);
- if (ret == NULL) {
- goto fail;
- }
- }
+ avb_assert(ret != NULL);
/* Replace any additional substitutions. */
if (additional_substitutions != NULL) {
@@ -233,7 +225,6 @@
AvbSlotVerifyResult avb_append_options(
AvbOps* ops,
- AvbSlotVerifyFlags flags,
AvbSlotVerifyData* slot_data,
AvbVBMetaImageHeader* toplevel_vbmeta,
AvbAlgorithmType algorithm_type,
@@ -244,16 +235,12 @@
bool is_device_unlocked;
AvbIOResult io_ret;
- /* Add androidboot.vbmeta.device option... except if not using a vbmeta
- * partition since it doesn't make sense in that case.
- */
- if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) {
- if (!cmdline_append_option(slot_data,
- "androidboot.vbmeta.device",
- "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) {
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
- goto out;
- }
+ /* Add androidboot.vbmeta.device option. */
+ if (!cmdline_append_option(slot_data,
+ "androidboot.vbmeta.device",
+ "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+ goto out;
}
/* Add androidboot.vbmeta.avb_version option. */
diff --git a/libavb/avb_cmdline.h b/libavb/avb_cmdline.h
index 377783f..e1f5b1b 100644
--- a/libavb/avb_cmdline.h
+++ b/libavb/avb_cmdline.h
@@ -62,7 +62,6 @@
AvbSlotVerifyResult avb_append_options(
AvbOps* ops,
- AvbSlotVerifyFlags flags,
AvbSlotVerifyData* slot_data,
AvbVBMetaImageHeader* toplevel_vbmeta,
AvbAlgorithmType algorithm_type,
diff --git a/libavb/avb_descriptor.c b/libavb/avb_descriptor.c
index cfc2aac..4f8e925 100644
--- a/libavb/avb_descriptor.c
+++ b/libavb/avb_descriptor.c
@@ -91,11 +91,7 @@
const AvbDescriptor* dh = (const AvbDescriptor*)p;
avb_assert_aligned(dh);
uint64_t nb_following = avb_be64toh(dh->num_bytes_following);
- uint64_t nb_total = 0;
- if (!avb_safe_add(&nb_total, sizeof(AvbDescriptor), nb_following)) {
- avb_error("Invalid descriptor length.\n");
- goto out;
- }
+ uint64_t nb_total = sizeof(AvbDescriptor) + nb_following;
if ((nb_total & 7) != 0) {
avb_error("Invalid descriptor length.\n");
@@ -111,10 +107,7 @@
goto out;
}
- if (!avb_safe_add_to((uint64_t*)(&p), nb_total)) {
- avb_error("Invalid descriptor length.\n");
- goto out;
- }
+ p += nb_total;
}
ret = true;
diff --git a/libavb/avb_ops.h b/libavb/avb_ops.h
index dec163d..7f86386 100644
--- a/libavb/avb_ops.h
+++ b/libavb/avb_ops.h
@@ -191,10 +191,6 @@
*
* If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set -
* true if trusted or false if untrusted.
- *
- * NOTE: If AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is passed to
- * avb_slot_verify() then this operation is never used. Instead, the
- * validate_public_key_for_partition() operation is used
*/
AvbIOResult (*validate_vbmeta_public_key)(AvbOps* ops,
const uint8_t* public_key_data,
@@ -312,25 +308,6 @@
const char* name,
size_t value_size,
const uint8_t* value);
-
- /* Like validate_vbmeta_public_key() but for when the flag
- * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is being used. The name of the
- * partition to get the public key for is passed in |partition_name|.
- *
- * Also returns the rollback index location to use for the partition, in
- * |out_rollback_index_location|.
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- */
- AvbIOResult (*validate_public_key_for_partition)(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted,
- uint32_t* out_rollback_index_location);
};
#ifdef __cplusplus
diff --git a/libavb/avb_slot_verify.c b/libavb/avb_slot_verify.c
index 0d75210..75b26d6 100644
--- a/libavb/avb_slot_verify.c
+++ b/libavb/avb_slot_verify.c
@@ -385,27 +385,19 @@
if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
goto out;
}
- // Although only one of the type might be used, we have to defined the
- // structure here so that they would live outside the 'if/else' scope to be
- // used later.
- AvbSHA256Ctx sha256_ctx;
- AvbSHA512Ctx sha512_ctx;
- size_t image_size_to_hash = hash_desc.image_size;
- // If we allow verification error and the whole partition is smaller than
- // image size in hash descriptor, we just hash the whole partition.
- if (image_size_to_hash > image_size) {
- image_size_to_hash = image_size;
- }
+
if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
+ AvbSHA256Ctx sha256_ctx;
avb_sha256_init(&sha256_ctx);
avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len);
- avb_sha256_update(&sha256_ctx, image_buf, image_size_to_hash);
+ avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size);
digest = avb_sha256_final(&sha256_ctx);
digest_len = AVB_SHA256_DIGEST_SIZE;
} else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
+ AvbSHA512Ctx sha512_ctx;
avb_sha512_init(&sha512_ctx);
avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len);
- avb_sha512_update(&sha512_ctx, image_buf, image_size_to_hash);
+ avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size);
digest = avb_sha512_final(&sha512_ctx);
digest_len = AVB_SHA512_DIGEST_SIZE;
} else {
@@ -558,7 +550,6 @@
AvbOps* ops,
const char* const* requested_partitions,
const char* ab_suffix,
- AvbSlotVerifyFlags flags,
bool allow_verification_error,
AvbVBMetaImageFlags toplevel_vbmeta_flags,
int rollback_index_location,
@@ -572,7 +563,7 @@
char full_partition_name[AVB_PART_NAME_MAX_SIZE];
AvbSlotVerifyResult ret;
AvbIOResult io_ret;
- uint64_t vbmeta_offset;
+ size_t vbmeta_offset;
size_t vbmeta_size;
uint8_t* vbmeta_buf = NULL;
size_t vbmeta_num_read;
@@ -585,7 +576,7 @@
size_t num_descriptors;
size_t n;
bool is_main_vbmeta;
- bool look_for_vbmeta_footer;
+ bool is_vbmeta_partition;
AvbVBMetaData* vbmeta_image_data = NULL;
ret = AVB_SLOT_VERIFY_RESULT_OK;
@@ -596,20 +587,8 @@
* rollback_index_location to determine whether we're the main
* vbmeta struct.
*/
- is_main_vbmeta = false;
- if (rollback_index_location == 0) {
- if ((flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) == 0) {
- is_main_vbmeta = true;
- }
- }
-
- /* Don't use footers for vbmeta partitions ('vbmeta' or
- * 'vbmeta_<partition_name>').
- */
- look_for_vbmeta_footer = true;
- if (avb_strncmp(partition_name, "vbmeta", avb_strlen("vbmeta")) == 0) {
- look_for_vbmeta_footer = false;
- }
+ is_main_vbmeta = (rollback_index_location == 0);
+ is_vbmeta_partition = (avb_strcmp(partition_name, "vbmeta") == 0);
if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) {
avb_error("Partition name is not valid UTF-8.\n");
@@ -637,7 +616,7 @@
*/
vbmeta_offset = 0;
vbmeta_size = VBMETA_MAX_SIZE;
- if (look_for_vbmeta_footer) {
+ if (!is_vbmeta_partition) {
uint8_t footer_buf[AVB_FOOTER_SIZE];
size_t footer_num_read;
AvbFooter footer;
@@ -705,14 +684,13 @@
* go try to get it from the boot partition instead.
*/
if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION &&
- !look_for_vbmeta_footer) {
+ is_vbmeta_partition) {
avb_debugv(full_partition_name,
": No such partition. Trying 'boot' instead.\n",
NULL);
ret = load_and_verify_vbmeta(ops,
requested_partitions,
ab_suffix,
- flags,
allow_verification_error,
0 /* toplevel_vbmeta_flags */,
0 /* rollback_index_location */,
@@ -790,8 +768,6 @@
}
}
- uint32_t rollback_index_location_to_use = rollback_index_location;
-
/* Check if key used to make signature matches what is expected. */
if (pk_data != NULL) {
if (expected_public_key != NULL) {
@@ -819,27 +795,9 @@
pk_metadata_len = vbmeta_header.public_key_metadata_size;
}
- // If we're not using a vbmeta partition, need to use another AvbOps...
- if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
- io_ret = ops->validate_public_key_for_partition(
- ops,
- full_partition_name,
- pk_data,
- pk_len,
- pk_metadata,
- pk_metadata_len,
- &key_is_trusted,
- &rollback_index_location_to_use);
- } else {
- avb_assert(is_main_vbmeta);
- io_ret = ops->validate_vbmeta_public_key(ops,
- pk_data,
- pk_len,
- pk_metadata,
- pk_metadata_len,
- &key_is_trusted);
- }
-
+ avb_assert(is_main_vbmeta);
+ io_ret = ops->validate_vbmeta_public_key(
+ ops, pk_data, pk_len, pk_metadata, pk_metadata_len, &key_is_trusted);
if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
@@ -864,7 +822,7 @@
/* Check rollback index. */
io_ret = ops->read_rollback_index(
- ops, rollback_index_location_to_use, &stored_rollback_index);
+ ops, rollback_index_location, &stored_rollback_index);
if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
@@ -890,9 +848,7 @@
if (is_main_vbmeta) {
avb_assert(slot_data->num_vbmeta_images == 0);
} else {
- if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) {
- avb_assert(slot_data->num_vbmeta_images > 0);
- }
+ avb_assert(slot_data->num_vbmeta_images > 0);
}
if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) {
avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL);
@@ -1016,7 +972,6 @@
load_and_verify_vbmeta(ops,
requested_partitions,
ab_suffix,
- flags,
allow_verification_error,
toplevel_vbmeta_flags,
chain_desc.rollback_index_location,
@@ -1205,8 +1160,7 @@
}
}
- if (rollback_index_location < 0 ||
- rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
+ if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
avb_errorv(
full_partition_name, ": Invalid rollback_index_location.\n", NULL);
ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
@@ -1378,6 +1332,7 @@
avb_assert(ops->read_is_device_unlocked != NULL);
avb_assert(ops->read_from_partition != NULL);
avb_assert(ops->get_size_of_partition != NULL);
+ avb_assert(ops->validate_vbmeta_public_key != NULL);
avb_assert(ops->read_rollback_index != NULL);
avb_assert(ops->get_unique_guid_for_partition != NULL);
@@ -1410,21 +1365,6 @@
}
}
- /* Make sure passed-in AvbOps support verifying public keys and getting
- * rollback index location if not using a vbmeta partition.
- */
- if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
- if (ops->validate_public_key_for_partition == NULL) {
- avb_error(
- "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION was passed but the "
- "validate_public_key_for_partition() operation isn't implemented.\n");
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
- goto fail;
- }
- } else {
- avb_assert(ops->validate_vbmeta_public_key != NULL);
- }
-
slot_data = avb_calloc(sizeof(AvbSlotVerifyData));
if (slot_data == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
@@ -1449,161 +1389,122 @@
goto fail;
}
- if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
- if (requested_partitions == NULL || requested_partitions[0] == NULL) {
- avb_fatal(
- "Requested partitions cannot be empty when using "
- "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION");
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
- goto fail;
- }
-
- /* No vbmeta partition, go through each of the requested partitions... */
- for (size_t n = 0; requested_partitions[n] != NULL; n++) {
- ret = load_and_verify_vbmeta(ops,
- requested_partitions,
- ab_suffix,
- flags,
- allow_verification_error,
- 0 /* toplevel_vbmeta_flags */,
- 0 /* rollback_index_location */,
- requested_partitions[n],
- avb_strlen(requested_partitions[n]),
- NULL /* expected_public_key */,
- 0 /* expected_public_key_length */,
- slot_data,
- &algorithm_type,
- additional_cmdline_subst);
- if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
- goto fail;
- }
- }
-
- } else {
- /* Usual path, load "vbmeta"... */
- ret = load_and_verify_vbmeta(ops,
- requested_partitions,
- ab_suffix,
- flags,
- allow_verification_error,
- 0 /* toplevel_vbmeta_flags */,
- 0 /* rollback_index_location */,
- "vbmeta",
- avb_strlen("vbmeta"),
- NULL /* expected_public_key */,
- 0 /* expected_public_key_length */,
- slot_data,
- &algorithm_type,
- additional_cmdline_subst);
- if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
- goto fail;
- }
- }
-
- if (!result_should_continue(ret)) {
+ ret = load_and_verify_vbmeta(ops,
+ requested_partitions,
+ ab_suffix,
+ allow_verification_error,
+ 0 /* toplevel_vbmeta_flags */,
+ 0 /* rollback_index_location */,
+ "vbmeta",
+ avb_strlen("vbmeta"),
+ NULL /* expected_public_key */,
+ 0 /* expected_public_key_length */,
+ slot_data,
+ &algorithm_type,
+ additional_cmdline_subst);
+ if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
goto fail;
}
/* If things check out, mangle the kernel command-line as needed. */
- if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) {
+ if (result_should_continue(ret)) {
if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
avb_assert(
avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0);
using_boot_for_vbmeta = true;
}
- }
- /* Byteswap top-level vbmeta header since we'll need it below. */
- avb_vbmeta_image_header_to_host_byte_order(
- (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
- &toplevel_vbmeta);
+ /* Byteswap top-level vbmeta header since we'll need it below. */
+ avb_vbmeta_image_header_to_host_byte_order(
+ (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
+ &toplevel_vbmeta);
- /* Fill in |ab_suffix| field. */
- slot_data->ab_suffix = avb_strdup(ab_suffix);
- if (slot_data->ab_suffix == NULL) {
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
- goto fail;
- }
-
- /* If verification is disabled, we are done ... we specifically
- * don't want to add any androidboot.* options since verification
- * is disabled.
- */
- if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
- /* Since verification is disabled we didn't process any
- * descriptors and thus there's no cmdline... so set root= such
- * that the system partition is mounted.
- */
- avb_assert(slot_data->cmdline == NULL);
- // Devices with dynamic partitions won't have system partition.
- // Instead, it has a large super partition to accommodate *.img files.
- // See b/119551429 for details.
- if (has_system_partition(ops, ab_suffix)) {
- slot_data->cmdline =
- avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
- } else {
- // The |cmdline| field should be a NUL-terminated string.
- slot_data->cmdline = avb_strdup("");
- }
- if (slot_data->cmdline == NULL) {
+ /* Fill in |ab_suffix| field. */
+ slot_data->ab_suffix = avb_strdup(ab_suffix);
+ if (slot_data->ab_suffix == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto fail;
}
- } else {
- /* If requested, manage dm-verity mode... */
- AvbHashtreeErrorMode resolved_hashtree_error_mode = hashtree_error_mode;
- if (hashtree_error_mode ==
- AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) {
- AvbIOResult io_ret;
- io_ret = avb_manage_hashtree_error_mode(
- ops, flags, slot_data, &resolved_hashtree_error_mode);
- if (io_ret != AVB_IO_RESULT_OK) {
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
- if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
- ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
- }
- goto fail;
+
+ /* If verification is disabled, we are done ... we specifically
+ * don't want to add any androidboot.* options since verification
+ * is disabled.
+ */
+ if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
+ /* Since verification is disabled we didn't process any
+ * descriptors and thus there's no cmdline... so set root= such
+ * that the system partition is mounted.
+ */
+ avb_assert(slot_data->cmdline == NULL);
+ // Devices with dynamic partitions won't have system partition.
+ // Instead, it has a large super partition to accommodate *.img files.
+ // See b/119551429 for details.
+ if (has_system_partition(ops, ab_suffix)) {
+ slot_data->cmdline =
+ avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
+ } else {
+ // The |cmdline| field should be a NUL-terminated string.
+ slot_data->cmdline = avb_strdup("");
}
- }
- slot_data->resolved_hashtree_error_mode = resolved_hashtree_error_mode;
-
- /* Add options... */
- AvbSlotVerifyResult sub_ret;
- sub_ret = avb_append_options(ops,
- flags,
- slot_data,
- &toplevel_vbmeta,
- algorithm_type,
- hashtree_error_mode,
- resolved_hashtree_error_mode);
- if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
- ret = sub_ret;
- goto fail;
- }
- }
-
- /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */
- if (slot_data->cmdline != NULL && avb_strlen(slot_data->cmdline) != 0) {
- char* new_cmdline;
- new_cmdline = avb_sub_cmdline(ops,
- slot_data->cmdline,
- ab_suffix,
- using_boot_for_vbmeta,
- additional_cmdline_subst);
- if (new_cmdline != slot_data->cmdline) {
- if (new_cmdline == NULL) {
+ if (slot_data->cmdline == NULL) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto fail;
}
- avb_free(slot_data->cmdline);
- slot_data->cmdline = new_cmdline;
- }
- }
+ } else {
+ /* If requested, manage dm-verity mode... */
+ AvbHashtreeErrorMode resolved_hashtree_error_mode = hashtree_error_mode;
+ if (hashtree_error_mode ==
+ AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) {
+ AvbIOResult io_ret;
+ io_ret = avb_manage_hashtree_error_mode(
+ ops, flags, slot_data, &resolved_hashtree_error_mode);
+ if (io_ret != AVB_IO_RESULT_OK) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+ if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+ }
+ goto fail;
+ }
+ }
+ slot_data->resolved_hashtree_error_mode = resolved_hashtree_error_mode;
- if (out_data != NULL) {
- *out_data = slot_data;
- } else {
- avb_slot_verify_data_free(slot_data);
+ /* Add options... */
+ AvbSlotVerifyResult sub_ret;
+ sub_ret = avb_append_options(ops,
+ slot_data,
+ &toplevel_vbmeta,
+ algorithm_type,
+ hashtree_error_mode,
+ resolved_hashtree_error_mode);
+ if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
+ ret = sub_ret;
+ goto fail;
+ }
+ }
+
+ /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */
+ if (slot_data->cmdline != NULL && avb_strlen(slot_data->cmdline) != 0) {
+ char* new_cmdline;
+ new_cmdline = avb_sub_cmdline(ops,
+ slot_data->cmdline,
+ ab_suffix,
+ using_boot_for_vbmeta,
+ additional_cmdline_subst);
+ if (new_cmdline != slot_data->cmdline) {
+ if (new_cmdline == NULL) {
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+ goto fail;
+ }
+ avb_free(slot_data->cmdline);
+ slot_data->cmdline = new_cmdline;
+ }
+ }
+
+ if (out_data != NULL) {
+ *out_data = slot_data;
+ } else {
+ avb_slot_verify_data_free(slot_data);
+ }
}
avb_free_cmdline_subst_list(additional_cmdline_subst);
diff --git a/libavb/avb_slot_verify.h b/libavb/avb_slot_verify.h
index a2c98f4..d42d64c 100644
--- a/libavb/avb_slot_verify.h
+++ b/libavb/avb_slot_verify.h
@@ -117,21 +117,11 @@
* should be set if using AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO
* and the reason the boot loader is running is because the device
* was restarted by the dm-verity driver.
- *
- * If the AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION flag is set then
- * data won't be loaded from the "vbmeta" partition and the
- * |validate_vbmeta_public_key| operation is never called. Instead, the
- * vbmeta structs in |requested_partitions| are loaded and processed and the
- * |validate_public_key_for_partition| operation is called for each of these
- * vbmeta structs. This flag is useful when booting into recovery on a device
- * not using A/B - see section "Booting into recovery" in README.md for
- * more information.
*/
typedef enum {
AVB_SLOT_VERIFY_FLAGS_NONE = 0,
AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR = (1 << 0),
- AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION = (1 << 1),
- AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION = (1 << 2),
+ AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION = (1 << 1)
} AvbSlotVerifyFlags;
/* Get a textual representation of |result|. */
@@ -255,9 +245,7 @@
* PARTUUID=$(ANDROID_VBMETA_PARTUUID) before substitution so it
* will end up pointing to the vbmeta partition for the verified
* slot. If there is no vbmeta partition it will point to the boot
- * partition of the verified slot. If the flag
- * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is used, this is not
- * set.
+ * partition of the verified slot.
*
* androidboot.vbmeta.avb_version: This is set to the decimal value
* of AVB_VERSION_MAJOR followed by a dot followed by the decimal
diff --git a/libavb/avb_sysdeps.h b/libavb/avb_sysdeps.h
index e511a8a..e1f2ebc 100644
--- a/libavb/avb_sysdeps.h
+++ b/libavb/avb_sysdeps.h
@@ -75,14 +75,6 @@
*/
int avb_strcmp(const char* s1, const char* s2);
-/* Compare |n| bytes in two strings.
- *
- * Return an integer less than, equal to, or greater than zero if the
- * first |n| bytes of |s1| is found, respectively, to be less than,
- * to match, or be greater than the first |n| bytes of |s2|.
- */
-int avb_strncmp(const char* s1, const char* s2, size_t n);
-
/* Copy |n| bytes from |src| to |dest|. */
void* avb_memcpy(void* dest, const void* src, size_t n);
diff --git a/libavb/avb_sysdeps_posix.c b/libavb/avb_sysdeps_posix.c
index e26c3ef..0cbabee 100644
--- a/libavb/avb_sysdeps_posix.c
+++ b/libavb/avb_sysdeps_posix.c
@@ -46,10 +46,6 @@
return strcmp(s1, s2);
}
-int avb_strncmp(const char* s1, const char* s2, size_t n) {
- return strncmp(s1, s2, n);
-}
-
size_t avb_strlen(const char* str) {
return strlen(str);
}
diff --git a/test/Android.bp b/test/Android.bp
index 057cd1e..e3c2f31 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -39,4 +39,5 @@
},
},
test_config: "at_auth_unlock_unittest.xml",
+ test_suites: ["general-tests"],
}
diff --git a/test/avb_slot_verify_unittest.cc b/test/avb_slot_verify_unittest.cc
index 28ec151..e03c37e 100644
--- a/test/avb_slot_verify_unittest.cc
+++ b/test/avb_slot_verify_unittest.cc
@@ -478,74 +478,6 @@
avb_slot_verify_data_free(slot_data);
}
-TEST_F(AvbSlotVerifyTest, LoadSmallerPartitionIfAllowingVerificationError) {
- const size_t boot_partition_size = 16 * 1024 * 1024;
- const size_t boot_image_size = 5 * 1024 * 1024;
- const size_t new_boot_image_size = 1 * 1024 * 1024;
- base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
-
- // If we're allowing verification errors then check that the whole
- // partition is loaded. This is needed because in this mode for
- // example the "boot" partition might be flashed with another
- // boot.img that is larger than what the HashDescriptor in vbmeta
- // says.
- EXPECT_COMMAND(
- 0,
- "./avbtool add_hash_footer"
- " --image %s"
- " --rollback_index 0"
- " --partition_name boot"
- " --partition_size %zd"
- " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
- " --salt deadbeef"
- " --internal_release_string \"\"",
- boot_path.value().c_str(),
- boot_partition_size);
-
- GenerateVBMetaImage(
- "vbmeta_a.img",
- "SHA256_RSA2048",
- 4,
- base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf(
- "--include_descriptors_from_image %s"
- " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
- " --internal_release_string \"\"",
- boot_path.value().c_str()));
-
- // Now replace the boot partition with something bigger and
- // different. Because FakeOps's get_size_of_partition() operation
- // just returns the file size it means that this is what is returned
- // by get_size_of_partition().
- //
- // Also make sure this image will return a different digest by using
- // a non-standard starting byte. This is to force avb_slot_verify()
- // to return ERROR_VERIFICATION below.
- GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
-
- ops_.set_expected_public_key(
- PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
-
- AvbSlotVerifyData* slot_data = NULL;
- const char* requested_partitions[] = {"boot", NULL};
- EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
- avb_slot_verify(ops_.avb_ops(),
- requested_partitions,
- "_a",
- AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
- AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
- &slot_data));
- EXPECT_NE(nullptr, slot_data);
-
- // Check that the loaded partition is actually
- // |new_boot_image_size|.
- EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
- EXPECT_EQ("boot",
- std::string(slot_data->loaded_partitions[0].partition_name));
- EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
- avb_slot_verify_data_free(slot_data);
-}
-
TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
const size_t boot_partition_size = 16 * 1024 * 1024;
const size_t boot_image_size = 5 * 1024 * 1024;
@@ -1728,115 +1660,6 @@
EXPECT_TRUE(partitions.find("bar_a") == partitions.end());
}
-TEST_F(AvbSlotVerifyTest, NoVBMetaPartitionFlag) {
- const size_t foo_partition_size = 16 * 1024 * 1024;
- const size_t bar_partition_size = 32 * 1024 * 1024;
- const size_t foo_image_size = 5 * 1024 * 1024;
- const size_t bar_image_size = 10 * 1024 * 1024;
- base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
- base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
-
- EXPECT_COMMAND(0,
- "./avbtool add_hash_footer"
- " --image %s"
- " --kernel_cmdline 'this is=5 from foo=42'"
- " --partition_name foo"
- " --partition_size %zd"
- " --salt deadbeef"
- " --internal_release_string \"\""
- " --algorithm SHA256_RSA4096"
- " --salt deadbeef"
- " --key test/data/testkey_rsa4096.pem"
- " --rollback_index 42",
- foo_path.value().c_str(),
- foo_partition_size);
-
- EXPECT_COMMAND(0,
- "./avbtool add_hash_footer"
- " --image %s"
- " --kernel_cmdline 'and=43 from bar'"
- " --partition_name bar"
- " --partition_size %zd"
- " --salt deadbeef"
- " --internal_release_string \"\""
- " --algorithm SHA256_RSA2048"
- " --salt deadbeef"
- " --key test/data/testkey_rsa2048.pem"
- " --rollback_index 43",
- bar_path.value().c_str(),
- bar_partition_size);
-
- ops_.set_expected_public_key_for_partition(
- "foo_a",
- PublicKeyAVB(base::FilePath("test/data/testkey_rsa4096.pem")),
- 1);
- ops_.set_expected_public_key_for_partition(
- "bar_a",
- PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")),
- 2);
- ops_.set_stored_rollback_indexes({{0, 1000}, {1, 10}, {2, 11}});
- AvbSlotVerifyData* slot_data = NULL;
- const char* requested_partitions[] = {"foo", "bar", NULL};
-
- // Without AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION, this should fail because
- // vbmeta_a (or boot_a) cannot not be found.
- EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
- avb_slot_verify(ops_.avb_ops(),
- requested_partitions,
- "_a",
- AVB_SLOT_VERIFY_FLAGS_NONE,
- AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
- &slot_data));
-
- // However, with this flag it should succeed (note that rollback indexes in
- // the images exceed the stored rollback indexes)
- EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
- avb_slot_verify(ops_.avb_ops(),
- requested_partitions,
- "_a",
- AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
- AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
- &slot_data));
- EXPECT_NE(nullptr, slot_data);
- EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
- EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
- EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[1].partition_name));
- // Note the absence of 'androidboot.vbmeta.device'
- EXPECT_EQ(
- "this is=5 from foo=42 and=43 from bar "
- "androidboot.vbmeta.avb_version=1.1 "
- "androidboot.vbmeta.device_state=locked "
- "androidboot.vbmeta.hash_alg=sha256 "
- "androidboot.vbmeta.size=3456 "
- "androidboot.vbmeta.digest="
- "b5dbfb1743073f9a4cb45f94d1d849f89ca9777d158a2a06d09517c79ffd86cd "
- "androidboot.vbmeta.invalidate_on_error=yes "
- "androidboot.veritymode=enforcing",
- std::string(slot_data->cmdline));
- avb_slot_verify_data_free(slot_data);
-
- // Check that rollback protection works if we increase the stored rollback
- // indexes to exceed that of the image... do a check for each location.
- ops_.set_stored_rollback_indexes({{0, 1000}, {1, 10}, {2, 100}});
- EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
- avb_slot_verify(ops_.avb_ops(),
- requested_partitions,
- "_a",
- AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
- AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
- &slot_data));
- EXPECT_EQ(nullptr, slot_data);
- ops_.set_stored_rollback_indexes({{0, 1000}, {1, 100}, {2, 10}});
- EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
- avb_slot_verify(ops_.avb_ops(),
- requested_partitions,
- "_a",
- AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
- AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
- &slot_data));
- EXPECT_EQ(nullptr, slot_data);
-}
-
TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
base::FilePath md_path = GenerateImage("md.bin", 1536);
diff --git a/test/avb_sysdeps_posix_testing.cc b/test/avb_sysdeps_posix_testing.cc
index 0a6ac13..ee1cb97 100644
--- a/test/avb_sysdeps_posix_testing.cc
+++ b/test/avb_sysdeps_posix_testing.cc
@@ -50,10 +50,6 @@
return strcmp(s1, s2);
}
-int avb_strncmp(const char* s1, const char* s2, size_t n) {
- return strncmp(s1, s2, n);
-}
-
size_t avb_strlen(const char* str) {
return strlen(str);
}
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index 42f6f4d..1dfdf86 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -1003,15 +1003,6 @@
extracted_vbmeta_path.value().c_str());
}
- /* Zero the hashtree on a copy of the image. */
- EXPECT_COMMAND(0,
- "cp %s %s.zht",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0,
- "./avbtool zero_hashtree --image %s.zht ",
- rootfs_path.value().c_str());
-
if (sparse_image) {
EXPECT_COMMAND(0,
"mv %s %s.sparse",
@@ -1022,16 +1013,6 @@
rootfs_path.value().c_str(),
rootfs_path.value().c_str());
EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
-
- EXPECT_COMMAND(0,
- "mv %s.zht %s.zht.sparse",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0,
- "simg2img %s.zht.sparse %s.zht",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0, "rm -f %s.zht.sparse", rootfs_path.value().c_str());
}
// To check that we generate the correct hashtree we can use
@@ -1057,11 +1038,6 @@
std::string part_data;
ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
- // Also read the zeroed hash-tree version.
- std::string zht_part_data;
- ASSERT_TRUE(base::ReadFileToString(
- base::FilePath(rootfs_path.value() + ".zht"), &zht_part_data));
-
// Check footer contains correct data.
AvbFooter f;
EXPECT_NE(0,
@@ -1119,33 +1095,6 @@
EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
mem_to_hexstring(desc_end + o, d.root_digest_len));
- // Check that the zeroed hashtree version differ only by the hashtree + fec
- // being zeroed out.
- EXPECT_EQ(part_data.size(), zht_part_data.size());
- size_t zht_ht_begin = d.tree_offset;
- size_t zht_ht_end = zht_ht_begin + d.tree_size;
- size_t zht_fec_begin = zht_ht_end;
- size_t zht_fec_end = zht_fec_begin + d.fec_size;
- EXPECT_EQ(0, memcmp(part_data.data(), zht_part_data.data(), zht_ht_begin));
- EXPECT_NE(0,
- memcmp(part_data.data() + zht_ht_begin,
- zht_part_data.data() + zht_ht_begin,
- zht_fec_end - zht_ht_begin));
- EXPECT_EQ(0,
- memcmp(part_data.data() + zht_fec_end,
- zht_part_data.data() + zht_fec_end,
- zht_part_data.size() - zht_fec_end));
- EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_ht_begin, "ZeRoHaSH", 8));
- for (size_t n = zht_ht_begin + 8; n < zht_ht_end; n++) {
- EXPECT_EQ(0, zht_part_data.data()[n]);
- }
- if (d.fec_size > 0) {
- EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_fec_begin, "ZeRoHaSH", 8));
- for (size_t n = zht_fec_begin + 8; n < zht_fec_end; n++) {
- EXPECT_EQ(0, zht_part_data.data()[n]);
- }
- }
-
// Check that we correctly generate dm-verity kernel cmdline
// snippets, if requested.
base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
@@ -1298,15 +1247,6 @@
InfoImage(rootfs_path));
}
- /* Zero the hashtree and FEC on a copy of the image. */
- EXPECT_COMMAND(0,
- "cp %s %s.zht",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0,
- "./avbtool zero_hashtree --image %s.zht ",
- rootfs_path.value().c_str());
-
if (sparse_image) {
EXPECT_COMMAND(0,
"mv %s %s.sparse",
@@ -1317,16 +1257,6 @@
rootfs_path.value().c_str(),
rootfs_path.value().c_str());
EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
-
- EXPECT_COMMAND(0,
- "mv %s.zht %s.zht.sparse",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0,
- "simg2img %s.zht.sparse %s.zht",
- rootfs_path.value().c_str(),
- rootfs_path.value().c_str());
- EXPECT_COMMAND(0, "rm -f %s.zht.sparse", rootfs_path.value().c_str());
}
/* TODO: would be nice to verify that the FEC data is correct. */
@@ -1335,11 +1265,6 @@
std::string part_data;
ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
- // Also read the zeroed hash-tree version.
- std::string zht_part_data;
- ASSERT_TRUE(base::ReadFileToString(
- base::FilePath(rootfs_path.value() + ".zht"), &zht_part_data));
-
// Check footer contains correct data.
AvbFooter f;
EXPECT_NE(0,
@@ -1399,33 +1324,6 @@
EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
mem_to_hexstring(desc_end + o, d.root_digest_len));
- // Check that the zeroed hashtree version differ only by the hashtree + fec
- // being zeroed out.
- EXPECT_EQ(part_data.size(), zht_part_data.size());
- size_t zht_ht_begin = d.tree_offset;
- size_t zht_ht_end = zht_ht_begin + d.tree_size;
- size_t zht_fec_begin = zht_ht_end;
- size_t zht_fec_end = zht_fec_begin + d.fec_size;
- EXPECT_EQ(0, memcmp(part_data.data(), zht_part_data.data(), zht_ht_begin));
- EXPECT_NE(0,
- memcmp(part_data.data() + zht_ht_begin,
- zht_part_data.data() + zht_ht_begin,
- zht_fec_end - zht_ht_begin));
- EXPECT_EQ(0,
- memcmp(part_data.data() + zht_fec_end,
- zht_part_data.data() + zht_fec_end,
- zht_part_data.size() - zht_fec_end));
- EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_ht_begin, "ZeRoHaSH", 8));
- for (size_t n = zht_ht_begin + 8; n < zht_ht_end; n++) {
- EXPECT_EQ(0, zht_part_data.data()[n]);
- }
- if (d.fec_size > 0) {
- EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_fec_begin, "ZeRoHaSH", 8));
- for (size_t n = zht_fec_begin + 8; n < zht_fec_end; n++) {
- EXPECT_EQ(0, zht_part_data.data()[n]);
- }
- }
-
// Check that we correctly generate dm-verity kernel cmdline
// snippets, if requested.
base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
@@ -1553,74 +1451,6 @@
partition_size);
}
-TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSizeWithNoHashtree) {
- const size_t partition_size = 10 * 1024 * 1024;
- base::FilePath output_path = testdir_.Append("max_size.txt");
-
- EXPECT_COMMAND(0,
- "./avbtool add_hashtree_footer "
- "--no_hashtree "
- "--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());
-
- // vbmeta(64) + footer(4) takes up 68 KiB
- EXPECT_EQ(68 * 1024ULL, partition_size - max_image_size);
-
- // Check that we can add a hashtree with an image this size for such
- // a partition size.
- base::FilePath system_path = GenerateImage("system", max_image_size);
- EXPECT_COMMAND(0,
- "./avbtool add_hashtree_footer"
- " --image %s"
- " --no_hashtree"
- " --partition_name system"
- " --partition_size %zd"
- " --salt deadbeef"
- " --algorithm SHA512_RSA4096 "
- " --key test/data/testkey_rsa4096.pem"
- " --internal_release_string \"\"",
- system_path.value().c_str(),
- partition_size);
- // with --no_hashtree, Tree/FEC sizes are 0 bytes
- ASSERT_EQ(
- "Footer version: 1.0\n"
- "Image size: 10485760 bytes\n"
- "Original image size: 10416128 bytes\n"
- "VBMeta offset: 10416128\n"
- "VBMeta size: 2112 bytes\n"
- "--\n"
- "Minimum libavb version: 1.0\n"
- "Header Block: 256 bytes\n"
- "Authentication Block: 576 bytes\n"
- "Auxiliary Block: 1280 bytes\n"
- "Algorithm: SHA512_RSA4096\n"
- "Rollback Index: 0\n"
- "Flags: 0\n"
- "Release String: ''\n"
- "Descriptors:\n"
- " Hashtree descriptor:\n"
- " Version of dm-verity: 1\n"
- " Image Size: 10416128 bytes\n"
- " Tree Offset: 10416128\n"
- " Tree Size: 0 bytes\n"
- " Data Block Size: 4096 bytes\n"
- " Hash Block Size: 4096 bytes\n"
- " FEC num roots: 2\n"
- " FEC offset: 10416128\n"
- " FEC size: 0 bytes\n"
- " Hash Algorithm: sha1\n"
- " Partition Name: system\n"
- " Salt: deadbeef\n"
- " Root Digest: 4215bd42bcc99636f42956ce3d2c7884d6a8093b\n"
- " Flags: 0\n",
- InfoImage(system_path));
-}
-
TEST_F(AvbToolTest, AddHashtreeFooterWithPersistentDigest) {
size_t partition_size = 10 * 1024 * 1024;
base::FilePath path = GenerateImage("digest_location", partition_size / 2);
@@ -2562,68 +2392,6 @@
}
}
-TEST_F(AvbToolTest, VerifyImageWithHashAndZeroedHashtree) {
- const size_t system_partition_size = 10 * 1024 * 1024;
- const size_t system_image_size = 8 * 1024 * 1024;
- base::FilePath system_path = GenerateImage("system.img", system_image_size);
- EXPECT_COMMAND(0,
- "./avbtool add_hashtree_footer --salt d00df00d --image %s "
- "--partition_size %zd --partition_name system "
- "--internal_release_string \"\" ",
- system_path.value().c_str(),
- system_partition_size);
-
- GenerateVBMetaImage("vbmeta.img",
- "SHA256_RSA2048",
- 0,
- base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--include_descriptors_from_image %s ",
- system_path.value().c_str()));
-
- EXPECT_COMMAND(0,
- "./avbtool verify_image --image %s --accept_zeroed_hashtree",
- vbmeta_image_path_.value().c_str());
-
- EXPECT_COMMAND(
- 0, "./avbtool zero_hashtree --image %s", system_path.value().c_str());
-
- EXPECT_COMMAND(1,
- "./avbtool verify_image --image %s",
- vbmeta_image_path_.value().c_str());
-
- EXPECT_COMMAND(0,
- "./avbtool verify_image --image %s --accept_zeroed_hashtree",
- vbmeta_image_path_.value().c_str());
-}
-
-TEST_F(AvbToolTest, VerifyImageWithNoHashtree) {
- const size_t system_partition_size = 10 * 1024 * 1024;
- const size_t system_image_size = 8 * 1024 * 1024;
- base::FilePath system_path = GenerateImage("system.img", system_image_size);
- EXPECT_COMMAND(0,
- "./avbtool add_hashtree_footer --salt d00df00d --image %s "
- "--partition_size %zd --partition_name system "
- "--no_hashtree "
- "--internal_release_string \"\" ",
- system_path.value().c_str(),
- system_partition_size);
-
- GenerateVBMetaImage("vbmeta.img",
- "SHA256_RSA2048",
- 0,
- base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--include_descriptors_from_image %s ",
- system_path.value().c_str()));
-
- EXPECT_COMMAND(1,
- "./avbtool verify_image --image %s",
- vbmeta_image_path_.value().c_str());
-
- EXPECT_COMMAND(0,
- "./avbtool verify_image --image %s --accept_zeroed_hashtree",
- vbmeta_image_path_.value().c_str());
-}
-
TEST_F(AvbToolTest, VerifyImageWithHashAndHashtreeCorruptHash) {
GenerateImageWithHashAndHashtreeSetup();
diff --git a/test/fake_avb_ops.cc b/test/fake_avb_ops.cc
index 6e8ab8c..2fdba10 100644
--- a/test/fake_avb_ops.cc
+++ b/test/fake_avb_ops.cc
@@ -262,30 +262,6 @@
return AVB_IO_RESULT_OK;
}
-AvbIOResult FakeAvbOps::validate_public_key_for_partition(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_key_is_trusted,
- uint32_t* out_rollback_index_location) {
- std::string expected_public_key =
- expected_public_key_for_partition_map_[partition];
- uint32_t rollback_index_location =
- rollback_index_location_for_partition_map_[partition];
- if (out_key_is_trusted != NULL) {
- bool pk_matches = (public_key_length == expected_public_key.size() &&
- (memcmp(expected_public_key.c_str(),
- public_key_data,
- public_key_length) == 0));
- *out_key_is_trusted = pk_matches;
- *out_rollback_index_location = rollback_index_location;
- }
- return AVB_IO_RESULT_OK;
-}
-
AvbIOResult FakeAvbOps::read_rollback_index(AvbOps* ops,
size_t rollback_index_location,
uint64_t* out_rollback_index) {
@@ -460,27 +436,6 @@
out_key_is_trusted);
}
-static AvbIOResult my_ops_validate_public_key_for_partition(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_key_is_trusted,
- uint32_t* out_rollback_index_location) {
- return FakeAvbOps::GetInstanceFromAvbOps(ops)
- ->delegate()
- ->validate_public_key_for_partition(ops,
- partition,
- public_key_data,
- public_key_length,
- public_key_metadata,
- public_key_metadata_length,
- out_key_is_trusted,
- out_rollback_index_location);
-}
-
static AvbIOResult my_ops_read_rollback_index(AvbOps* ops,
size_t rollback_index_location,
uint64_t* out_rollback_index) {
@@ -586,8 +541,6 @@
avb_ops_.get_size_of_partition = my_ops_get_size_of_partition;
avb_ops_.read_persistent_value = my_ops_read_persistent_value;
avb_ops_.write_persistent_value = my_ops_write_persistent_value;
- avb_ops_.validate_public_key_for_partition =
- my_ops_validate_public_key_for_partition;
// Just use the built-in A/B metadata read/write routines.
avb_ab_ops_.ops = &avb_ops_;
diff --git a/test/fake_avb_ops.h b/test/fake_avb_ops.h
index 2cc12d8..935dbf4 100644
--- a/test/fake_avb_ops.h
+++ b/test/fake_avb_ops.h
@@ -95,16 +95,6 @@
size_t value_size,
const uint8_t* value) = 0;
- virtual AvbIOResult validate_public_key_for_partition(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted,
- uint32_t* out_rollback_index_location) = 0;
-
virtual AvbIOResult read_permanent_attributes(
AvbAtxPermanentAttributes* attributes) = 0;
@@ -160,16 +150,6 @@
expected_public_key_ = expected_public_key;
}
- void set_expected_public_key_for_partition(
- const std::string& partition_name,
- const std::string& expected_public_key,
- uint32_t rollback_index_location) {
- expected_public_key_for_partition_map_[partition_name] =
- expected_public_key;
- rollback_index_location_for_partition_map_[partition_name] =
- rollback_index_location;
- }
-
void set_expected_public_key_metadata(
const std::string& expected_public_key_metadata) {
expected_public_key_metadata_ = expected_public_key_metadata;
@@ -268,16 +248,6 @@
size_t value_size,
const uint8_t* value) override;
- AvbIOResult validate_public_key_for_partition(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted,
- uint32_t* out_rollback_index_location) override;
-
AvbIOResult read_permanent_attributes(
AvbAtxPermanentAttributes* attributes) override;
@@ -301,10 +271,6 @@
std::string expected_public_key_;
std::string expected_public_key_metadata_;
- std::map<std::string, std::string> expected_public_key_for_partition_map_;
-
- std::map<std::string, uint32_t> rollback_index_location_for_partition_map_;
-
std::map<size_t, uint64_t> stored_rollback_indexes_;
std::map<size_t, uint64_t> verified_rollback_indexes_;
@@ -362,25 +328,6 @@
out_key_is_trusted);
}
- AvbIOResult validate_public_key_for_partition(
- AvbOps* ops,
- const char* partition,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_key_is_trusted,
- uint32_t* out_rollback_index_location) override {
- return ops_.validate_public_key_for_partition(ops,
- partition,
- public_key_data,
- public_key_length,
- public_key_metadata,
- public_key_metadata_length,
- out_key_is_trusted,
- out_rollback_index_location);
- }
-
AvbIOResult read_rollback_index(AvbOps* ops,
size_t rollback_index_slot,
uint64_t* out_rollback_index) override {
diff --git a/tools/at_auth_unlock.py b/tools/at_auth_unlock.py
index c7e6869..80b5bb6 100755
--- a/tools/at_auth_unlock.py
+++ b/tools/at_auth_unlock.py
@@ -38,10 +38,6 @@
of the provided credential archives for a match against the product ID of
the device being unlocked and automatically use the first match.
-This tool also clears the factory partition persistent digest unless the
---clear_factory_digest=false option is used. There is no harm to clear this
-digest even if changes to the factory partition are not planned.
-
Dependencies:
- Python 2.7.x, 3.2.x, or newer (for argparse)
- PyCrypto 2.5 or newer (for PKCS1_v1_5 and RSA PKCS#8 PEM key import)
@@ -53,7 +49,7 @@
fastboot, given valid unlock credentials for the device."""
HELP_USAGE = """
- %(prog)s [-h] [-v] [-s SERIAL] [--clear_factory_digest=true|false] unlock_creds.zip [unlock_creds_2.zip ...]
+ %(prog)s [-h] [-v] [-s SERIAL] unlock_creds.zip [unlock_creds_2.zip ...]
%(prog)s --pik_cert pik_cert.bin --puk_cert puk_cert.bin --puk puk.pem"""
HELP_EPILOG = """examples:
@@ -374,67 +370,6 @@
return creds
-def ClearFactoryPersistentDigest(serial=None, verbose=False):
- """Clears the factory partition persistent digest using fastboot.
-
- Most of the time this should be cleared when unlocking a device because
- otherwise any attempts to update the factory partition will be rejected once
- the device is again locked, causing confusion. There is no harm to clear this
- digest even if factory partition updates are not planned.
-
- Arguments:
- serial: [optional] A device serial number or other valid value to be passed
- to fastboot's '-s' switch to select the device to unlock.
- verbose: [optional] Enable verbose output, which prints the fastboot
- commands and their output as the commands are run.
- """
- FACTORY_PERSISTENT_DIGEST_NAME = 'avb.persistent_digest.factory'
-
- tempdir = tempfile.mkdtemp()
- try:
- digest_data = os.path.join(tempdir, 'digest_data')
-
- with open(digest_data, 'wb') as out:
- out.write(struct.pack('<I', len(FACTORY_PERSISTENT_DIGEST_NAME)))
- out.write(FACTORY_PERSISTENT_DIGEST_NAME)
- # Sending a zero length digest will clear the existing digest.
- out.write(struct.pack('<I', 0))
-
- def fastboot_cmd(args):
- args = ['fastboot'] + (['-s', serial] if serial else []) + args
- if verbose:
- print('$ ' + ' '.join(args))
-
- out = subprocess.check_output(
- args, stderr=subprocess.STDOUT).decode('utf-8')
-
- if verbose:
- print(out)
-
- try:
- fastboot_cmd(['stage', digest_data])
- fastboot_cmd(['oem', 'at-write-persistent-digest'])
- print("Successfully cleared the factory partition persistent digest.")
- return True
- except subprocess.CalledProcessError as e:
- print(e.output.decode('utf-8'))
- print("Command '{}' returned non-zero exit status {}".format(
- ' '.join(e.cmd), e.returncode))
- print("Warning: Failed to clear factory partition persistent digest.")
- return False
-
- finally:
- shutil.rmtree(tempdir)
-
-
-def parse_boolean(value):
- if value.strip().lower() in ('true', 't', 'yes', 'y', 'on', '1'):
- return True
- elif value.strip().lower() in ('false', 'f', 'no', 'n', 'off', '0'):
- return False
- else:
- raise argparse.ArgumentTypeError('Unexpected boolean value: %s' % value)
-
def main(in_args):
parser = argparse.ArgumentParser(
description=HELP_DESCRIPTION,
@@ -455,13 +390,6 @@
help=
"specify device to unlock, either by serial or any other valid value for fastboot's -s arg"
)
- parser.add_argument(
- '--clear_factory_digest',
- nargs='?',
- type=parse_boolean,
- default='true',
- const='true',
- help='Defaults to true. Set to false to prevent clearing the factory persistent digest')
# User must provide either a unlock credential bundle, or the individual files
# normally contained in such a bundle.
@@ -537,8 +465,6 @@
creds = [UnlockCredentials(args.pik_cert, args.puk_cert, args.puk)]
ret = AuthenticatedUnlock(creds, serial=args.serial, verbose=args.verbose)
- if ret and args.clear_factory_digest:
- ret = ClearFactoryPersistentDigest(serial=args.serial, verbose=args.verbose)
return 0 if ret else 1
diff --git a/tools/transparency/pixel_factory_image_verify.py b/tools/transparency/pixel_factory_image_verify.py
deleted file mode 100755
index 4479789..0000000
--- a/tools/transparency/pixel_factory_image_verify.py
+++ /dev/null
@@ -1,341 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2019, The Android Open Source Project
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation
-# files (the "Software"), to deal in the Software without
-# restriction, including without limitation the rights to use, copy,
-# modify, merge, publish, distribute, sublicense, and/or sell copies
-# of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-
-"""Tool for verifying VBMeta & calculate VBMeta Digests of Pixel factory images.
-
-If given an HTTPS URL it will download the file first before processing.
-$ pixel_factory_image_verify.py https://dl.google.com/dl/android/aosp/image.zip
-
-Otherwise, the argument is considered to be a local file.
-$ pixel_factory_image_verify.py image.zip
-
-The list of canonical Pixel factory images can be found here:
-https://developers.google.com/android/images
-
-Supported are all factory images of Pixel 3 and later devices.
-
-In order for the tool to run correct the following utilities need to be
-pre-installed: wget, unzip.
-
-The tool also runs outside of the repository location as long as the working
-directory is writable.
-"""
-
-from __future__ import print_function
-
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-import distutils.spawn
-
-
-class PixelFactoryImageVerifier(object):
- """Object for the pixel_factory_image_verify command line tool."""
-
- def __init__(self):
- self.working_dir = os.getcwd()
- self.script_path = os.path.realpath(__file__)
- self.script_dir = os.path.split(self.script_path)[0]
- self.avbtool_path = os.path.abspath(os.path.join(self.script_path,
- '../../../avbtool'))
-
- def run(self, argv):
- """Command line processor.
-
- Args:
- argv: The command line parameter list.
- """
- # Checks for command line parameters and show help if non given.
- if len(argv) != 2:
- print('No command line parameter given. At least a filename or URL for a '
- 'Pixel 3 or later factory image needs to be specified.')
- sys.exit(1)
-
- # Checks if necessary commands are available.
- for cmd in ['grep', 'unzip', 'wget']:
- if not distutils.spawn.find_executable(cmd):
- print('Necessary command line tool needs to be installed first: %s'
- % cmd)
- sys.exit(1)
-
- # Downloads factory image if URL is specified; otherwise treat it as file.
- if argv[1].lower().startswith('https://'):
- factory_image_zip = self._download_factory_image(argv[1])
- if not factory_image_zip:
- sys.exit(1)
- else:
- factory_image_zip = os.path.abspath(argv[1])
-
- # Unpacks the factory image into partition images.
- partition_image_dir = self._unpack_factory_image(factory_image_zip)
- if not partition_image_dir:
- sys.exit(1)
-
- # Validates the VBMeta of the factory image.
- verified = self._verify_vbmeta_partitions(partition_image_dir)
- if not verified:
- sys.exit(1)
-
- fingerprint = self._extract_build_fingerprint(partition_image_dir)
- if not fingerprint:
- sys.exit(1)
-
- # Calculates the VBMeta Digest for the factory image.
- vbmeta_digest = self._calculate_vbmeta_digest(partition_image_dir)
- if not vbmeta_digest:
- sys.exit(1)
-
- print('The build fingerprint for factory image is: %s' % fingerprint)
- print('The VBMeta Digest for factory image is: %s' % vbmeta_digest)
- sys.exit(0)
-
- def _download_factory_image(self, url):
- """Downloads the factory image to the working directory.
-
- Args:
- url: The download URL for the factory image.
-
- Returns:
- The absolute path to the factory image or None if it failed.
- """
- # Creates temporary download folder.
- download_path = tempfile.mkdtemp(dir=self.working_dir)
-
- # Downloads the factory image to the temporary folder.
- download_filename = self._download_file(download_path, url)
- if not download_filename:
- return None
-
- # Moves the downloaded file into the working directory.
- download_file = os.path.join(download_path, download_filename)
- target_file = os.path.join(self.working_dir, download_filename)
- if os.path.exists(target_file):
- try:
- os.remove(target_file)
- except OSError as e:
- print('File %s already exists and cannot be deleted.' % download_file)
- return None
- try:
- shutil.move(download_file, self.working_dir)
- except shutil.Error as e:
- print('File %s cannot be moved to %s: %s' % (download_file,
- target_file, e))
- return None
-
- # Removes temporary download folder.
- try:
- shutil.rmtree(download_path)
- except shutil.Error as e:
- print('Temporary download folder %s could not be removed.'
- % download_path)
- return os.path.join(self.working_dir, download_filename)
-
- def _download_file(self, download_dir, url):
- """Downloads a file from the Internet.
-
- Args:
- download_dir: The folder the file should be downloaded to.
- url: The download URL for the file.
-
- Returns:
- The name of the downloaded file as it apears on disk; otherwise None
- if download failed.
- """
- print('Fetching file from: %s' % url)
- os.chdir(download_dir)
- args = ['wget', url]
- result, _ = self._run_command(args,
- 'Successfully downloaded file.',
- 'File download failed.')
- os.chdir(self.working_dir)
- if not result:
- return None
-
- # Figure out the file name of what was downloaded: It will be the only file
- # in the download folder.
- files = os.listdir(download_dir)
- if files and len(files) == 1:
- return files[0]
- else:
- return None
-
- def _unpack_factory_image(self, factory_image_file):
- """Unpacks the factory image zip file.
-
- Args:
- factory_image_file: path and file name to the image file.
-
- Returns:
- The path to the folder which contains the unpacked factory image files or
- None if it failed.
- """
- unpack_dir = tempfile.mkdtemp(dir=self.working_dir)
- args = ['unzip', factory_image_file, '-d', unpack_dir]
- result, _ = self._run_command(args,
- 'Successfully unpacked factory image.',
- 'Failed to unpack factory image.')
- if not result:
- return None
-
- # Locate the directory which contains the image files.
- files = os.listdir(unpack_dir)
- image_name = None
- for f in files:
- path = os.path.join(self.working_dir, unpack_dir, f)
- if os.path.isdir(path):
- image_name = f
- break
- if not image_name:
- print('No image found: %s' % image_name)
- return None
-
- # Move image file directory to the working directory
- image_dir = os.path.join(unpack_dir, image_name)
- target_dir = os.path.join(self.working_dir, image_name)
- if os.path.exists(target_dir):
- try:
- shutil.rmtree(target_dir)
- except shutil.Error as e:
- print('Directory %s already exists and cannot be deleted.' % target_dir)
- return None
-
- try:
- shutil.move(image_dir, self.working_dir)
- except shutil.Error as e:
- print('Directory %s could not be moved to %s: %s' % (image_dir,
- self.working_dir, e))
- return None
-
- # Removes tmp unpack directory.
- try:
- shutil.rmtree(unpack_dir)
- except shutil.Error as e:
- print('Temporary download folder %s could not be removed.'
- % unpack_dir)
-
- # Unzip the secondary zip file which contain the individual images.
- image_filename = 'image-%s' % image_name
- image_folder = os.path.join(self.working_dir, image_name)
- os.chdir(image_folder)
-
- args = ['unzip', image_filename]
- result, _ = self._run_command(
- args,
- 'Successfully unpacked factory image partitions.',
- 'Failed to unpack factory image partitions.')
- if not result:
- return None
- return image_folder
-
- def _verify_vbmeta_partitions(self, image_dir):
- """Verifies all partitions protected by VBMeta using avbtool verify_image.
-
- Args:
- image_dir: The folder containing the unpacked factory image partitions,
- which contains a vbmeta.img patition.
-
- Returns:
- True if the VBMeta protected parititions verify.
- """
- os.chdir(image_dir)
- args = [self.avbtool_path,
- 'verify_image',
- '--image', 'vbmeta.img',
- '--follow_chain_partitions']
- result, _ = self._run_command(args,
- 'Successfully verified VBmeta.',
- 'Verification of VBmeta failed.')
- os.chdir(self.working_dir)
- return result
-
- def _extract_build_fingerprint(self, image_dir):
- """Extracts the build fingerprint from the system.img.
- Args:
- image_dir: The folder containing the unpacked factory image partitions,
- which contains a vbmeta.img patition.
-
- Returns:
- The build fingerprint string, e.g.
- google/blueline/blueline:9/PQ2A.190305.002/5240760:user/release-keys
- """
- os.chdir(image_dir)
- args = ['grep',
- '-a',
- 'ro\.build\.fingerprint=google/.*/release-keys',
- 'system.img']
-
- result, output = self._run_command(
- args,
- 'Successfully extracted build fingerpint.',
- 'Build fingerprint extraction failed.')
- os.chdir(self.working_dir)
- if result:
- _, fingerprint = output.split('=', 1)
- return fingerprint.rstrip()
- else:
- return None
-
- def _calculate_vbmeta_digest(self, image_dir):
- """Calculates the VBMeta Digest for given parititions using avbtool.
-
- Args:
- image_dir: The folder containing the unpacked factory image partitions,
- which contains a vbmeta.img partition.
-
- Returns:
- Hex string with the VBmeta Digest value or None if it failed.
- """
- os.chdir(image_dir)
- args = [self.avbtool_path,
- 'calculate_vbmeta_digest',
- '--image', 'vbmeta.img']
- result, output = self._run_command(args,
- 'Successfully calculated VBMeta Digest.',
- 'Failed to calculate VBmeta Digest.')
- os.chdir(self.working_dir)
- if result:
- return output
- else:
- return None
-
- def _run_command(self, args, success_msg, fail_msg):
- """Runs command line tools."""
- p = subprocess.Popen(args, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- pout, _ = p.communicate()
- if p.wait() == 0:
- print(success_msg)
- return True, pout
- else:
- print(fail_msg)
- return False, pout
-
-
-if __name__ == '__main__':
- tool = PixelFactoryImageVerifier()
- tool.run(sys.argv)
-