1*d289c2baSAndroid Build Coastguard Worker // Copyright 2023, The Android Open Source Project
2*d289c2baSAndroid Build Coastguard Worker //
3*d289c2baSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*d289c2baSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*d289c2baSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*d289c2baSAndroid Build Coastguard Worker //
7*d289c2baSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*d289c2baSAndroid Build Coastguard Worker //
9*d289c2baSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*d289c2baSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*d289c2baSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*d289c2baSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*d289c2baSAndroid Build Coastguard Worker // limitations under the License.
14*d289c2baSAndroid Build Coastguard Worker
15*d289c2baSAndroid Build Coastguard Worker //! libavb_rs verification tests.
16*d289c2baSAndroid Build Coastguard Worker
17*d289c2baSAndroid Build Coastguard Worker use crate::{
18*d289c2baSAndroid Build Coastguard Worker build_test_ops_one_image_one_vbmeta,
19*d289c2baSAndroid Build Coastguard Worker test_data::*,
20*d289c2baSAndroid Build Coastguard Worker test_ops::{FakeVbmetaKey, TestOps},
21*d289c2baSAndroid Build Coastguard Worker verify_one_image_one_vbmeta,
22*d289c2baSAndroid Build Coastguard Worker };
23*d289c2baSAndroid Build Coastguard Worker use avb::{
24*d289c2baSAndroid Build Coastguard Worker slot_verify, ChainPartitionDescriptor, ChainPartitionDescriptorFlags, Descriptor,
25*d289c2baSAndroid Build Coastguard Worker HashDescriptor, HashDescriptorFlags, HashtreeDescriptor, HashtreeDescriptorFlags,
26*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode, IoError, KernelCommandlineDescriptor, KernelCommandlineDescriptorFlags,
27*d289c2baSAndroid Build Coastguard Worker PropertyDescriptor, SlotVerifyData, SlotVerifyError, SlotVerifyFlags, SlotVerifyResult,
28*d289c2baSAndroid Build Coastguard Worker };
29*d289c2baSAndroid Build Coastguard Worker use hex::decode;
30*d289c2baSAndroid Build Coastguard Worker use std::{ffi::CString, fs};
31*d289c2baSAndroid Build Coastguard Worker #[cfg(feature = "uuid")]
32*d289c2baSAndroid Build Coastguard Worker use uuid::uuid;
33*d289c2baSAndroid Build Coastguard Worker
34*d289c2baSAndroid Build Coastguard Worker /// Initializes a `TestOps` object such that verification will succeed on `TEST_PARTITION_NAME` and
35*d289c2baSAndroid Build Coastguard Worker /// `TEST_PARTITION_2_NAME`.
build_test_ops_two_images_one_vbmeta<'a>() -> TestOps<'a>36*d289c2baSAndroid Build Coastguard Worker fn build_test_ops_two_images_one_vbmeta<'a>() -> TestOps<'a> {
37*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
38*d289c2baSAndroid Build Coastguard Worker // Add in the contents of the second partition and overwrite the vbmeta partition to
39*d289c2baSAndroid Build Coastguard Worker // include both partition descriptors.
40*d289c2baSAndroid Build Coastguard Worker ops.add_partition(TEST_PARTITION_2_NAME, fs::read(TEST_IMAGE_PATH).unwrap());
41*d289c2baSAndroid Build Coastguard Worker ops.add_partition("vbmeta", fs::read(TEST_VBMETA_2_PARTITIONS_PATH).unwrap());
42*d289c2baSAndroid Build Coastguard Worker ops
43*d289c2baSAndroid Build Coastguard Worker }
44*d289c2baSAndroid Build Coastguard Worker
45*d289c2baSAndroid Build Coastguard Worker /// Calls `slot_verify()` for both test partitions.
verify_two_images<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>>46*d289c2baSAndroid Build Coastguard Worker fn verify_two_images<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>> {
47*d289c2baSAndroid Build Coastguard Worker slot_verify(
48*d289c2baSAndroid Build Coastguard Worker ops,
49*d289c2baSAndroid Build Coastguard Worker &[
50*d289c2baSAndroid Build Coastguard Worker &CString::new(TEST_PARTITION_NAME).unwrap(),
51*d289c2baSAndroid Build Coastguard Worker &CString::new(TEST_PARTITION_2_NAME).unwrap(),
52*d289c2baSAndroid Build Coastguard Worker ],
53*d289c2baSAndroid Build Coastguard Worker None,
54*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NONE,
55*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
56*d289c2baSAndroid Build Coastguard Worker )
57*d289c2baSAndroid Build Coastguard Worker }
58*d289c2baSAndroid Build Coastguard Worker
59*d289c2baSAndroid Build Coastguard Worker /// Initializes a `TestOps` object such that verification will succeed on the `boot` partition with
60*d289c2baSAndroid Build Coastguard Worker /// a combined image + vbmeta.
build_test_ops_boot_partition<'a>() -> TestOps<'a>61*d289c2baSAndroid Build Coastguard Worker fn build_test_ops_boot_partition<'a>() -> TestOps<'a> {
62*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
63*d289c2baSAndroid Build Coastguard Worker ops.partitions.clear();
64*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
65*d289c2baSAndroid Build Coastguard Worker "boot",
66*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_IMAGE_WITH_VBMETA_FOOTER_FOR_BOOT_PATH).unwrap(),
67*d289c2baSAndroid Build Coastguard Worker );
68*d289c2baSAndroid Build Coastguard Worker ops
69*d289c2baSAndroid Build Coastguard Worker }
70*d289c2baSAndroid Build Coastguard Worker
71*d289c2baSAndroid Build Coastguard Worker /// Calls `slot_verify()` using standard args for `build_test_ops_boot_partition()` setup.
verify_boot_partition<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>>72*d289c2baSAndroid Build Coastguard Worker fn verify_boot_partition<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>> {
73*d289c2baSAndroid Build Coastguard Worker slot_verify(
74*d289c2baSAndroid Build Coastguard Worker ops,
75*d289c2baSAndroid Build Coastguard Worker &[&CString::new("boot").unwrap()],
76*d289c2baSAndroid Build Coastguard Worker None,
77*d289c2baSAndroid Build Coastguard Worker // libavb has some special-case handling to automatically detect a combined image + vbmeta
78*d289c2baSAndroid Build Coastguard Worker // in the `boot` partition; don't pass the `AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION` flag
79*d289c2baSAndroid Build Coastguard Worker // so we can test this behavior.
80*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NONE,
81*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
82*d289c2baSAndroid Build Coastguard Worker )
83*d289c2baSAndroid Build Coastguard Worker }
84*d289c2baSAndroid Build Coastguard Worker
85*d289c2baSAndroid Build Coastguard Worker /// Initializes a `TestOps` object such that verification will succeed on
86*d289c2baSAndroid Build Coastguard Worker /// `TEST_PARTITION_PERSISTENT_DIGEST_NAME`.
build_test_ops_persistent_digest<'a>(image: Vec<u8>) -> TestOps<'a>87*d289c2baSAndroid Build Coastguard Worker fn build_test_ops_persistent_digest<'a>(image: Vec<u8>) -> TestOps<'a> {
88*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
89*d289c2baSAndroid Build Coastguard Worker ops.partitions.clear();
90*d289c2baSAndroid Build Coastguard Worker // Use the vbmeta image with the persistent digest descriptor.
91*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
92*d289c2baSAndroid Build Coastguard Worker "vbmeta",
93*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_VBMETA_PERSISTENT_DIGEST_PATH).unwrap(),
94*d289c2baSAndroid Build Coastguard Worker );
95*d289c2baSAndroid Build Coastguard Worker // Register the image contents to be stored via persistent digest.
96*d289c2baSAndroid Build Coastguard Worker ops.add_partition(TEST_PARTITION_PERSISTENT_DIGEST_NAME, image);
97*d289c2baSAndroid Build Coastguard Worker ops
98*d289c2baSAndroid Build Coastguard Worker }
99*d289c2baSAndroid Build Coastguard Worker
100*d289c2baSAndroid Build Coastguard Worker /// Calls `slot_verify()` using standard args for `build_test_ops_persistent_digest()` setup.
verify_persistent_digest<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>>101*d289c2baSAndroid Build Coastguard Worker fn verify_persistent_digest<'a>(ops: &mut TestOps<'a>) -> SlotVerifyResult<'a, SlotVerifyData<'a>> {
102*d289c2baSAndroid Build Coastguard Worker slot_verify(
103*d289c2baSAndroid Build Coastguard Worker ops,
104*d289c2baSAndroid Build Coastguard Worker &[&CString::new(TEST_PARTITION_PERSISTENT_DIGEST_NAME).unwrap()],
105*d289c2baSAndroid Build Coastguard Worker None,
106*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NONE,
107*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
108*d289c2baSAndroid Build Coastguard Worker )
109*d289c2baSAndroid Build Coastguard Worker }
110*d289c2baSAndroid Build Coastguard Worker
111*d289c2baSAndroid Build Coastguard Worker /// Modifies the partition contents by flipping a bit.
modify_partition_contents(ops: &mut TestOps, partition: &str)112*d289c2baSAndroid Build Coastguard Worker fn modify_partition_contents(ops: &mut TestOps, partition: &str) {
113*d289c2baSAndroid Build Coastguard Worker ops.partitions
114*d289c2baSAndroid Build Coastguard Worker .get_mut(partition)
115*d289c2baSAndroid Build Coastguard Worker .unwrap()
116*d289c2baSAndroid Build Coastguard Worker .contents
117*d289c2baSAndroid Build Coastguard Worker .as_mut_vec()[0] ^= 0x01;
118*d289c2baSAndroid Build Coastguard Worker }
119*d289c2baSAndroid Build Coastguard Worker
120*d289c2baSAndroid Build Coastguard Worker /// Returns the persistent value name for `TEST_PARTITION_PERSISTENT_DIGEST_NAME`.
persistent_digest_value_name() -> String121*d289c2baSAndroid Build Coastguard Worker fn persistent_digest_value_name() -> String {
122*d289c2baSAndroid Build Coastguard Worker // This exact format is a libavb implementation detail but is unlikely to change. If it does
123*d289c2baSAndroid Build Coastguard Worker // just update this format to match.
124*d289c2baSAndroid Build Coastguard Worker format!("avb.persistent_digest.{TEST_PARTITION_PERSISTENT_DIGEST_NAME}")
125*d289c2baSAndroid Build Coastguard Worker }
126*d289c2baSAndroid Build Coastguard Worker
127*d289c2baSAndroid Build Coastguard Worker #[test]
one_image_one_vbmeta_passes_verification_with_correct_data()128*d289c2baSAndroid Build Coastguard Worker fn one_image_one_vbmeta_passes_verification_with_correct_data() {
129*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
130*d289c2baSAndroid Build Coastguard Worker
131*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
132*d289c2baSAndroid Build Coastguard Worker
133*d289c2baSAndroid Build Coastguard Worker // Make sure the resulting `SlotVerifyData` looks correct.
134*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
135*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.ab_suffix().to_bytes(), b"");
136*d289c2baSAndroid Build Coastguard Worker // We don't care about the exact commandline, just search for a substring we know will
137*d289c2baSAndroid Build Coastguard Worker // exist to make sure the commandline is being provided to the caller correctly.
138*d289c2baSAndroid Build Coastguard Worker assert!(data
139*d289c2baSAndroid Build Coastguard Worker .cmdline()
140*d289c2baSAndroid Build Coastguard Worker .to_str()
141*d289c2baSAndroid Build Coastguard Worker .unwrap()
142*d289c2baSAndroid Build Coastguard Worker .contains("androidboot.vbmeta.device_state=locked"));
143*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.rollback_indexes(), &[0; 32]);
144*d289c2baSAndroid Build Coastguard Worker assert_eq!(
145*d289c2baSAndroid Build Coastguard Worker data.resolved_hashtree_error_mode(),
146*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO
147*d289c2baSAndroid Build Coastguard Worker );
148*d289c2baSAndroid Build Coastguard Worker
149*d289c2baSAndroid Build Coastguard Worker // Check the `VbmetaData` struct looks correct.
150*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data().len(), 1);
151*d289c2baSAndroid Build Coastguard Worker let vbmeta_data = &data.vbmeta_data()[0];
152*d289c2baSAndroid Build Coastguard Worker assert_eq!(vbmeta_data.partition_name().to_str().unwrap(), "vbmeta");
153*d289c2baSAndroid Build Coastguard Worker assert_eq!(vbmeta_data.data(), fs::read(TEST_VBMETA_PATH).unwrap());
154*d289c2baSAndroid Build Coastguard Worker assert_eq!(vbmeta_data.verify_result(), Ok(()));
155*d289c2baSAndroid Build Coastguard Worker
156*d289c2baSAndroid Build Coastguard Worker // Check the `PartitionData` struct looks correct.
157*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data().len(), 1);
158*d289c2baSAndroid Build Coastguard Worker let partition_data = &data.partition_data()[0];
159*d289c2baSAndroid Build Coastguard Worker assert_eq!(
160*d289c2baSAndroid Build Coastguard Worker partition_data.partition_name().to_str().unwrap(),
161*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME
162*d289c2baSAndroid Build Coastguard Worker );
163*d289c2baSAndroid Build Coastguard Worker assert_eq!(partition_data.data(), fs::read(TEST_IMAGE_PATH).unwrap());
164*d289c2baSAndroid Build Coastguard Worker assert!(!partition_data.preloaded());
165*d289c2baSAndroid Build Coastguard Worker assert!(partition_data.verify_result().is_ok());
166*d289c2baSAndroid Build Coastguard Worker }
167*d289c2baSAndroid Build Coastguard Worker
168*d289c2baSAndroid Build Coastguard Worker #[test]
preloaded_image_passes_verification()169*d289c2baSAndroid Build Coastguard Worker fn preloaded_image_passes_verification() {
170*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
171*d289c2baSAndroid Build Coastguard Worker // Use preloaded data instead for the test partition.
172*d289c2baSAndroid Build Coastguard Worker let preloaded = fs::read(TEST_IMAGE_PATH).unwrap();
173*d289c2baSAndroid Build Coastguard Worker ops.add_preloaded_partition(TEST_PARTITION_NAME, &preloaded);
174*d289c2baSAndroid Build Coastguard Worker
175*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
176*d289c2baSAndroid Build Coastguard Worker
177*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
178*d289c2baSAndroid Build Coastguard Worker let partition_data = &data.partition_data()[0];
179*d289c2baSAndroid Build Coastguard Worker assert!(partition_data.preloaded());
180*d289c2baSAndroid Build Coastguard Worker }
181*d289c2baSAndroid Build Coastguard Worker
182*d289c2baSAndroid Build Coastguard Worker // When all images are loaded from disk (rather than preloaded), libavb allocates memory itself for
183*d289c2baSAndroid Build Coastguard Worker // the data, so there is no shared ownership; the returned verification data owns the image data
184*d289c2baSAndroid Build Coastguard Worker // and can hold onto it even after the `ops` goes away.
185*d289c2baSAndroid Build Coastguard Worker #[test]
verification_data_from_disk_can_outlive_ops()186*d289c2baSAndroid Build Coastguard Worker fn verification_data_from_disk_can_outlive_ops() {
187*d289c2baSAndroid Build Coastguard Worker let result = {
188*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
189*d289c2baSAndroid Build Coastguard Worker verify_one_image_one_vbmeta(&mut ops)
190*d289c2baSAndroid Build Coastguard Worker };
191*d289c2baSAndroid Build Coastguard Worker
192*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
193*d289c2baSAndroid Build Coastguard Worker
194*d289c2baSAndroid Build Coastguard Worker // The verification data owns the images and we can still access them.
195*d289c2baSAndroid Build Coastguard Worker assert_eq!(
196*d289c2baSAndroid Build Coastguard Worker data.partition_data()[0].data(),
197*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_IMAGE_PATH).unwrap()
198*d289c2baSAndroid Build Coastguard Worker );
199*d289c2baSAndroid Build Coastguard Worker }
200*d289c2baSAndroid Build Coastguard Worker
201*d289c2baSAndroid Build Coastguard Worker // When preloaded data is passed into ops but outlives it, we can also continue to access it from
202*d289c2baSAndroid Build Coastguard Worker // the verification data after the ops goes away. The ops was only borrowing it, and now the
203*d289c2baSAndroid Build Coastguard Worker // verification data continues to borrow it.
204*d289c2baSAndroid Build Coastguard Worker #[test]
verification_data_preloaded_can_outlive_ops()205*d289c2baSAndroid Build Coastguard Worker fn verification_data_preloaded_can_outlive_ops() {
206*d289c2baSAndroid Build Coastguard Worker let preloaded = fs::read(TEST_IMAGE_PATH).unwrap();
207*d289c2baSAndroid Build Coastguard Worker
208*d289c2baSAndroid Build Coastguard Worker let result = {
209*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
210*d289c2baSAndroid Build Coastguard Worker ops.add_preloaded_partition(TEST_PARTITION_NAME, &preloaded);
211*d289c2baSAndroid Build Coastguard Worker verify_one_image_one_vbmeta(&mut ops)
212*d289c2baSAndroid Build Coastguard Worker };
213*d289c2baSAndroid Build Coastguard Worker
214*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
215*d289c2baSAndroid Build Coastguard Worker
216*d289c2baSAndroid Build Coastguard Worker // The verification data is borrowing the preloaded images and we can still access them.
217*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data()[0].data(), preloaded);
218*d289c2baSAndroid Build Coastguard Worker }
219*d289c2baSAndroid Build Coastguard Worker
220*d289c2baSAndroid Build Coastguard Worker // When preloaded data is passed into ops but also goes out of scope, the verification data loses
221*d289c2baSAndroid Build Coastguard Worker // access to it, violating lifetime rules.
222*d289c2baSAndroid Build Coastguard Worker //
223*d289c2baSAndroid Build Coastguard Worker // Our lifetimes *must* be configured such that this does not compile, since `result` is borrowing
224*d289c2baSAndroid Build Coastguard Worker // `preloaded` which has gone out of scope.
225*d289c2baSAndroid Build Coastguard Worker //
226*d289c2baSAndroid Build Coastguard Worker // TODO: figure out how to make a compile-fail test; for now we just have to manually test by
227*d289c2baSAndroid Build Coastguard Worker // un-commenting the code.
228*d289c2baSAndroid Build Coastguard Worker // #[test]
229*d289c2baSAndroid Build Coastguard Worker // fn verification_data_preloaded_cannot_outlive_result() {
230*d289c2baSAndroid Build Coastguard Worker // let result = {
231*d289c2baSAndroid Build Coastguard Worker // let preloaded = fs::read(TEST_IMAGE_PATH).unwrap();
232*d289c2baSAndroid Build Coastguard Worker // let mut ops = build_test_ops_one_image_one_vbmeta();
233*d289c2baSAndroid Build Coastguard Worker // ops.add_preloaded_partition(TEST_PARTITION_NAME, &preloaded);
234*d289c2baSAndroid Build Coastguard Worker // verify_one_image_one_vbmeta(&mut ops)
235*d289c2baSAndroid Build Coastguard Worker // };
236*d289c2baSAndroid Build Coastguard Worker // result.unwrap();
237*d289c2baSAndroid Build Coastguard Worker // }
238*d289c2baSAndroid Build Coastguard Worker
239*d289c2baSAndroid Build Coastguard Worker #[test]
slotted_partition_passes_verification()240*d289c2baSAndroid Build Coastguard Worker fn slotted_partition_passes_verification() {
241*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
242*d289c2baSAndroid Build Coastguard Worker // Move the partitions to a "_c" slot.
243*d289c2baSAndroid Build Coastguard Worker ops.partitions.clear();
244*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
245*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_SLOT_C_NAME,
246*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_IMAGE_PATH).unwrap(),
247*d289c2baSAndroid Build Coastguard Worker );
248*d289c2baSAndroid Build Coastguard Worker ops.add_partition("vbmeta_c", fs::read(TEST_VBMETA_PATH).unwrap());
249*d289c2baSAndroid Build Coastguard Worker
250*d289c2baSAndroid Build Coastguard Worker let result = slot_verify(
251*d289c2baSAndroid Build Coastguard Worker &mut ops,
252*d289c2baSAndroid Build Coastguard Worker &[&CString::new(TEST_PARTITION_NAME).unwrap()],
253*d289c2baSAndroid Build Coastguard Worker Some(&CString::new("_c").unwrap()),
254*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NONE,
255*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
256*d289c2baSAndroid Build Coastguard Worker );
257*d289c2baSAndroid Build Coastguard Worker
258*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
259*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.ab_suffix().to_bytes(), b"_c");
260*d289c2baSAndroid Build Coastguard Worker }
261*d289c2baSAndroid Build Coastguard Worker
262*d289c2baSAndroid Build Coastguard Worker #[test]
two_images_one_vbmeta_passes_verification()263*d289c2baSAndroid Build Coastguard Worker fn two_images_one_vbmeta_passes_verification() {
264*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_two_images_one_vbmeta();
265*d289c2baSAndroid Build Coastguard Worker
266*d289c2baSAndroid Build Coastguard Worker let result = verify_two_images(&mut ops);
267*d289c2baSAndroid Build Coastguard Worker
268*d289c2baSAndroid Build Coastguard Worker // We should still only have 1 `VbmetaData` since we only used 1 vbmeta image, but it
269*d289c2baSAndroid Build Coastguard Worker // signed 2 partitions so we should have 2 `PartitionData` objects.
270*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
271*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data().len(), 1);
272*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data().len(), 2);
273*d289c2baSAndroid Build Coastguard Worker assert_eq!(
274*d289c2baSAndroid Build Coastguard Worker data.partition_data()[0].partition_name().to_str().unwrap(),
275*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME
276*d289c2baSAndroid Build Coastguard Worker );
277*d289c2baSAndroid Build Coastguard Worker assert_eq!(
278*d289c2baSAndroid Build Coastguard Worker data.partition_data()[1].partition_name().to_str().unwrap(),
279*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_2_NAME
280*d289c2baSAndroid Build Coastguard Worker );
281*d289c2baSAndroid Build Coastguard Worker }
282*d289c2baSAndroid Build Coastguard Worker
283*d289c2baSAndroid Build Coastguard Worker #[test]
combined_image_vbmeta_partition_passes_verification()284*d289c2baSAndroid Build Coastguard Worker fn combined_image_vbmeta_partition_passes_verification() {
285*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
286*d289c2baSAndroid Build Coastguard Worker ops.partitions.clear();
287*d289c2baSAndroid Build Coastguard Worker // Register the single combined image + vbmeta in `TEST_PARTITION_NAME`.
288*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
289*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME,
290*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_IMAGE_WITH_VBMETA_FOOTER_PATH).unwrap(),
291*d289c2baSAndroid Build Coastguard Worker );
292*d289c2baSAndroid Build Coastguard Worker // For a combined image it should not attempt to use the default "vbmeta" key, instead we
293*d289c2baSAndroid Build Coastguard Worker // register the public key specifically for this partition.
294*d289c2baSAndroid Build Coastguard Worker ops.default_vbmeta_key = None;
295*d289c2baSAndroid Build Coastguard Worker ops.vbmeta_keys_for_partition.insert(
296*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME,
297*d289c2baSAndroid Build Coastguard Worker (
298*d289c2baSAndroid Build Coastguard Worker FakeVbmetaKey::Avb {
299*d289c2baSAndroid Build Coastguard Worker public_key: fs::read(TEST_PUBLIC_KEY_PATH).unwrap(),
300*d289c2baSAndroid Build Coastguard Worker public_key_metadata: None,
301*d289c2baSAndroid Build Coastguard Worker },
302*d289c2baSAndroid Build Coastguard Worker TEST_VBMETA_ROLLBACK_LOCATION as u32,
303*d289c2baSAndroid Build Coastguard Worker ),
304*d289c2baSAndroid Build Coastguard Worker );
305*d289c2baSAndroid Build Coastguard Worker
306*d289c2baSAndroid Build Coastguard Worker let result = slot_verify(
307*d289c2baSAndroid Build Coastguard Worker &mut ops,
308*d289c2baSAndroid Build Coastguard Worker &[&CString::new(TEST_PARTITION_NAME).unwrap()],
309*d289c2baSAndroid Build Coastguard Worker None,
310*d289c2baSAndroid Build Coastguard Worker // Tell libavb that the vbmeta image is embedded, not in its own partition.
311*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
312*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
313*d289c2baSAndroid Build Coastguard Worker );
314*d289c2baSAndroid Build Coastguard Worker
315*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
316*d289c2baSAndroid Build Coastguard Worker
317*d289c2baSAndroid Build Coastguard Worker // Vbmeta should indicate that it came from `TEST_PARTITION_NAME`.
318*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data().len(), 1);
319*d289c2baSAndroid Build Coastguard Worker let vbmeta_data = &data.vbmeta_data()[0];
320*d289c2baSAndroid Build Coastguard Worker assert_eq!(
321*d289c2baSAndroid Build Coastguard Worker vbmeta_data.partition_name().to_str().unwrap(),
322*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME
323*d289c2baSAndroid Build Coastguard Worker );
324*d289c2baSAndroid Build Coastguard Worker
325*d289c2baSAndroid Build Coastguard Worker // Partition should indicate that it came from `TEST_PARTITION_NAME`, but only contain the
326*d289c2baSAndroid Build Coastguard Worker // image contents.
327*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data().len(), 1);
328*d289c2baSAndroid Build Coastguard Worker let partition_data = &data.partition_data()[0];
329*d289c2baSAndroid Build Coastguard Worker assert_eq!(
330*d289c2baSAndroid Build Coastguard Worker partition_data.partition_name().to_str().unwrap(),
331*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_NAME
332*d289c2baSAndroid Build Coastguard Worker );
333*d289c2baSAndroid Build Coastguard Worker assert_eq!(partition_data.data(), fs::read(TEST_IMAGE_PATH).unwrap());
334*d289c2baSAndroid Build Coastguard Worker }
335*d289c2baSAndroid Build Coastguard Worker
336*d289c2baSAndroid Build Coastguard Worker // Validate the custom behavior if the combined image + vbmeta live in the `boot` partition.
337*d289c2baSAndroid Build Coastguard Worker #[test]
vbmeta_with_boot_partition_passes_verification()338*d289c2baSAndroid Build Coastguard Worker fn vbmeta_with_boot_partition_passes_verification() {
339*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_boot_partition();
340*d289c2baSAndroid Build Coastguard Worker
341*d289c2baSAndroid Build Coastguard Worker let result = verify_boot_partition(&mut ops);
342*d289c2baSAndroid Build Coastguard Worker
343*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
344*d289c2baSAndroid Build Coastguard Worker
345*d289c2baSAndroid Build Coastguard Worker // Vbmeta should indicate that it came from `boot`.
346*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data().len(), 1);
347*d289c2baSAndroid Build Coastguard Worker let vbmeta_data = &data.vbmeta_data()[0];
348*d289c2baSAndroid Build Coastguard Worker assert_eq!(vbmeta_data.partition_name().to_str().unwrap(), "boot");
349*d289c2baSAndroid Build Coastguard Worker
350*d289c2baSAndroid Build Coastguard Worker // Partition should indicate that it came from `boot`, but only contain the image contents.
351*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data().len(), 1);
352*d289c2baSAndroid Build Coastguard Worker let partition_data = &data.partition_data()[0];
353*d289c2baSAndroid Build Coastguard Worker assert_eq!(partition_data.partition_name().to_str().unwrap(), "boot");
354*d289c2baSAndroid Build Coastguard Worker assert_eq!(partition_data.data(), fs::read(TEST_IMAGE_PATH).unwrap());
355*d289c2baSAndroid Build Coastguard Worker }
356*d289c2baSAndroid Build Coastguard Worker
357*d289c2baSAndroid Build Coastguard Worker #[test]
persistent_digest_verification_updates_persistent_value()358*d289c2baSAndroid Build Coastguard Worker fn persistent_digest_verification_updates_persistent_value() {
359*d289c2baSAndroid Build Coastguard Worker // With persistent digests, the image hash isn't stored in the descriptor, but is instead
360*d289c2baSAndroid Build Coastguard Worker // calculated on-demand and stored into a named persistent value. So our test image can contain
361*d289c2baSAndroid Build Coastguard Worker // anything, but does have to match the size indicated by the descriptor.
362*d289c2baSAndroid Build Coastguard Worker let image_contents = vec![0xAAu8; TEST_IMAGE_SIZE];
363*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_persistent_digest(image_contents.clone());
364*d289c2baSAndroid Build Coastguard Worker
365*d289c2baSAndroid Build Coastguard Worker {
366*d289c2baSAndroid Build Coastguard Worker let result = verify_persistent_digest(&mut ops);
367*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
368*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data()[0].data(), image_contents);
369*d289c2baSAndroid Build Coastguard Worker } // Drop `result` here so it releases `ops` and we can use it again.
370*d289c2baSAndroid Build Coastguard Worker
371*d289c2baSAndroid Build Coastguard Worker assert!(ops
372*d289c2baSAndroid Build Coastguard Worker .persistent_values
373*d289c2baSAndroid Build Coastguard Worker .contains_key(&persistent_digest_value_name()));
374*d289c2baSAndroid Build Coastguard Worker }
375*d289c2baSAndroid Build Coastguard Worker
376*d289c2baSAndroid Build Coastguard Worker #[cfg(feature = "uuid")]
377*d289c2baSAndroid Build Coastguard Worker #[test]
successful_verification_substitutes_partition_guid()378*d289c2baSAndroid Build Coastguard Worker fn successful_verification_substitutes_partition_guid() {
379*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
380*d289c2baSAndroid Build Coastguard Worker ops.partitions.get_mut("vbmeta").unwrap().uuid = uuid!("01234567-89ab-cdef-0123-456789abcdef");
381*d289c2baSAndroid Build Coastguard Worker
382*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
383*d289c2baSAndroid Build Coastguard Worker
384*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
385*d289c2baSAndroid Build Coastguard Worker assert!(data
386*d289c2baSAndroid Build Coastguard Worker .cmdline()
387*d289c2baSAndroid Build Coastguard Worker .to_str()
388*d289c2baSAndroid Build Coastguard Worker .unwrap()
389*d289c2baSAndroid Build Coastguard Worker .contains("androidboot.vbmeta.device=PARTUUID=01234567-89ab-cdef-0123-456789abcdef"));
390*d289c2baSAndroid Build Coastguard Worker }
391*d289c2baSAndroid Build Coastguard Worker
392*d289c2baSAndroid Build Coastguard Worker #[cfg(feature = "uuid")]
393*d289c2baSAndroid Build Coastguard Worker #[test]
successful_verification_substitutes_boot_partition_guid()394*d289c2baSAndroid Build Coastguard Worker fn successful_verification_substitutes_boot_partition_guid() {
395*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_boot_partition();
396*d289c2baSAndroid Build Coastguard Worker ops.partitions.get_mut("boot").unwrap().uuid = uuid!("01234567-89ab-cdef-0123-456789abcdef");
397*d289c2baSAndroid Build Coastguard Worker
398*d289c2baSAndroid Build Coastguard Worker let result = verify_boot_partition(&mut ops);
399*d289c2baSAndroid Build Coastguard Worker
400*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
401*d289c2baSAndroid Build Coastguard Worker // In this case libavb substitutes the `boot` partition GUID in for `vbmeta`.
402*d289c2baSAndroid Build Coastguard Worker assert!(data
403*d289c2baSAndroid Build Coastguard Worker .cmdline()
404*d289c2baSAndroid Build Coastguard Worker .to_str()
405*d289c2baSAndroid Build Coastguard Worker .unwrap()
406*d289c2baSAndroid Build Coastguard Worker .contains("androidboot.vbmeta.device=PARTUUID=01234567-89ab-cdef-0123-456789abcdef"));
407*d289c2baSAndroid Build Coastguard Worker }
408*d289c2baSAndroid Build Coastguard Worker
409*d289c2baSAndroid Build Coastguard Worker #[test]
corrupted_image_fails_verification()410*d289c2baSAndroid Build Coastguard Worker fn corrupted_image_fails_verification() {
411*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
412*d289c2baSAndroid Build Coastguard Worker modify_partition_contents(&mut ops, TEST_PARTITION_NAME);
413*d289c2baSAndroid Build Coastguard Worker
414*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
415*d289c2baSAndroid Build Coastguard Worker
416*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
417*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Verification(None)));
418*d289c2baSAndroid Build Coastguard Worker }
419*d289c2baSAndroid Build Coastguard Worker
420*d289c2baSAndroid Build Coastguard Worker #[test]
read_partition_callback_error_fails_verification()421*d289c2baSAndroid Build Coastguard Worker fn read_partition_callback_error_fails_verification() {
422*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
423*d289c2baSAndroid Build Coastguard Worker ops.partitions.remove(TEST_PARTITION_NAME);
424*d289c2baSAndroid Build Coastguard Worker
425*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
426*d289c2baSAndroid Build Coastguard Worker
427*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
428*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
429*d289c2baSAndroid Build Coastguard Worker }
430*d289c2baSAndroid Build Coastguard Worker
431*d289c2baSAndroid Build Coastguard Worker #[test]
undersized_partition_fails_verification()432*d289c2baSAndroid Build Coastguard Worker fn undersized_partition_fails_verification() {
433*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
434*d289c2baSAndroid Build Coastguard Worker ops.partitions
435*d289c2baSAndroid Build Coastguard Worker .get_mut(TEST_PARTITION_NAME)
436*d289c2baSAndroid Build Coastguard Worker .unwrap()
437*d289c2baSAndroid Build Coastguard Worker .contents
438*d289c2baSAndroid Build Coastguard Worker .as_mut_vec()
439*d289c2baSAndroid Build Coastguard Worker .pop();
440*d289c2baSAndroid Build Coastguard Worker
441*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
442*d289c2baSAndroid Build Coastguard Worker
443*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
444*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
445*d289c2baSAndroid Build Coastguard Worker }
446*d289c2baSAndroid Build Coastguard Worker
447*d289c2baSAndroid Build Coastguard Worker #[test]
corrupted_vbmeta_fails_verification()448*d289c2baSAndroid Build Coastguard Worker fn corrupted_vbmeta_fails_verification() {
449*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
450*d289c2baSAndroid Build Coastguard Worker modify_partition_contents(&mut ops, "vbmeta");
451*d289c2baSAndroid Build Coastguard Worker
452*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
453*d289c2baSAndroid Build Coastguard Worker
454*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
455*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::InvalidMetadata));
456*d289c2baSAndroid Build Coastguard Worker }
457*d289c2baSAndroid Build Coastguard Worker
458*d289c2baSAndroid Build Coastguard Worker #[test]
rollback_violation_fails_verification()459*d289c2baSAndroid Build Coastguard Worker fn rollback_violation_fails_verification() {
460*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
461*d289c2baSAndroid Build Coastguard Worker // Device with rollback = 1 should refuse to boot image with rollback = 0.
462*d289c2baSAndroid Build Coastguard Worker ops.rollbacks.insert(TEST_VBMETA_ROLLBACK_LOCATION, Ok(1));
463*d289c2baSAndroid Build Coastguard Worker
464*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
465*d289c2baSAndroid Build Coastguard Worker
466*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
467*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::RollbackIndex));
468*d289c2baSAndroid Build Coastguard Worker }
469*d289c2baSAndroid Build Coastguard Worker
470*d289c2baSAndroid Build Coastguard Worker #[test]
rollback_callback_error_fails_verification()471*d289c2baSAndroid Build Coastguard Worker fn rollback_callback_error_fails_verification() {
472*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
473*d289c2baSAndroid Build Coastguard Worker ops.rollbacks.clear();
474*d289c2baSAndroid Build Coastguard Worker
475*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
476*d289c2baSAndroid Build Coastguard Worker
477*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
478*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
479*d289c2baSAndroid Build Coastguard Worker }
480*d289c2baSAndroid Build Coastguard Worker
481*d289c2baSAndroid Build Coastguard Worker #[test]
untrusted_vbmeta_keys_fails_verification()482*d289c2baSAndroid Build Coastguard Worker fn untrusted_vbmeta_keys_fails_verification() {
483*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
484*d289c2baSAndroid Build Coastguard Worker ops.default_vbmeta_key = Some(FakeVbmetaKey::Avb {
485*d289c2baSAndroid Build Coastguard Worker public_key: b"not_the_key".into(),
486*d289c2baSAndroid Build Coastguard Worker public_key_metadata: None,
487*d289c2baSAndroid Build Coastguard Worker });
488*d289c2baSAndroid Build Coastguard Worker
489*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
490*d289c2baSAndroid Build Coastguard Worker
491*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
492*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::PublicKeyRejected));
493*d289c2baSAndroid Build Coastguard Worker }
494*d289c2baSAndroid Build Coastguard Worker
495*d289c2baSAndroid Build Coastguard Worker #[test]
vbmeta_keys_callback_error_fails_verification()496*d289c2baSAndroid Build Coastguard Worker fn vbmeta_keys_callback_error_fails_verification() {
497*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
498*d289c2baSAndroid Build Coastguard Worker ops.default_vbmeta_key = None;
499*d289c2baSAndroid Build Coastguard Worker
500*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
501*d289c2baSAndroid Build Coastguard Worker
502*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
503*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
504*d289c2baSAndroid Build Coastguard Worker }
505*d289c2baSAndroid Build Coastguard Worker
506*d289c2baSAndroid Build Coastguard Worker #[test]
unlock_state_callback_error_fails_verification()507*d289c2baSAndroid Build Coastguard Worker fn unlock_state_callback_error_fails_verification() {
508*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
509*d289c2baSAndroid Build Coastguard Worker ops.unlock_state = Err(IoError::Io);
510*d289c2baSAndroid Build Coastguard Worker
511*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
512*d289c2baSAndroid Build Coastguard Worker
513*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
514*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
515*d289c2baSAndroid Build Coastguard Worker }
516*d289c2baSAndroid Build Coastguard Worker
517*d289c2baSAndroid Build Coastguard Worker #[test]
persistent_digest_mismatch_fails_verification()518*d289c2baSAndroid Build Coastguard Worker fn persistent_digest_mismatch_fails_verification() {
519*d289c2baSAndroid Build Coastguard Worker let image_contents = vec![0xAAu8; TEST_IMAGE_SIZE];
520*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_persistent_digest(image_contents.clone());
521*d289c2baSAndroid Build Coastguard Worker // Put in an incorrect persistent digest; `slot_verify()` should detect the mismatch and fail.
522*d289c2baSAndroid Build Coastguard Worker ops.add_persistent_value(&persistent_digest_value_name(), Ok(b"incorrect_digest"));
523*d289c2baSAndroid Build Coastguard Worker // Make a copy so we can verify the persistent values don't change on failure.
524*d289c2baSAndroid Build Coastguard Worker let original_persistent_values = ops.persistent_values.clone();
525*d289c2baSAndroid Build Coastguard Worker
526*d289c2baSAndroid Build Coastguard Worker assert!(verify_persistent_digest(&mut ops).is_err());
527*d289c2baSAndroid Build Coastguard Worker
528*d289c2baSAndroid Build Coastguard Worker // Persistent value should be unchanged.
529*d289c2baSAndroid Build Coastguard Worker assert_eq!(ops.persistent_values, original_persistent_values);
530*d289c2baSAndroid Build Coastguard Worker }
531*d289c2baSAndroid Build Coastguard Worker
532*d289c2baSAndroid Build Coastguard Worker #[test]
persistent_digest_callback_error_fails_verification()533*d289c2baSAndroid Build Coastguard Worker fn persistent_digest_callback_error_fails_verification() {
534*d289c2baSAndroid Build Coastguard Worker let image_contents = vec![0xAAu8; TEST_IMAGE_SIZE];
535*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_persistent_digest(image_contents.clone());
536*d289c2baSAndroid Build Coastguard Worker ops.add_persistent_value(&persistent_digest_value_name(), Err(IoError::NoSuchValue));
537*d289c2baSAndroid Build Coastguard Worker
538*d289c2baSAndroid Build Coastguard Worker let result = verify_persistent_digest(&mut ops);
539*d289c2baSAndroid Build Coastguard Worker
540*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
541*d289c2baSAndroid Build Coastguard Worker assert!(matches!(error, SlotVerifyError::Io));
542*d289c2baSAndroid Build Coastguard Worker }
543*d289c2baSAndroid Build Coastguard Worker
544*d289c2baSAndroid Build Coastguard Worker #[test]
corrupted_image_with_allow_verification_error_flag_fails_verification_with_data()545*d289c2baSAndroid Build Coastguard Worker fn corrupted_image_with_allow_verification_error_flag_fails_verification_with_data() {
546*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
547*d289c2baSAndroid Build Coastguard Worker modify_partition_contents(&mut ops, TEST_PARTITION_NAME);
548*d289c2baSAndroid Build Coastguard Worker
549*d289c2baSAndroid Build Coastguard Worker let result = slot_verify(
550*d289c2baSAndroid Build Coastguard Worker &mut ops,
551*d289c2baSAndroid Build Coastguard Worker &[&CString::new(TEST_PARTITION_NAME).unwrap()],
552*d289c2baSAndroid Build Coastguard Worker None,
553*d289c2baSAndroid Build Coastguard Worker // Pass the flag to allow verification errors.
554*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
555*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
556*d289c2baSAndroid Build Coastguard Worker );
557*d289c2baSAndroid Build Coastguard Worker
558*d289c2baSAndroid Build Coastguard Worker // Verification should fail, but with the `AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR` flag
559*d289c2baSAndroid Build Coastguard Worker // it should give us back the verification data.
560*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
561*d289c2baSAndroid Build Coastguard Worker let data = match error {
562*d289c2baSAndroid Build Coastguard Worker SlotVerifyError::Verification(Some(data)) => data,
563*d289c2baSAndroid Build Coastguard Worker _ => panic!("Expected verification data to exist"),
564*d289c2baSAndroid Build Coastguard Worker };
565*d289c2baSAndroid Build Coastguard Worker
566*d289c2baSAndroid Build Coastguard Worker // vbmeta verification should have succeeded since that image was still correct.
567*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data().len(), 1);
568*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data()[0].verify_result(), Ok(()));
569*d289c2baSAndroid Build Coastguard Worker // Partition verification should have failed since we modified the image.
570*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.partition_data().len(), 1);
571*d289c2baSAndroid Build Coastguard Worker assert!(matches!(
572*d289c2baSAndroid Build Coastguard Worker data.partition_data()[0].verify_result(),
573*d289c2baSAndroid Build Coastguard Worker Err(SlotVerifyError::Verification(None))
574*d289c2baSAndroid Build Coastguard Worker ));
575*d289c2baSAndroid Build Coastguard Worker }
576*d289c2baSAndroid Build Coastguard Worker
577*d289c2baSAndroid Build Coastguard Worker #[test]
one_image_one_vbmeta_verification_data_display()578*d289c2baSAndroid Build Coastguard Worker fn one_image_one_vbmeta_verification_data_display() {
579*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
580*d289c2baSAndroid Build Coastguard Worker
581*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
582*d289c2baSAndroid Build Coastguard Worker
583*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
584*d289c2baSAndroid Build Coastguard Worker assert_eq!(
585*d289c2baSAndroid Build Coastguard Worker format!("{data}"),
586*d289c2baSAndroid Build Coastguard Worker r#"slot: "", vbmeta: ["vbmeta": Ok(())], images: ["test_part": Ok(())]"#
587*d289c2baSAndroid Build Coastguard Worker );
588*d289c2baSAndroid Build Coastguard Worker }
589*d289c2baSAndroid Build Coastguard Worker
590*d289c2baSAndroid Build Coastguard Worker #[test]
preloaded_image_verification_data_display()591*d289c2baSAndroid Build Coastguard Worker fn preloaded_image_verification_data_display() {
592*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
593*d289c2baSAndroid Build Coastguard Worker let preloaded = fs::read(TEST_IMAGE_PATH).unwrap();
594*d289c2baSAndroid Build Coastguard Worker ops.add_preloaded_partition(TEST_PARTITION_NAME, &preloaded);
595*d289c2baSAndroid Build Coastguard Worker
596*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
597*d289c2baSAndroid Build Coastguard Worker
598*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
599*d289c2baSAndroid Build Coastguard Worker assert_eq!(
600*d289c2baSAndroid Build Coastguard Worker format!("{data}"),
601*d289c2baSAndroid Build Coastguard Worker r#"slot: "", vbmeta: ["vbmeta": Ok(())], images: ["test_part"(p): Ok(())]"#
602*d289c2baSAndroid Build Coastguard Worker );
603*d289c2baSAndroid Build Coastguard Worker }
604*d289c2baSAndroid Build Coastguard Worker
605*d289c2baSAndroid Build Coastguard Worker #[test]
two_images_one_vbmeta_verification_data_display()606*d289c2baSAndroid Build Coastguard Worker fn two_images_one_vbmeta_verification_data_display() {
607*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_two_images_one_vbmeta();
608*d289c2baSAndroid Build Coastguard Worker
609*d289c2baSAndroid Build Coastguard Worker let result = verify_two_images(&mut ops);
610*d289c2baSAndroid Build Coastguard Worker
611*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
612*d289c2baSAndroid Build Coastguard Worker assert_eq!(
613*d289c2baSAndroid Build Coastguard Worker format!("{data}"),
614*d289c2baSAndroid Build Coastguard Worker r#"slot: "", vbmeta: ["vbmeta": Ok(())], images: ["test_part": Ok(()), "test_part_2": Ok(())]"#
615*d289c2baSAndroid Build Coastguard Worker );
616*d289c2baSAndroid Build Coastguard Worker }
617*d289c2baSAndroid Build Coastguard Worker
618*d289c2baSAndroid Build Coastguard Worker #[test]
corrupted_image_verification_data_display()619*d289c2baSAndroid Build Coastguard Worker fn corrupted_image_verification_data_display() {
620*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
621*d289c2baSAndroid Build Coastguard Worker modify_partition_contents(&mut ops, TEST_PARTITION_NAME);
622*d289c2baSAndroid Build Coastguard Worker
623*d289c2baSAndroid Build Coastguard Worker let result = slot_verify(
624*d289c2baSAndroid Build Coastguard Worker &mut ops,
625*d289c2baSAndroid Build Coastguard Worker &[&CString::new(TEST_PARTITION_NAME).unwrap()],
626*d289c2baSAndroid Build Coastguard Worker None,
627*d289c2baSAndroid Build Coastguard Worker SlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
628*d289c2baSAndroid Build Coastguard Worker HashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO,
629*d289c2baSAndroid Build Coastguard Worker );
630*d289c2baSAndroid Build Coastguard Worker
631*d289c2baSAndroid Build Coastguard Worker let error = result.unwrap_err();
632*d289c2baSAndroid Build Coastguard Worker let data = match error {
633*d289c2baSAndroid Build Coastguard Worker SlotVerifyError::Verification(Some(data)) => data,
634*d289c2baSAndroid Build Coastguard Worker _ => panic!("Expected verification data to exist"),
635*d289c2baSAndroid Build Coastguard Worker };
636*d289c2baSAndroid Build Coastguard Worker assert_eq!(
637*d289c2baSAndroid Build Coastguard Worker format!("{data}"),
638*d289c2baSAndroid Build Coastguard Worker r#"slot: "", vbmeta: ["vbmeta": Ok(())], images: ["test_part": Err(Verification(None))]"#
639*d289c2baSAndroid Build Coastguard Worker );
640*d289c2baSAndroid Build Coastguard Worker }
641*d289c2baSAndroid Build Coastguard Worker
642*d289c2baSAndroid Build Coastguard Worker #[test]
one_image_gives_single_descriptor()643*d289c2baSAndroid Build Coastguard Worker fn one_image_gives_single_descriptor() {
644*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
645*d289c2baSAndroid Build Coastguard Worker
646*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
647*d289c2baSAndroid Build Coastguard Worker
648*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
649*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data()[0].descriptors().unwrap().len(), 1);
650*d289c2baSAndroid Build Coastguard Worker }
651*d289c2baSAndroid Build Coastguard Worker
652*d289c2baSAndroid Build Coastguard Worker #[test]
two_images_gives_two_descriptors()653*d289c2baSAndroid Build Coastguard Worker fn two_images_gives_two_descriptors() {
654*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_two_images_one_vbmeta();
655*d289c2baSAndroid Build Coastguard Worker
656*d289c2baSAndroid Build Coastguard Worker let result = verify_two_images(&mut ops);
657*d289c2baSAndroid Build Coastguard Worker
658*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
659*d289c2baSAndroid Build Coastguard Worker assert_eq!(data.vbmeta_data()[0].descriptors().unwrap().len(), 2);
660*d289c2baSAndroid Build Coastguard Worker }
661*d289c2baSAndroid Build Coastguard Worker
662*d289c2baSAndroid Build Coastguard Worker /// Runs verification on the given contents and checks for a resulting descriptor.
663*d289c2baSAndroid Build Coastguard Worker ///
664*d289c2baSAndroid Build Coastguard Worker /// This test helper performs the following steps:
665*d289c2baSAndroid Build Coastguard Worker ///
666*d289c2baSAndroid Build Coastguard Worker /// 1. set up a `TestOps` for the default test image/vbmeta
667*d289c2baSAndroid Build Coastguard Worker /// 2. replace the vbmeta image with the contents at `vbmeta_path`
668*d289c2baSAndroid Build Coastguard Worker /// 3. run verification
669*d289c2baSAndroid Build Coastguard Worker /// 4. check that the given `descriptor` exists in the verification data
verify_and_find_descriptor(vbmeta_path: &str, expected_descriptor: &Descriptor)670*d289c2baSAndroid Build Coastguard Worker fn verify_and_find_descriptor(vbmeta_path: &str, expected_descriptor: &Descriptor) {
671*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
672*d289c2baSAndroid Build Coastguard Worker
673*d289c2baSAndroid Build Coastguard Worker // Replace the vbmeta image with the requested variation.
674*d289c2baSAndroid Build Coastguard Worker ops.add_partition("vbmeta", fs::read(vbmeta_path).unwrap());
675*d289c2baSAndroid Build Coastguard Worker
676*d289c2baSAndroid Build Coastguard Worker let result = verify_one_image_one_vbmeta(&mut ops);
677*d289c2baSAndroid Build Coastguard Worker
678*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
679*d289c2baSAndroid Build Coastguard Worker let descriptors = &data.vbmeta_data()[0].descriptors().unwrap();
680*d289c2baSAndroid Build Coastguard Worker assert!(descriptors.contains(expected_descriptor));
681*d289c2baSAndroid Build Coastguard Worker }
682*d289c2baSAndroid Build Coastguard Worker
683*d289c2baSAndroid Build Coastguard Worker #[test]
verify_hash_descriptor()684*d289c2baSAndroid Build Coastguard Worker fn verify_hash_descriptor() {
685*d289c2baSAndroid Build Coastguard Worker verify_and_find_descriptor(
686*d289c2baSAndroid Build Coastguard Worker // The standard vbmeta image should contain the hash descriptor.
687*d289c2baSAndroid Build Coastguard Worker TEST_VBMETA_PATH,
688*d289c2baSAndroid Build Coastguard Worker &Descriptor::Hash(HashDescriptor {
689*d289c2baSAndroid Build Coastguard Worker image_size: TEST_IMAGE_SIZE as u64,
690*d289c2baSAndroid Build Coastguard Worker hash_algorithm: TEST_IMAGE_HASH_ALGO,
691*d289c2baSAndroid Build Coastguard Worker flags: HashDescriptorFlags(0),
692*d289c2baSAndroid Build Coastguard Worker partition_name: TEST_PARTITION_NAME,
693*d289c2baSAndroid Build Coastguard Worker salt: &decode(TEST_IMAGE_SALT_HEX).unwrap(),
694*d289c2baSAndroid Build Coastguard Worker digest: &decode(TEST_IMAGE_DIGEST_HEX).unwrap(),
695*d289c2baSAndroid Build Coastguard Worker }),
696*d289c2baSAndroid Build Coastguard Worker );
697*d289c2baSAndroid Build Coastguard Worker }
698*d289c2baSAndroid Build Coastguard Worker
699*d289c2baSAndroid Build Coastguard Worker #[test]
verify_property_descriptor()700*d289c2baSAndroid Build Coastguard Worker fn verify_property_descriptor() {
701*d289c2baSAndroid Build Coastguard Worker verify_and_find_descriptor(
702*d289c2baSAndroid Build Coastguard Worker TEST_VBMETA_WITH_PROPERTY_PATH,
703*d289c2baSAndroid Build Coastguard Worker &Descriptor::Property(PropertyDescriptor {
704*d289c2baSAndroid Build Coastguard Worker key: TEST_PROPERTY_KEY,
705*d289c2baSAndroid Build Coastguard Worker value: TEST_PROPERTY_VALUE,
706*d289c2baSAndroid Build Coastguard Worker }),
707*d289c2baSAndroid Build Coastguard Worker );
708*d289c2baSAndroid Build Coastguard Worker }
709*d289c2baSAndroid Build Coastguard Worker
710*d289c2baSAndroid Build Coastguard Worker #[test]
verify_hashtree_descriptor()711*d289c2baSAndroid Build Coastguard Worker fn verify_hashtree_descriptor() {
712*d289c2baSAndroid Build Coastguard Worker verify_and_find_descriptor(
713*d289c2baSAndroid Build Coastguard Worker TEST_VBMETA_WITH_HASHTREE_PATH,
714*d289c2baSAndroid Build Coastguard Worker &Descriptor::Hashtree(HashtreeDescriptor {
715*d289c2baSAndroid Build Coastguard Worker dm_verity_version: 1,
716*d289c2baSAndroid Build Coastguard Worker image_size: TEST_IMAGE_SIZE as u64,
717*d289c2baSAndroid Build Coastguard Worker tree_offset: TEST_IMAGE_SIZE as u64,
718*d289c2baSAndroid Build Coastguard Worker tree_size: 4096,
719*d289c2baSAndroid Build Coastguard Worker data_block_size: 4096,
720*d289c2baSAndroid Build Coastguard Worker hash_block_size: 4096,
721*d289c2baSAndroid Build Coastguard Worker fec_num_roots: 0,
722*d289c2baSAndroid Build Coastguard Worker fec_offset: 0,
723*d289c2baSAndroid Build Coastguard Worker fec_size: 0,
724*d289c2baSAndroid Build Coastguard Worker hash_algorithm: TEST_HASHTREE_ALGORITHM,
725*d289c2baSAndroid Build Coastguard Worker flags: HashtreeDescriptorFlags(0),
726*d289c2baSAndroid Build Coastguard Worker partition_name: TEST_PARTITION_HASH_TREE_NAME,
727*d289c2baSAndroid Build Coastguard Worker salt: &decode(TEST_HASHTREE_SALT_HEX).unwrap(),
728*d289c2baSAndroid Build Coastguard Worker root_digest: &decode(TEST_HASHTREE_DIGEST_HEX).unwrap(),
729*d289c2baSAndroid Build Coastguard Worker }),
730*d289c2baSAndroid Build Coastguard Worker );
731*d289c2baSAndroid Build Coastguard Worker }
732*d289c2baSAndroid Build Coastguard Worker
733*d289c2baSAndroid Build Coastguard Worker #[test]
verify_kernel_commandline_descriptor()734*d289c2baSAndroid Build Coastguard Worker fn verify_kernel_commandline_descriptor() {
735*d289c2baSAndroid Build Coastguard Worker verify_and_find_descriptor(
736*d289c2baSAndroid Build Coastguard Worker TEST_VBMETA_WITH_COMMANDLINE_PATH,
737*d289c2baSAndroid Build Coastguard Worker &Descriptor::KernelCommandline(KernelCommandlineDescriptor {
738*d289c2baSAndroid Build Coastguard Worker flags: KernelCommandlineDescriptorFlags(0),
739*d289c2baSAndroid Build Coastguard Worker commandline: TEST_KERNEL_COMMANDLINE,
740*d289c2baSAndroid Build Coastguard Worker }),
741*d289c2baSAndroid Build Coastguard Worker );
742*d289c2baSAndroid Build Coastguard Worker }
743*d289c2baSAndroid Build Coastguard Worker
744*d289c2baSAndroid Build Coastguard Worker #[test]
verify_chain_partition_descriptor()745*d289c2baSAndroid Build Coastguard Worker fn verify_chain_partition_descriptor() {
746*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_two_images_one_vbmeta();
747*d289c2baSAndroid Build Coastguard Worker
748*d289c2baSAndroid Build Coastguard Worker // Set up the fake ops to contain:
749*d289c2baSAndroid Build Coastguard Worker // * the default test image in TEST_PARTITION_NAME
750*d289c2baSAndroid Build Coastguard Worker // * a signed test image with vbmeta footer in TEST_PARTITION_2_NAME
751*d289c2baSAndroid Build Coastguard Worker // * a vbmeta image in "vbmeta" which:
752*d289c2baSAndroid Build Coastguard Worker // * signs the default TEST_PARTITION_NAME image
753*d289c2baSAndroid Build Coastguard Worker // * chains to TEST_PARTITION_2_NAME
754*d289c2baSAndroid Build Coastguard Worker //
755*d289c2baSAndroid Build Coastguard Worker // Since this is an unusual configuration, it's simpler to just set it up manually here
756*d289c2baSAndroid Build Coastguard Worker // rather than try to adapt `verify_and_find_descriptor()` for this one case.
757*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
758*d289c2baSAndroid Build Coastguard Worker "vbmeta",
759*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_VBMETA_WITH_CHAINED_PARTITION_PATH).unwrap(),
760*d289c2baSAndroid Build Coastguard Worker );
761*d289c2baSAndroid Build Coastguard Worker // Replace the chained partition with the combined image + vbmeta footer.
762*d289c2baSAndroid Build Coastguard Worker ops.add_partition(
763*d289c2baSAndroid Build Coastguard Worker TEST_PARTITION_2_NAME,
764*d289c2baSAndroid Build Coastguard Worker fs::read(TEST_IMAGE_WITH_VBMETA_FOOTER_FOR_TEST_PART_2).unwrap(),
765*d289c2baSAndroid Build Coastguard Worker );
766*d289c2baSAndroid Build Coastguard Worker // Add the rollback index for the chained partition's location.
767*d289c2baSAndroid Build Coastguard Worker ops.rollbacks.insert(
768*d289c2baSAndroid Build Coastguard Worker TEST_CHAINED_PARTITION_ROLLBACK_LOCATION,
769*d289c2baSAndroid Build Coastguard Worker Ok(TEST_CHAINED_PARTITION_ROLLBACK_INDEX),
770*d289c2baSAndroid Build Coastguard Worker );
771*d289c2baSAndroid Build Coastguard Worker
772*d289c2baSAndroid Build Coastguard Worker let result = verify_two_images(&mut ops);
773*d289c2baSAndroid Build Coastguard Worker
774*d289c2baSAndroid Build Coastguard Worker let data = result.unwrap();
775*d289c2baSAndroid Build Coastguard Worker // We should have two vbmeta images - one from the "vbmeta" partition, the other embedded
776*d289c2baSAndroid Build Coastguard Worker // in the footer of TEST_PARTITION_2_NAME.
777*d289c2baSAndroid Build Coastguard Worker let vbmetas = data.vbmeta_data();
778*d289c2baSAndroid Build Coastguard Worker assert_eq!(vbmetas.len(), 2);
779*d289c2baSAndroid Build Coastguard Worker // Search for the main vbmeta so we don't assume any particular order.
780*d289c2baSAndroid Build Coastguard Worker let main_vbmeta = vbmetas
781*d289c2baSAndroid Build Coastguard Worker .iter()
782*d289c2baSAndroid Build Coastguard Worker .find(|v| v.partition_name().to_str().unwrap() == "vbmeta")
783*d289c2baSAndroid Build Coastguard Worker .unwrap();
784*d289c2baSAndroid Build Coastguard Worker
785*d289c2baSAndroid Build Coastguard Worker // The main vbmeta should contain the chain descriptor.
786*d289c2baSAndroid Build Coastguard Worker let expected = ChainPartitionDescriptor {
787*d289c2baSAndroid Build Coastguard Worker rollback_index_location: TEST_CHAINED_PARTITION_ROLLBACK_LOCATION as u32,
788*d289c2baSAndroid Build Coastguard Worker partition_name: TEST_PARTITION_2_NAME,
789*d289c2baSAndroid Build Coastguard Worker public_key: &fs::read(TEST_PUBLIC_KEY_RSA8192_PATH).unwrap(),
790*d289c2baSAndroid Build Coastguard Worker flags: ChainPartitionDescriptorFlags(0),
791*d289c2baSAndroid Build Coastguard Worker };
792*d289c2baSAndroid Build Coastguard Worker assert!(main_vbmeta
793*d289c2baSAndroid Build Coastguard Worker .descriptors()
794*d289c2baSAndroid Build Coastguard Worker .unwrap()
795*d289c2baSAndroid Build Coastguard Worker .contains(&Descriptor::ChainPartition(expected)));
796*d289c2baSAndroid Build Coastguard Worker }
797*d289c2baSAndroid Build Coastguard Worker
798*d289c2baSAndroid Build Coastguard Worker #[test]
verify_get_property_value()799*d289c2baSAndroid Build Coastguard Worker fn verify_get_property_value() {
800*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
801*d289c2baSAndroid Build Coastguard Worker ops.add_partition("vbmeta", fs::read(TEST_VBMETA_WITH_PROPERTY_PATH).unwrap());
802*d289c2baSAndroid Build Coastguard Worker
803*d289c2baSAndroid Build Coastguard Worker let data = verify_one_image_one_vbmeta(&mut ops).unwrap();
804*d289c2baSAndroid Build Coastguard Worker
805*d289c2baSAndroid Build Coastguard Worker assert_eq!(
806*d289c2baSAndroid Build Coastguard Worker data.vbmeta_data()[0].get_property_value(TEST_PROPERTY_KEY),
807*d289c2baSAndroid Build Coastguard Worker Some(TEST_PROPERTY_VALUE),
808*d289c2baSAndroid Build Coastguard Worker "Expected valid buffer for the given key"
809*d289c2baSAndroid Build Coastguard Worker );
810*d289c2baSAndroid Build Coastguard Worker }
811*d289c2baSAndroid Build Coastguard Worker
812*d289c2baSAndroid Build Coastguard Worker #[test]
verify_get_property_value_not_found()813*d289c2baSAndroid Build Coastguard Worker fn verify_get_property_value_not_found() {
814*d289c2baSAndroid Build Coastguard Worker let mut ops = build_test_ops_one_image_one_vbmeta();
815*d289c2baSAndroid Build Coastguard Worker ops.add_partition("vbmeta", fs::read(TEST_VBMETA_WITH_PROPERTY_PATH).unwrap());
816*d289c2baSAndroid Build Coastguard Worker
817*d289c2baSAndroid Build Coastguard Worker let data = verify_one_image_one_vbmeta(&mut ops).unwrap();
818*d289c2baSAndroid Build Coastguard Worker
819*d289c2baSAndroid Build Coastguard Worker assert_eq!(
820*d289c2baSAndroid Build Coastguard Worker data.vbmeta_data()[0].get_property_value("test_prop_doesnt_exist"),
821*d289c2baSAndroid Build Coastguard Worker None,
822*d289c2baSAndroid Build Coastguard Worker "Expected property not found for not existing key"
823*d289c2baSAndroid Build Coastguard Worker );
824*d289c2baSAndroid Build Coastguard Worker }
825