1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <endian.h>
18 
19 #include <android-base/unique_fd.h>
20 #include <base/files/file_util.h>
21 #include <base/rand_util.h>
22 #include <base/strings/string_util.h>
23 #include <libavb/libavb.h>
24 
25 #include "avb_util.h"
26 #include "fs_avb/fs_avb_util.h"
27 #include "fs_avb_test_util.h"
28 
29 // Target classes or functions to test:
30 using android::fs_mgr::AvbPartitionToDevicePatition;
31 using android::fs_mgr::DeriveAvbPartitionName;
32 using android::fs_mgr::FstabEntry;
33 using android::fs_mgr::GetAvbFooter;
34 using android::fs_mgr::GetAvbPropertyDescriptor;
35 using android::fs_mgr::GetChainPartitionInfo;
36 using android::fs_mgr::GetTotalSize;
37 using android::fs_mgr::LoadAndVerifyVbmetaByPartition;
38 using android::fs_mgr::LoadAndVerifyVbmetaByPath;
39 using android::fs_mgr::ValidatePublicKeyBlob;
40 using android::fs_mgr::VBMetaData;
41 using android::fs_mgr::VBMetaVerifyResult;
42 using android::fs_mgr::VerifyVBMetaData;
43 using android::fs_mgr::VerifyVBMetaSignature;
44 
45 namespace fs_avb_host_test {
46 
47 class AvbUtilTest : public BaseFsAvbTest {
48   public:
AvbUtilTest()49     AvbUtilTest(){};
50 
51   protected:
~AvbUtilTest()52     ~AvbUtilTest(){};
53     // Helper function for VerifyVBMetaSignature test. Modifies vbmeta.data()
54     // in a number of places at |offset| of size |length| and checks that
55     // VerifyVBMetaSignature() returns |expected_result|.
56     bool TestVBMetaModification(VBMetaVerifyResult expected_result, const VBMetaData& vbmeta,
57                                 size_t offset, size_t length);
58     // Modifies a random bit for a file, in the range of [offset, offset + length - 1].
59     void ModifyFile(const base::FilePath& file_path, size_t offset, ssize_t length);
60 
61     // Loads the content of avb_image_path and comparies it with the content of vbmeta.
62     bool CompareVBMeta(const base::FilePath& avb_image_path, const VBMetaData& expected_vbmeta);
63 
64     // Sets the flas in vbmeta header, the image_path could be a vbmeta.img or a system.img.
65     void SetVBMetaFlags(const base::FilePath& image_path, uint32_t flags);
66 };
67 
SetVBMetaFlags(const base::FilePath & image_path,uint32_t flags)68 void AvbUtilTest::SetVBMetaFlags(const base::FilePath& image_path, uint32_t flags) {
69     if (!base::PathExists(image_path)) return;
70 
71     std::string image_file_name = image_path.RemoveExtension().BaseName().value();
72     bool is_vbmeta_partition =
73         base::StartsWith(image_file_name, "vbmeta", base::CompareCase::INSENSITIVE_ASCII);
74 
75     android::base::unique_fd fd(open(image_path.value().c_str(), O_RDWR | O_CLOEXEC));
76     EXPECT_TRUE(fd > 0);
77 
78     uint64_t vbmeta_offset = 0;  // for vbmeta.img
79     if (!is_vbmeta_partition) {
80         std::unique_ptr<AvbFooter> footer = GetAvbFooter(fd);
81         EXPECT_NE(nullptr, footer);
82         vbmeta_offset = footer->vbmeta_offset;
83     }
84 
85     auto flags_offset = vbmeta_offset + offsetof(AvbVBMetaImageHeader, flags);
86     uint32_t flags_data = htobe32(flags);
87     EXPECT_EQ(flags_offset, lseek64(fd, flags_offset, SEEK_SET));
88     EXPECT_EQ(sizeof flags_data, write(fd, &flags_data, sizeof flags_data));
89 }
90 
TEST_F(AvbUtilTest,AvbPartitionToDevicePatition)91 TEST_F(AvbUtilTest, AvbPartitionToDevicePatition) {
92     EXPECT_EQ("system", AvbPartitionToDevicePatition("system", "", ""));
93     EXPECT_EQ("system", AvbPartitionToDevicePatition("system", "", "_b"));
94 
95     EXPECT_EQ("system_a", AvbPartitionToDevicePatition("system", "_a", ""));
96     EXPECT_EQ("system_a", AvbPartitionToDevicePatition("system", "_a", "_b"));
97 
98     EXPECT_EQ("system_b", AvbPartitionToDevicePatition("system_other", "", "_b"));
99     EXPECT_EQ("system_b", AvbPartitionToDevicePatition("system_other", "_a", "_b"));
100 }
101 
TEST_F(AvbUtilTest,DeriveAvbPartitionName)102 TEST_F(AvbUtilTest, DeriveAvbPartitionName) {
103     // The fstab_entry to test.
104     FstabEntry fstab_entry = {
105             .blk_device = "/dev/block/dm-1",  // a dm-linear device (logical)
106             .logical_partition_name = "system",
107             .mount_point = "/system",
108             .fs_type = "ext4",
109     };
110 
111     // Logical partitions.
112     // non-A/B
113     fstab_entry.fs_mgr_flags.logical = true;
114     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_dont_care"));
115     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
116     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "", ""));
117     // Active slot.
118     fstab_entry.fs_mgr_flags.slot_select = true;
119     fstab_entry.logical_partition_name = "system_a";
120     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_dont_care"));
121     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
122     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", ""));
123     EXPECT_EQ("system_a", DeriveAvbPartitionName(fstab_entry, "_wont_erase_a", "_dont_care"));
124     // The other slot.
125     fstab_entry.fs_mgr_flags.slot_select = false;
126     fstab_entry.fs_mgr_flags.slot_select_other = true;
127     fstab_entry.logical_partition_name = "system_b";
128     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_b"));
129     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
130     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "", "_b"));
131     EXPECT_EQ("system_b_other", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_wont_erase_b"));
132 
133     // Non-logical partitions.
134     // non-A/B.
135     fstab_entry.fs_mgr_flags.logical = false;
136     fstab_entry.fs_mgr_flags.slot_select = false;
137     fstab_entry.fs_mgr_flags.slot_select_other = false;
138     fstab_entry.blk_device = "/dev/block/by-name/system";
139     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_dont_care"));
140     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
141     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "", ""));
142     // Active slot _a.
143     fstab_entry.fs_mgr_flags.slot_select = true;
144     fstab_entry.blk_device = "/dev/block/by-name/system_a";
145     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_dont_care"));
146     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
147     EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", ""));
148     EXPECT_EQ("system_a", DeriveAvbPartitionName(fstab_entry, "_wont_erase_a", "_dont_care"));
149     // Inactive slot _b.
150     fstab_entry.fs_mgr_flags.slot_select = false;
151     fstab_entry.fs_mgr_flags.slot_select_other = true;
152     fstab_entry.blk_device = "/dev/block/by-name/system_b";
153     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "dont_care", "_b"));
154     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
155     EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "", "_b"));
156     EXPECT_EQ("system_b_other", DeriveAvbPartitionName(fstab_entry, "dont_care", "_wont_erase_b"));
157 }
158 
TEST_F(AvbUtilTest,GetFdTotalSize)159 TEST_F(AvbUtilTest, GetFdTotalSize) {
160     // Generates a raw test.img via BaseFsAvbTest.
161     const size_t image_size = 5 * 1024 * 1024;
162     base::FilePath image_path = GenerateImage("test.img", image_size);
163 
164     // Checks file size is as expected via base::GetFileSize().
165     int64_t file_size;
166     ASSERT_TRUE(base::GetFileSize(image_path, &file_size));
167     EXPECT_EQ(image_size, file_size);
168 
169     // Checks file size is expected via libfs_avb internal utils.
170     auto fd = OpenUniqueReadFd(image_path);
171     EXPECT_EQ(image_size, GetTotalSize(fd));
172 }
173 
TEST_F(AvbUtilTest,GetFdTotalSizeWithOffset)174 TEST_F(AvbUtilTest, GetFdTotalSizeWithOffset) {
175     // Generates a raw test.img via BaseFsAvbTest.
176     const size_t image_size = 10 * 1024 * 1024;
177     base::FilePath image_path = GenerateImage("test.img", image_size);
178 
179     // Checks file size is expected even with a non-zero offset at the beginning.
180     auto fd = OpenUniqueReadFd(image_path);
181     off_t initial_offset = 2019;
182     EXPECT_EQ(initial_offset, lseek(fd, initial_offset, SEEK_SET));
183     EXPECT_EQ(image_size, GetTotalSize(fd));            // checks that total size is still returned.
184     EXPECT_EQ(initial_offset, lseek(fd, 0, SEEK_CUR));  // checks original offset is restored.
185 }
186 
TEST_F(AvbUtilTest,GetAvbFooter)187 TEST_F(AvbUtilTest, GetAvbFooter) {
188     // Generates a raw system.img
189     const size_t image_size = 10 * 1024 * 1024;
190     const size_t partition_size = 15 * 1024 * 1024;
191     base::FilePath system_path = GenerateImage("system.img", image_size);
192     EXPECT_NE(0U, system_path.value().size());
193 
194     // Checks image size is as expected.
195     int64_t file_size;
196     ASSERT_TRUE(base::GetFileSize(system_path, &file_size));
197     EXPECT_EQ(image_size, file_size);
198 
199     // Appends AVB Hashtree Footer.
200     AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
201                  data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
202                  "--internal_release_string \"unit test\"");
203 
204     // Checks partition size is as expected, after adding footer.
205     ASSERT_TRUE(base::GetFileSize(system_path, &file_size));
206     EXPECT_EQ(partition_size, file_size);
207 
208     // Checks avb footer and avb vbmeta.
209     EXPECT_EQ(
210             "Footer version:           1.0\n"
211             "Image size:               15728640 bytes\n"
212             "Original image size:      10485760 bytes\n"
213             "VBMeta offset:            10661888\n"
214             "VBMeta size:              3648 bytes\n"
215             "--\n"
216             "Minimum libavb version:   1.0\n"
217             "Header Block:             256 bytes\n"
218             "Authentication Block:     1088 bytes\n"
219             "Auxiliary Block:          2304 bytes\n"
220             "Public key (sha1):        5227b569de003adc7f8ec3fc03e05dfbd969abad\n"
221             "Algorithm:                SHA512_RSA8192\n"
222             "Rollback Index:           20\n"
223             "Flags:                    0\n"
224             "Rollback Index Location:  0\n"
225             "Release String:           'unit test'\n"
226             "Descriptors:\n"
227             "    Hashtree descriptor:\n"
228             "      Version of dm-verity:  1\n"
229             "      Image Size:            10485760 bytes\n"
230             "      Tree Offset:           10485760\n"
231             "      Tree Size:             86016 bytes\n"
232             "      Data Block Size:       4096 bytes\n"
233             "      Hash Block Size:       4096 bytes\n"
234             "      FEC num roots:         2\n"
235             "      FEC offset:            10571776\n"
236             "      FEC size:              90112 bytes\n"
237             "      Hash Algorithm:        sha1\n"
238             "      Partition Name:        system\n"
239             "      Salt:                  d00df00d\n"
240             "      Root Digest:           a3d5dd307341393d85de356c384ff543ec1ed81b\n"
241             "      Flags:                 0\n",
242             InfoImage(system_path));
243 
244     // Checks each field from GetAvbFooter(fd).
245     auto fd = OpenUniqueReadFd(system_path);
246     auto footer = GetAvbFooter(fd);
247     EXPECT_NE(nullptr, footer);
248     EXPECT_EQ(10485760, footer->original_image_size);
249     EXPECT_EQ(10661888, footer->vbmeta_offset);
250     EXPECT_EQ(3648, footer->vbmeta_size);
251 }
252 
TEST_F(AvbUtilTest,GetAvbFooterErrorVerification)253 TEST_F(AvbUtilTest, GetAvbFooterErrorVerification) {
254     // Generates a raw system.img
255     const size_t image_size = 5 * 1024 * 1024;
256     base::FilePath system_path = GenerateImage("system.img", image_size);
257 
258     // Checks each field from GetAvbFooter(fd).
259     auto fd = OpenUniqueReadFd(system_path);
260     auto footer = GetAvbFooter(fd);
261     EXPECT_EQ(nullptr, footer);
262 }
263 
TEST_F(AvbUtilTest,GetAvbFooterInsufficientSize)264 TEST_F(AvbUtilTest, GetAvbFooterInsufficientSize) {
265     // Generates a raw system.img
266     const size_t image_size = AVB_FOOTER_SIZE - 10;
267     base::FilePath system_path = GenerateImage("system.img", image_size);
268 
269     // Checks each field from GetAvbFooter(fd).
270     auto fd = OpenUniqueReadFd(system_path);
271     auto footer = GetAvbFooter(fd);
272     EXPECT_EQ(nullptr, footer);
273 }
274 
TEST_F(AvbUtilTest,GetAvbPropertyDescriptor_Basic)275 TEST_F(AvbUtilTest, GetAvbPropertyDescriptor_Basic) {
276     // Makes a vbmeta.img with some properties.
277     GenerateVBMetaImage("vbmeta.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
278                         {}, /* include_descriptor_image_paths */
279                         {}, /* chain_partitions */
280                         "--prop foo:android "
281                         "--prop bar:treble "
282                         "--internal_release_string \"unit test\" ");
283     auto vbmeta = LoadVBMetaData("vbmeta.img");
284 
285     // Puts the vbmeta into a vector, for GetAvbPropertyDescriptor to use.
286     std::vector<VBMetaData> vbmeta_images;
287     vbmeta_images.emplace_back(std::move(vbmeta));
288 
289     EXPECT_EQ("android", GetAvbPropertyDescriptor("foo", vbmeta_images));
290     EXPECT_EQ("treble", GetAvbPropertyDescriptor("bar", vbmeta_images));
291     EXPECT_EQ("", GetAvbPropertyDescriptor("non-existent", vbmeta_images));
292 }
293 
TEST_F(AvbUtilTest,GetAvbPropertyDescriptor_SecurityPatchLevel)294 TEST_F(AvbUtilTest, GetAvbPropertyDescriptor_SecurityPatchLevel) {
295     // Generates a raw boot.img
296     const size_t boot_image_size = 5 * 1024 * 1024;
297     const size_t boot_partition_size = 10 * 1024 * 1024;
298     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
299     // Adds AVB Hash Footer.
300     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
301                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
302                  "--internal_release_string \"unit test\"");
303 
304     // Generates a raw system.img, use a smaller size to speed-up unit test.
305     const size_t system_image_size = 10 * 1024 * 1024;
306     const size_t system_partition_size = 15 * 1024 * 1024;
307     base::FilePath system_path = GenerateImage("system.img", system_image_size);
308     // Adds AVB Hashtree Footer.
309     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
310                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
311                  "--prop com.android.build.system.security_patch:2019-04-05 "
312                  "--internal_release_string \"unit test\"");
313 
314     // Generates chain partition descriptors.
315     base::FilePath rsa4096_public_key =
316             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
317 
318     // Makes a vbmeta.img including the 'system' chained descriptor.
319     GenerateVBMetaImage("vbmeta.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
320                         {boot_path},                         /* include_descriptor_image_paths */
321                         {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
322                         "--internal_release_string \"unit test\"");
323 
324     auto vbmeta = LoadVBMetaData("vbmeta.img");
325     auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system-vbmeta.img");
326 
327     // Puts the vbmeta into a vector, for GetAvbPropertyDescriptor to use.
328     std::vector<VBMetaData> vbmeta_images;
329     vbmeta_images.emplace_back(std::move(vbmeta));
330     vbmeta_images.emplace_back(std::move(system_vbmeta));
331 
332     EXPECT_EQ("2019-04-05",
333               GetAvbPropertyDescriptor("com.android.build.system.security_patch", vbmeta_images));
334 }
335 
TEST_F(AvbUtilTest,GetVBMetaHeader)336 TEST_F(AvbUtilTest, GetVBMetaHeader) {
337     // Generates a raw boot.img
338     const size_t image_size = 5 * 1024 * 1024;
339     const size_t partition_size = 10 * 1024 * 1024;
340     base::FilePath boot_path = GenerateImage("boot.img", image_size);
341     // Appends AVB Hash Footer.
342     AddAvbFooter(boot_path, "hash", "boot", partition_size, "SHA256_RSA4096", 10,
343                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
344                  "--internal_release_string \"unit test\"");
345     // Extracts boot vbmeta from boot.img into boot-vbmeta.img.
346     base::FilePath boot_vbmeta = ExtractVBMetaImage(boot_path, "boot-vbmeta.img");
347     EXPECT_EQ(
348             "Minimum libavb version:   1.0\n"
349             "Header Block:             256 bytes\n"
350             "Authentication Block:     576 bytes\n"
351             "Auxiliary Block:          1216 bytes\n"
352             "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
353             "Algorithm:                SHA256_RSA4096\n"
354             "Rollback Index:           10\n"
355             "Flags:                    0\n"
356             "Rollback Index Location:  0\n"
357             "Release String:           'unit test'\n"
358             "Descriptors:\n"
359             "    Hash descriptor:\n"
360             "      Image Size:            5242880 bytes\n"
361             "      Hash Algorithm:        sha256\n"
362             "      Partition Name:        boot\n"
363             "      Salt:                  d00df00d\n"
364             "      Digest:                "
365             "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n"
366             "      Flags:                 0\n",
367             InfoImage("boot-vbmeta.img"));
368 
369     // Creates a VBMetaData with the content from boot-vbmeta.img.
370     std::string content;
371     EXPECT_TRUE(base::ReadFileToString(boot_vbmeta, &content));
372     VBMetaData vbmeta((uint8_t*)content.data(), content.size(), "boot-vbmeta");
373     EXPECT_EQ(content.size(), vbmeta.size());
374 
375     // Checks each field returned from GetVBMetaHeader().
376     auto vbmeta_header = vbmeta.GetVBMetaHeader(false /* update_vbmeta_size */);
377     EXPECT_NE(nullptr, vbmeta_header);
378     EXPECT_EQ(576, vbmeta_header->authentication_data_block_size);
379     EXPECT_EQ(1216, vbmeta_header->auxiliary_data_block_size);
380     EXPECT_EQ(AVB_ALGORITHM_TYPE_SHA256_RSA4096, vbmeta_header->algorithm_type);
381     EXPECT_EQ(0, vbmeta_header->hash_offset);
382     EXPECT_EQ(32, vbmeta_header->hash_size);
383     EXPECT_EQ(32, vbmeta_header->signature_offset);
384     EXPECT_EQ(512, vbmeta_header->signature_size);
385     EXPECT_EQ(176, vbmeta_header->public_key_offset);
386     EXPECT_EQ(1032, vbmeta_header->public_key_size);
387     EXPECT_EQ(0, vbmeta_header->descriptors_offset);
388     EXPECT_EQ(176, vbmeta_header->descriptors_size);
389     EXPECT_EQ(10, vbmeta_header->rollback_index);
390     EXPECT_EQ(0, vbmeta_header->flags);
391     EXPECT_EQ("unit test", std::string((const char*)vbmeta_header->release_string));
392 
393     // Appends some garbage to the end of the vbmeta buffer, checks it still can work.
394     std::string padding(2020, 'A');  // Generate a padding with length 2020.
395     std::string content_padding = content + padding;
396     VBMetaData vbmeta_padding((const uint8_t*)content_padding.data(), content_padding.size(),
397                               "boot");
398     EXPECT_EQ(content_padding.size(), vbmeta_padding.size());
399 
400     // Checks each field still can be parsed properly, even with garbage padding.
401     vbmeta_header = vbmeta_padding.GetVBMetaHeader(false /* update_vbmeta_size */);
402     EXPECT_NE(nullptr, vbmeta_header);
403     EXPECT_EQ(576, vbmeta_header->authentication_data_block_size);
404     EXPECT_EQ(1216, vbmeta_header->auxiliary_data_block_size);
405     EXPECT_EQ(AVB_ALGORITHM_TYPE_SHA256_RSA4096, vbmeta_header->algorithm_type);
406     EXPECT_EQ(0, vbmeta_header->hash_offset);
407     EXPECT_EQ(32, vbmeta_header->hash_size);
408     EXPECT_EQ(32, vbmeta_header->signature_offset);
409     EXPECT_EQ(512, vbmeta_header->signature_size);
410     EXPECT_EQ(176, vbmeta_header->public_key_offset);
411     EXPECT_EQ(1032, vbmeta_header->public_key_size);
412     EXPECT_EQ(0, vbmeta_header->descriptors_offset);
413     EXPECT_EQ(176, vbmeta_header->descriptors_size);
414     EXPECT_EQ(10, vbmeta_header->rollback_index);
415     EXPECT_EQ(0, vbmeta_header->flags);
416     EXPECT_EQ("unit test", std::string((const char*)vbmeta_header->release_string));
417 
418     // Checks vbmeta size is updated to the actual size without padding.
419     vbmeta_header = vbmeta_padding.GetVBMetaHeader(true /* update_vbmeta_size */);
420     EXPECT_EQ(content_padding.size() - padding.size(), vbmeta_padding.size());
421 }
422 
TEST_F(AvbUtilTest,ValidatePublicKeyBlob)423 TEST_F(AvbUtilTest, ValidatePublicKeyBlob) {
424     // Generates a raw key.bin
425     const size_t key_size = 2048;
426     base::FilePath key_path = GenerateImage("key.bin", key_size);
427 
428     uint8_t key_data[key_size];
429     EXPECT_EQ(key_size, base::ReadFile(key_path, (char*)key_data, key_size));
430 
431     std::string expected_key_blob;
432     EXPECT_TRUE(base::ReadFileToString(key_path, &expected_key_blob));
433     EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
434 
435     key_data[10] ^= 0x80;  // toggles a bit and expects a failure
436     EXPECT_FALSE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
437     key_data[10] ^= 0x80;  // toggles the bit again, should pass
438     EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
439 }
440 
TEST_F(AvbUtilTest,VerifyEmptyPublicKeyBlob)441 TEST_F(AvbUtilTest, VerifyEmptyPublicKeyBlob) {
442     // Generates a raw key.bin
443     const size_t key_size = 2048;
444     base::FilePath key_path = GenerateImage("key.bin", key_size);
445 
446     uint8_t key_data[key_size];
447     EXPECT_EQ(key_size, base::ReadFile(key_path, (char*)key_data, key_size));
448 
449     std::string expected_key_blob = "";  // empty means no expectation, thus return true.
450     EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
451 }
452 
TEST_F(AvbUtilTest,ValidatePublicKeyBlob_MultipleAllowedKeys)453 TEST_F(AvbUtilTest, ValidatePublicKeyBlob_MultipleAllowedKeys) {
454     base::FilePath rsa2048_public_key =
455             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
456     base::FilePath rsa4096_public_key =
457             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
458     base::FilePath rsa8192_public_key =
459             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa8192.pem"));
460 
461     std::vector<std::string> allowed_key_paths;
462     allowed_key_paths.push_back(rsa2048_public_key.value());
463     allowed_key_paths.push_back(rsa4096_public_key.value());
464 
465     std::string expected_key_blob_2048;
466     EXPECT_TRUE(base::ReadFileToString(rsa2048_public_key, &expected_key_blob_2048));
467     std::string expected_key_blob_4096;
468     EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
469     std::string expected_key_blob_8192;
470     EXPECT_TRUE(base::ReadFileToString(rsa8192_public_key, &expected_key_blob_8192));
471 
472     EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_2048, allowed_key_paths));
473     EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_4096, allowed_key_paths));
474 
475     EXPECT_FALSE(ValidatePublicKeyBlob(expected_key_blob_8192, allowed_key_paths));
476     EXPECT_FALSE(ValidatePublicKeyBlob("invalid_content", allowed_key_paths));
477     EXPECT_FALSE(ValidatePublicKeyBlob("", allowed_key_paths));
478 
479     allowed_key_paths.push_back(rsa8192_public_key.value());
480     EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_8192, allowed_key_paths));
481 }
482 
TEST_F(AvbUtilTest,VerifyVBMetaSignature)483 TEST_F(AvbUtilTest, VerifyVBMetaSignature) {
484     const size_t image_size = 10 * 1024 * 1024;
485     const size_t partition_size = 15 * 1024 * 1024;
486     auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
487     auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
488                                                     "hashtree", signing_key, "SHA256_RSA4096",
489                                                     10 /* rollback_index */);
490 
491     auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
492     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
493               VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
494                                     nullptr /* out_public_key_data */));
495 
496     // Converts the expected key into an 'unexpected' key.
497     expected_public_key_blob[10] ^= 0x80;
498     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
499               VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
500                                     nullptr /* out_public_key_data */));
501 }
502 
TEST_F(AvbUtilTest,VerifyVBMetaSignatureOutputPublicKeyData)503 TEST_F(AvbUtilTest, VerifyVBMetaSignatureOutputPublicKeyData) {
504     const size_t image_size = 10 * 1024 * 1024;
505     const size_t partition_size = 15 * 1024 * 1024;
506     auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
507     auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
508                                                     "hashtree", signing_key, "SHA256_RSA4096",
509                                                     10 /* rollback_index */);
510     std::string out_public_key_data;
511     auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
512     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
513               VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
514     EXPECT_EQ(out_public_key_data, expected_public_key_blob);
515 
516     // Converts the expected key into an 'unexpected' key.
517     expected_public_key_blob[10] ^= 0x80;
518     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
519               VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
520     EXPECT_NE(out_public_key_data, expected_public_key_blob);
521 }
522 
TestVBMetaModification(VBMetaVerifyResult expected_result,const VBMetaData & vbmeta,size_t offset,size_t length)523 bool AvbUtilTest::TestVBMetaModification(VBMetaVerifyResult expected_result,
524                                          const VBMetaData& vbmeta, size_t offset, size_t length) {
525     uint8_t* d = reinterpret_cast<uint8_t*>(vbmeta.data());
526     const int kNumCheckIntervals = 8;
527 
528     // Tests |kNumCheckIntervals| modifications in the start, middle, and
529     // end of the given sub-array at offset with size.
530     for (int n = 0; n <= kNumCheckIntervals; n++) {
531         size_t o = std::min(length * n / kNumCheckIntervals, length - 1) + offset;
532         d[o] ^= 0x80;
533         VBMetaVerifyResult result = VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
534                                                           nullptr /* out_public_key_data */);
535         d[o] ^= 0x80;
536         if (result != expected_result) {
537             return false;
538         }
539     }
540 
541     return true;
542 }
543 
TEST_F(AvbUtilTest,VerifyVBMetaSignatureWithModification)544 TEST_F(AvbUtilTest, VerifyVBMetaSignatureWithModification) {
545     const size_t image_size = 10 * 1024 * 1024;
546     const size_t partition_size = 15 * 1024 * 1024;
547     auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
548     auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
549                                                     "hashtree", signing_key, "SHA256_RSA4096",
550                                                     10 /* rollback_index */);
551 
552     auto header = vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
553     size_t header_block_offset = 0;
554     size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
555     size_t auxiliary_block_offset =
556             authentication_block_offset + header->authentication_data_block_size;
557 
558     // Should detect modifications in the auxiliary data block.
559     EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
560                                        auxiliary_block_offset, header->auxiliary_data_block_size));
561 
562     // Sholud detect modifications in the hash part of authentication data block.
563     EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
564                                        authentication_block_offset + header->hash_offset,
565                                        header->hash_size));
566 
567     // Sholud detect modifications in the signature part of authentication data block.
568     EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
569                                        authentication_block_offset + header->signature_offset,
570                                        header->signature_size));
571 }
572 
TEST_F(AvbUtilTest,VerifyVBMetaSignatureNotSigned)573 TEST_F(AvbUtilTest, VerifyVBMetaSignatureNotSigned) {
574     const size_t image_size = 10 * 1024 * 1024;
575     const size_t partition_size = 15 * 1024 * 1024;
576     auto vbmeta = GenerateImageAndExtractVBMetaData(
577             "system", image_size, partition_size, "hashtree", {} /* avb_signing_key */,
578             "" /* avb_algorithm */, 10 /* rollback_index */);
579 
580     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
581               VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
582                                     nullptr /* out_public_key_data */));
583 }
584 
TEST_F(AvbUtilTest,VerifyVBMetaSignatureInvalidVBMeta)585 TEST_F(AvbUtilTest, VerifyVBMetaSignatureInvalidVBMeta) {
586     const size_t buffer_size = 5 * 1024 * 1024;
587     std::vector<uint8_t> vbmeta_buffer(buffer_size);
588     for (size_t n = 0; n < buffer_size; n++) {
589         vbmeta_buffer[n] = uint8_t(n);
590     }
591 
592     VBMetaData invalid_vbmeta((const uint8_t*)vbmeta_buffer.data(), vbmeta_buffer.size(),
593                               "invalid_vbmeta");
594     EXPECT_EQ(VBMetaVerifyResult::kError,
595               VerifyVBMetaSignature(invalid_vbmeta, "" /* expected_public_key_blob */,
596                                     nullptr /* out_public_Key_data */));
597 }
598 
CompareVBMeta(const base::FilePath & avb_image_path,const VBMetaData & expected_vbmeta)599 bool AvbUtilTest::CompareVBMeta(const base::FilePath& avb_image_path,
600                                 const VBMetaData& expected_vbmeta) {
601     if (!base::PathExists(avb_image_path)) return false;
602 
603     std::string image_file_name = avb_image_path.RemoveExtension().BaseName().value();
604 
605     base::FilePath extracted_vbmeta_path;
606     if (base::StartsWith(image_file_name, "vbmeta", base::CompareCase::INSENSITIVE_ASCII)) {
607         extracted_vbmeta_path = avb_image_path;  // no need to extract if it's a vbmeta image.
608     } else {
609         extracted_vbmeta_path = ExtractVBMetaImage(avb_image_path, image_file_name + "-vbmeta.img");
610     }
611 
612     // Gets file size of the vbmeta image.
613     int64_t extracted_vbmeta_size;
614     EXPECT_TRUE(base::GetFileSize(extracted_vbmeta_path, &extracted_vbmeta_size));
615 
616     // Reads the vbmeta into a vector.
617     std::vector<uint8_t> extracted_vbmeta_content(extracted_vbmeta_size);
618     EXPECT_TRUE(base::ReadFile(extracted_vbmeta_path,
619                                reinterpret_cast<char*>(extracted_vbmeta_content.data()),
620                                extracted_vbmeta_size));
621 
622     // Compares extracted_vbmeta_content with the expected_vbmeta.
623     EXPECT_EQ(expected_vbmeta.size(), extracted_vbmeta_size);
624     return memcmp(reinterpret_cast<void*>(extracted_vbmeta_content.data()),
625                   reinterpret_cast<void*>(expected_vbmeta.data()), extracted_vbmeta_size) == 0;
626 }
627 
TEST_F(AvbUtilTest,VerifyVBMetaDataWithoutFooter)628 TEST_F(AvbUtilTest, VerifyVBMetaDataWithoutFooter) {
629     // Generates chain partition descriptors.
630     base::FilePath rsa2048_public_key =
631             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
632     base::FilePath rsa4096_public_key =
633             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
634 
635     // Makes a vbmeta image includeing 'boot' and 'system' chained descriptors.
636     auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
637                                            data_dir_.Append("testkey_rsa8192.pem"),
638                                            {}, /* include_descriptor_image_paths */
639                                            {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
640                                             {"system", 2, rsa4096_public_key}},
641                                            "--internal_release_string \"unit test\"");
642     EXPECT_EQ(
643             "Minimum libavb version:   1.0\n"
644             "Header Block:             256 bytes\n"
645             "Authentication Block:     1088 bytes\n"
646             "Auxiliary Block:          3840 bytes\n"
647             "Public key (sha1):        5227b569de003adc7f8ec3fc03e05dfbd969abad\n"
648             "Algorithm:                SHA256_RSA8192\n"
649             "Rollback Index:           0\n"
650             "Flags:                    0\n"
651             "Rollback Index Location:  0\n"
652             "Release String:           'unit test'\n"
653             "Descriptors:\n"
654             "    Chain Partition descriptor:\n"
655             "      Partition Name:          boot\n"
656             "      Rollback Index Location: 1\n"
657             "      Public key (sha1):       cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
658             "    Chain Partition descriptor:\n"
659             "      Partition Name:          system\n"
660             "      Rollback Index Location: 2\n"
661             "      Public key (sha1):       2597c218aae470a130f61162feaae70afd97f011\n",
662             InfoImage("vbmeta.img"));
663 
664     android::base::unique_fd fd(open(vbmeta_path.value().c_str(), O_RDONLY | O_CLOEXEC));
665     ASSERT_TRUE(fd > 0);
666 
667     VBMetaVerifyResult verify_result;
668     std::string out_public_key_data;
669     std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
670             fd, "vbmeta", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
671     EXPECT_TRUE(vbmeta != nullptr);
672     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
673 
674     auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
675     EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
676 
677     // Checkes the returned vbmeta content is the same as that extracted via avbtool.
678     vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
679     EXPECT_TRUE(CompareVBMeta(vbmeta_path, *vbmeta));
680 }
681 
TEST_F(AvbUtilTest,VerifyVBMetaDataWithFooter)682 TEST_F(AvbUtilTest, VerifyVBMetaDataWithFooter) {
683     const size_t image_size = 10 * 1024 * 1024;
684     const size_t partition_size = 15 * 1024 * 1024;
685     base::FilePath system_path = GenerateImage("system.img", image_size);
686 
687     // Appends AVB Hashtree Footer.
688     AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
689                  data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
690                  "--internal_release_string \"unit test\"");
691 
692     android::base::unique_fd fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
693     ASSERT_TRUE(fd > 0);
694 
695     VBMetaVerifyResult verify_result;
696     std::string out_public_key_data;
697     std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
698             fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
699     EXPECT_TRUE(vbmeta != nullptr);
700     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
701 
702     auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
703     EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
704 
705     // Checkes the returned vbmeta content is the same as that extracted via avbtool.
706     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
707 }
708 
709 // Modifies a random bit for a file, in the range of [offset, offset + length - 1].
710 // Length < 0 means only resets previous modification without introducing new modification.
ModifyFile(const base::FilePath & file_path,size_t offset,ssize_t length)711 void AvbUtilTest::ModifyFile(const base::FilePath& file_path, size_t offset, ssize_t length) {
712     static int last_modified_location = -1;
713     static std::string last_file_path;
714 
715     int64_t file_size;
716     ASSERT_TRUE(base::GetFileSize(file_path, &file_size));
717 
718     std::vector<uint8_t> file_content(file_size);
719     ASSERT_TRUE(base::ReadFile(file_path, reinterpret_cast<char*>(file_content.data()), file_size));
720 
721     // Resets previous modification for consecutive calls on the same file.
722     if (last_file_path == file_path.value()) {
723         file_content[last_modified_location] ^= 0x80;
724     }
725 
726     // Introduces a new modification.
727     if (length > 0) {
728         int modify_location = base::RandInt(offset, offset + length - 1);
729         file_content[modify_location] ^= 0x80;
730         last_file_path = file_path.value();
731         last_modified_location = modify_location;
732     }
733 
734     ASSERT_EQ(file_size, static_cast<const size_t>(base::WriteFile(
735                                  file_path, reinterpret_cast<const char*>(file_content.data()),
736                                  file_content.size())));
737 }
738 
TEST_F(AvbUtilTest,VerifyVBMetaDataError)739 TEST_F(AvbUtilTest, VerifyVBMetaDataError) {
740     const size_t image_size = 10 * 1024 * 1024;
741     const size_t partition_size = 15 * 1024 * 1024;
742     base::FilePath system_path = GenerateImage("system.img", image_size);
743 
744     // Appends AVB Hashtree Footer.
745     AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
746                  data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
747                  "--internal_release_string \"unit test\"");
748 
749     android::base::unique_fd fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
750     ASSERT_TRUE(fd > 0);
751 
752     std::unique_ptr<AvbFooter> footer = GetAvbFooter(fd);
753     EXPECT_TRUE(footer != nullptr);
754 
755     VBMetaVerifyResult verify_result;
756     std::string out_public_key_data;
757     std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
758             fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
759     ASSERT_EQ(0, close(fd.release()));
760     EXPECT_NE(nullptr, vbmeta);
761     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
762 
763     auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
764     EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
765 
766     // Modifies hash and signature, checks there is verification error.
767     auto header = vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
768     size_t header_block_offset = 0;
769     size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
770 
771     // Modifies the hash.
772     ModifyFile(system_path,
773                footer->vbmeta_offset + authentication_block_offset + header->hash_offset,
774                header->hash_size);
775     android::base::unique_fd hash_modified_fd(
776             open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
777     ASSERT_TRUE(hash_modified_fd > 0);
778     // Should return ErrorVerification.
779     vbmeta = VerifyVBMetaData(hash_modified_fd, "system", "" /*expected_public_key_blob */,
780                               nullptr /* out_public_key_data */, &verify_result);
781     ASSERT_EQ(0, close(hash_modified_fd.release()));
782     EXPECT_NE(nullptr, vbmeta);
783     // EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta)); // b/187303962.
784     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
785 
786     // Modifies the auxiliary data block.
787     size_t auxiliary_block_offset =
788             authentication_block_offset + header->authentication_data_block_size;
789     ModifyFile(system_path, footer->vbmeta_offset + auxiliary_block_offset,
790                header->auxiliary_data_block_size);
791     android::base::unique_fd aux_modified_fd(
792             open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
793     ASSERT_TRUE(aux_modified_fd > 0);
794     // Should return ErrorVerification.
795     vbmeta = VerifyVBMetaData(aux_modified_fd, "system", "" /*expected_public_key_blob */,
796                               nullptr /* out_public_key_data */, &verify_result);
797     ASSERT_EQ(0, close(aux_modified_fd.release()));
798     EXPECT_NE(nullptr, vbmeta);
799     // EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta)); // b/187303962.
800     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
801 
802     // Resets previous modification by setting offset to -1, and checks the verification can pass.
803     ModifyFile(system_path, 0 /* offset */, -1 /* length */);
804     android::base::unique_fd ok_fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
805     ASSERT_TRUE(ok_fd > 0);
806     // Should return ResultOK..
807     vbmeta = VerifyVBMetaData(ok_fd, "system", "" /*expected_public_key_blob */,
808                               nullptr /* out_public_key_data */, &verify_result);
809     ASSERT_EQ(0, close(ok_fd.release()));
810     EXPECT_NE(nullptr, vbmeta);
811     // EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta)); // b/187303962.
812     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
813 }
814 
TEST_F(AvbUtilTest,GetChainPartitionInfo)815 TEST_F(AvbUtilTest, GetChainPartitionInfo) {
816     // Generates a raw boot.img
817     const size_t boot_image_size = 5 * 1024 * 1024;
818     const size_t boot_partition_size = 10 * 1024 * 1024;
819     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
820     // Adds AVB Hash Footer.
821     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
822                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
823                  "--internal_release_string \"unit test\"");
824 
825     // Generates a raw system.img, use a smaller size to speed-up unit test.
826     const size_t system_image_size = 10 * 1024 * 1024;
827     const size_t system_partition_size = 15 * 1024 * 1024;
828     base::FilePath system_path = GenerateImage("system.img", system_image_size);
829     // Adds AVB Hashtree Footer.
830     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
831                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
832                  "--internal_release_string \"unit test\"");
833 
834     // Generates chain partition descriptors.
835     base::FilePath rsa2048_public_key =
836             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
837     base::FilePath rsa4096_public_key =
838             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
839     // Makes a vbmeta_system.img including the 'system' chained descriptor.
840     GenerateVBMetaImage("vbmeta_system.img", "SHA256_RSA4096", 0,
841                         data_dir_.Append("testkey_rsa4096.pem"),
842                         {},                                  /* include_descriptor_image_paths */
843                         {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
844                         "--internal_release_string \"unit test\"");
845 
846     // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
847     GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0, data_dir_.Append("testkey_rsa8192.pem"),
848                         {},                               /* include_descriptor_image_paths */
849                         {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
850                          {"vbmeta_system", 2, rsa4096_public_key}},
851                         "--internal_release_string \"unit test\"");
852 
853     // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
854     EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
855               CalcVBMetaDigest("vbmeta.img", "sha256"));
856     // Loads the key blobs for comparison.
857     std::string expected_key_blob_2048;
858     EXPECT_TRUE(base::ReadFileToString(rsa2048_public_key, &expected_key_blob_2048));
859     std::string expected_key_blob_4096;
860     EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
861 
862     // Checks chain descriptors in vbmeta.img
863     EXPECT_EQ(
864             "Minimum libavb version:   1.0\n"
865             "Header Block:             256 bytes\n"
866             "Authentication Block:     1088 bytes\n"
867             "Auxiliary Block:          3840 bytes\n"
868             "Public key (sha1):        5227b569de003adc7f8ec3fc03e05dfbd969abad\n"
869             "Algorithm:                SHA256_RSA8192\n"
870             "Rollback Index:           0\n"
871             "Flags:                    0\n"
872             "Rollback Index Location:  0\n"
873             "Release String:           'unit test'\n"
874             "Descriptors:\n"
875             "    Chain Partition descriptor:\n"
876             "      Partition Name:          boot\n"
877             "      Rollback Index Location: 1\n"
878             "      Public key (sha1):       cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
879             "    Chain Partition descriptor:\n"
880             "      Partition Name:          vbmeta_system\n"
881             "      Rollback Index Location: 2\n"
882             "      Public key (sha1):       2597c218aae470a130f61162feaae70afd97f011\n",
883             InfoImage("vbmeta.img"));
884 
885     bool fatal_error = false;
886     auto chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta.img"), &fatal_error);
887     EXPECT_EQ(2, chained_descriptors.size());  // contains 'boot' and 'vbmeta_system'.
888     EXPECT_EQ(false, fatal_error);
889 
890     EXPECT_EQ("boot", chained_descriptors[0].partition_name);
891     EXPECT_EQ(expected_key_blob_2048, chained_descriptors[0].public_key_blob);
892 
893     EXPECT_EQ("vbmeta_system", chained_descriptors[1].partition_name);
894     EXPECT_EQ(expected_key_blob_4096, chained_descriptors[1].public_key_blob);
895 
896     // Checks chain descriptors in vbmeta_system.img
897     EXPECT_EQ(
898             "Minimum libavb version:   1.0\n"
899             "Header Block:             256 bytes\n"
900             "Authentication Block:     576 bytes\n"
901             "Auxiliary Block:          2176 bytes\n"
902             "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
903             "Algorithm:                SHA256_RSA4096\n"
904             "Rollback Index:           0\n"
905             "Flags:                    0\n"
906             "Rollback Index Location:  0\n"
907             "Release String:           'unit test'\n"
908             "Descriptors:\n"
909             "    Chain Partition descriptor:\n"
910             "      Partition Name:          system\n"
911             "      Rollback Index Location: 3\n"
912             "      Public key (sha1):       2597c218aae470a130f61162feaae70afd97f011\n",
913             InfoImage("vbmeta_system.img"));
914 
915     chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta_system.img"), &fatal_error);
916     EXPECT_EQ(1, chained_descriptors.size());  // contains 'system' only.
917     EXPECT_EQ(false, fatal_error);
918     EXPECT_EQ("system", chained_descriptors[0].partition_name);
919     EXPECT_EQ(expected_key_blob_4096, chained_descriptors[0].public_key_blob);
920 }
921 
TEST_F(AvbUtilTest,GetChainPartitionInfoNone)922 TEST_F(AvbUtilTest, GetChainPartitionInfoNone) {
923     // Generates a raw boot.img
924     const size_t boot_image_size = 5 * 1024 * 1024;
925     const size_t boot_partition_size = 10 * 1024 * 1024;
926     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
927     // Adds AVB Hash Footer.
928     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA4096", 10,
929                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
930                  "--internal_release_string \"unit test\"");
931 
932     // Generates a raw system.img, use a smaller size to speed-up unit test.
933     const size_t system_image_size = 10 * 1024 * 1024;
934     const size_t system_partition_size = 15 * 1024 * 1024;
935     base::FilePath system_path = GenerateImage("system.img", system_image_size);
936     // Adds AVB Hashtree Footer.
937     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA8192", 20,
938                  data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
939                  "--internal_release_string \"unit test\"");
940 
941     // Makes a vbmeta.img including both 'boot' and 'system' descriptors.
942     GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0, data_dir_.Append("testkey_rsa2048.pem"),
943                         {boot_path, system_path}, /* include_descriptor_image_paths */
944                         {},                       /* chain_partitions */
945                         "--internal_release_string \"unit test\"");
946     EXPECT_EQ("a069cbfc30c816cddf3b53f1ad53b7ca5d61a3d93845eb596bbb1b40caa1c62f",
947               CalcVBMetaDigest("vbmeta.img", "sha256"));
948 
949     EXPECT_EQ(
950             "Minimum libavb version:   1.0\n"
951             "Header Block:             256 bytes\n"
952             "Authentication Block:     320 bytes\n"
953             "Auxiliary Block:          960 bytes\n"
954             "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
955             "Algorithm:                SHA256_RSA2048\n"
956             "Rollback Index:           0\n"
957             "Flags:                    0\n"
958             "Rollback Index Location:  0\n"
959             "Release String:           'unit test'\n"
960             "Descriptors:\n"
961             "    Hash descriptor:\n"
962             "      Image Size:            5242880 bytes\n"
963             "      Hash Algorithm:        sha256\n"
964             "      Partition Name:        boot\n"
965             "      Salt:                  d00df00d\n"
966             "      Digest:                "
967             "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n"
968             "      Flags:                 0\n"
969             "    Hashtree descriptor:\n"
970             "      Version of dm-verity:  1\n"
971             "      Image Size:            10485760 bytes\n"
972             "      Tree Offset:           10485760\n"
973             "      Tree Size:             86016 bytes\n"
974             "      Data Block Size:       4096 bytes\n"
975             "      Hash Block Size:       4096 bytes\n"
976             "      FEC num roots:         2\n"
977             "      FEC offset:            10571776\n"
978             "      FEC size:              90112 bytes\n"
979             "      Hash Algorithm:        sha1\n"
980             "      Partition Name:        system\n"
981             "      Salt:                  d00df00d\n"
982             "      Root Digest:           a3d5dd307341393d85de356c384ff543ec1ed81b\n"
983             "      Flags:                 0\n",
984             InfoImage("vbmeta.img"));
985 
986     // Checks none of chain descriptors is found.
987     bool fatal_error = false;
988     auto chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta.img"), &fatal_error);
989     EXPECT_EQ(0, chained_descriptors.size());  // There is no chain descriptors.
990     EXPECT_EQ(false, fatal_error);
991 }
992 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPath)993 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPath) {
994     // Generates a raw system_other.img, use a smaller size to speed-up unit test.
995     const size_t system_image_size = 10 * 1024 * 1024;
996     const size_t system_partition_size = 15 * 1024 * 1024;
997     base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
998 
999     // Adds AVB Hashtree Footer.
1000     AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1001                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1002                  "--internal_release_string \"unit test\"");
1003 
1004     std::string expected_key_blob_4096 =
1005             ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
1006 
1007     bool verification_disabled;
1008     VBMetaVerifyResult verify_result;
1009     std::string out_public_key_data;
1010     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1011             system_path.value(), "system_other", expected_key_blob_4096,
1012             false /* allow_verification_error */, false /* rollback_protection */,
1013             false /* is_chained_vbmeta */, &out_public_key_data, &verification_disabled,
1014             &verify_result);
1015 
1016     EXPECT_NE(nullptr, vbmeta);
1017     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
1018     EXPECT_EQ(false, verification_disabled);
1019     EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1020 
1021     EXPECT_EQ(2112UL, vbmeta->size());
1022     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1023     EXPECT_EQ("system_other", vbmeta->partition());
1024     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1025 }
1026 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathErrorVerification)1027 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathErrorVerification) {
1028     // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1029     const size_t system_image_size = 10 * 1024 * 1024;
1030     const size_t system_partition_size = 15 * 1024 * 1024;
1031     base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1032 
1033     // Adds AVB Hashtree Footer.
1034     AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1035                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1036                  "--internal_release_string \"unit test\"");
1037 
1038     std::string expected_key_blob_4096 =
1039             ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
1040 
1041     // Modifies the auxiliary data of system_other.img
1042     auto fd = OpenUniqueReadFd(system_path);
1043     auto system_footer = GetAvbFooter(fd);
1044     auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system_other-vbmeta.img");
1045     auto system_header = system_vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1046     size_t header_block_offset = 0;
1047     size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
1048     size_t auxiliary_block_offset =
1049         authentication_block_offset + system_header->authentication_data_block_size;
1050 
1051     // Modifies the hash.
1052     ModifyFile(
1053         system_path,
1054         (system_footer->vbmeta_offset + authentication_block_offset + system_header->hash_offset),
1055         system_header->hash_size);
1056 
1057     VBMetaVerifyResult verify_result;
1058     // Not allow verification error.
1059     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1060             system_path.value(), "system_other", expected_key_blob_4096,
1061             false /* allow_verification_error */, false /* rollback_protection */,
1062             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1063             nullptr /* verification_disabled */, &verify_result);
1064     EXPECT_EQ(nullptr, vbmeta);
1065 
1066     // Allow verification error.
1067     vbmeta = LoadAndVerifyVbmetaByPath(
1068             system_path.value(), "system_other", expected_key_blob_4096,
1069             true /* allow_verification_error */, false /* rollback_protection */,
1070             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1071             nullptr /* verification_disabled */, &verify_result);
1072     EXPECT_NE(nullptr, vbmeta);
1073     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1074 
1075     EXPECT_EQ(2112UL, vbmeta->size());
1076     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1077     EXPECT_EQ("system_other", vbmeta->partition());
1078     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1079 
1080     // Modifies the auxiliary data block.
1081     ModifyFile(system_path, system_footer->vbmeta_offset + auxiliary_block_offset,
1082                system_header->auxiliary_data_block_size);
1083 
1084     // Not allow verification error.
1085     vbmeta = LoadAndVerifyVbmetaByPath(
1086             system_path.value(), "system_other", expected_key_blob_4096,
1087             false /* allow_verification_error */, false /* rollback_protection */,
1088             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1089             nullptr /* verification_disabled */, &verify_result);
1090     EXPECT_EQ(nullptr, vbmeta);
1091 
1092     // Allow verification error.
1093     vbmeta = LoadAndVerifyVbmetaByPath(
1094             system_path.value(), "system_other", expected_key_blob_4096,
1095             true /* allow_verification_error */, false /* rollback_protection */,
1096             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1097             nullptr /* verification_disabled */, &verify_result);
1098     EXPECT_NE(nullptr, vbmeta);
1099     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1100 }
1101 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathUnexpectedPublicKey)1102 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathUnexpectedPublicKey) {
1103     // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1104     const size_t system_image_size = 10 * 1024 * 1024;
1105     const size_t system_partition_size = 15 * 1024 * 1024;
1106     base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1107 
1108     // Adds AVB Hashtree Footer.
1109     AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1110                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1111                  "--internal_release_string \"unit test\"");
1112 
1113     std::string unexpected_key_blob_2048 =
1114             ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa2048.pem"));
1115     std::string expected_key_blob_4096 =
1116             ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
1117 
1118     // Uses the correct expected public key.
1119     VBMetaVerifyResult verify_result;
1120     std::string out_public_key_data;
1121     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1122             system_path.value(), "system_other", expected_key_blob_4096,
1123             false /* allow_verification_error */, false /* rollback_protection */,
1124             false /* is_chained_vbmeta */, &out_public_key_data,
1125             nullptr /* verification_disabled */, &verify_result);
1126     EXPECT_NE(nullptr, vbmeta);
1127     EXPECT_EQ(verify_result, VBMetaVerifyResult::kSuccess);
1128     EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1129     EXPECT_EQ(2112UL, vbmeta->size());
1130     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1131     EXPECT_EQ("system_other", vbmeta->partition());
1132     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1133 
1134     // Uses the wrong expected public key with allow_verification_error set to false.
1135     vbmeta = LoadAndVerifyVbmetaByPath(
1136             system_path.value(), "system_other", unexpected_key_blob_2048,
1137             false /* allow_verification_error */, false /* rollback_protection */,
1138             false /* is_chained_vbmeta */, &out_public_key_data,
1139             nullptr /* verification_disabled */, &verify_result);
1140     EXPECT_EQ(nullptr, vbmeta);
1141     // Checks out_public_key_data is still loaded properly, if the error is due
1142     // to an unexpected public key instead of vbmeta image verification error.
1143     EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1144 
1145     // Uses the wrong expected public key with allow_verification_error set to true.
1146     vbmeta = LoadAndVerifyVbmetaByPath(
1147             system_path.value(), "system_other", unexpected_key_blob_2048,
1148             true /* allow_verification_error */, false /* rollback_protection */,
1149             false /* is_chained_vbmeta */, &out_public_key_data,
1150             nullptr /* verification_disabled */, &verify_result);
1151     EXPECT_NE(nullptr, vbmeta);
1152     EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1153     EXPECT_EQ(verify_result, VBMetaVerifyResult::kErrorVerification);
1154     EXPECT_EQ(2112UL, vbmeta->size());
1155     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1156     EXPECT_EQ("system_other", vbmeta->partition());
1157     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1158 }
1159 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathVerificationDisabled)1160 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathVerificationDisabled) {
1161     // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1162     const size_t system_image_size = 10 * 1024 * 1024;
1163     const size_t system_partition_size = 15 * 1024 * 1024;
1164     base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1165 
1166     // Adds AVB Hashtree Footer.
1167     AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1168                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1169                  "--internal_release_string \"unit test\"");
1170 
1171     base::FilePath rsa4096_public_key =
1172         ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1173 
1174     std::string expected_key_blob_4096;
1175     EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
1176 
1177     // Sets disabled flag and expect the returned verification_disabled is true.
1178     SetVBMetaFlags(system_path, AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
1179     bool verification_disabled;
1180     VBMetaVerifyResult verify_result;
1181     std::string out_public_key_data;
1182     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1183             system_path.value(), "system_other", expected_key_blob_4096,
1184             true /* allow_verification_error */, false /* rollback_protection */,
1185             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1186             &verification_disabled, &verify_result);
1187 
1188     EXPECT_NE(nullptr, vbmeta);
1189     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1190     EXPECT_EQ(true, verification_disabled);  // should be true.
1191 
1192     EXPECT_EQ(2112UL, vbmeta->size());
1193     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1194     EXPECT_EQ("system_other", vbmeta->partition());
1195     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1196 
1197     // Since the vbmeta flags is modified, vbmeta will be nullptr
1198     // if verification error isn't allowed.
1199     vbmeta = LoadAndVerifyVbmetaByPath(
1200             system_path.value(), "system_other", expected_key_blob_4096,
1201             false /* allow_verification_error */, false /* rollback_protection */,
1202             false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1203             &verification_disabled, &verify_result);
1204     EXPECT_EQ(nullptr, vbmeta);
1205 }
1206 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartition)1207 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartition) {
1208     // Generates a raw boot.img
1209     const size_t boot_image_size = 5 * 1024 * 1024;
1210     const size_t boot_partition_size = 10 * 1024 * 1024;
1211     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1212 
1213     // Adds AVB Hash Footer.
1214     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1215                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1216                  "--internal_release_string \"unit test\"");
1217 
1218     // Generates a raw system.img, use a smaller size to speed-up unit test.
1219     const size_t system_image_size = 10 * 1024 * 1024;
1220     const size_t system_partition_size = 15 * 1024 * 1024;
1221     base::FilePath system_path = GenerateImage("system.img", system_image_size);
1222     // Adds AVB Hashtree Footer.
1223     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1224                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1225                  "--internal_release_string \"unit test\"");
1226 
1227     // Generates chain partition descriptors.
1228     base::FilePath rsa2048_public_key =
1229             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1230     base::FilePath rsa4096_public_key =
1231             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1232     // Makes a vbmeta_system.img including the 'system' chained descriptor.
1233     auto vbmeta_system_path = GenerateVBMetaImage(
1234             "vbmeta_system.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1235             {},                                  /* include_descriptor_image_paths */
1236             {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1237             "--internal_release_string \"unit test\"");
1238 
1239     // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1240     auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1241                                            data_dir_.Append("testkey_rsa8192.pem"),
1242                                            {}, /* include_descriptor_image_paths */
1243                                            {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1244                                             {"vbmeta_system", 2, rsa4096_public_key}},
1245                                            "--internal_release_string \"unit test\"");
1246 
1247     // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1248     EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
1249               CalcVBMetaDigest("vbmeta.img", "sha256"));
1250 
1251     // Starts to test LoadAndVerifyVbmetaByPartition.
1252     std::vector<VBMetaData> vbmeta_images;
1253     auto vbmeta_image_path = [this](const std::string& partition_name) {
1254         return test_dir_.Append(partition_name + ".img").value();
1255     };
1256 
1257     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1258               LoadAndVerifyVbmetaByPartition(
1259                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1260                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1261                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1262                   false /* is_chained_vbmeta*/, &vbmeta_images));
1263 
1264     EXPECT_EQ(4UL, vbmeta_images.size());  // vbmeta, boot, vbmeta_system and system
1265     // Binary comparison for each vbmeta image.
1266     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1267     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1268     EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1269     EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1270 
1271     // Skip loading chained vbmeta images.
1272     vbmeta_images.clear();
1273     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1274               LoadAndVerifyVbmetaByPartition(
1275                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1276                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1277                   false /* load_chained_vbmeta */, true /* rollback_protection */,
1278                   vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1279     // Only vbmeta is loaded.
1280     EXPECT_EQ(1UL, vbmeta_images.size());
1281     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1282 }
1283 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionWithSuffixes)1284 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionWithSuffixes) {
1285     // Tests the following chained partitions.
1286     // vbmeta_a.img
1287     // |--> boot_b.img (boot_other)
1288     // |--> vbmeta_system_b.img (vbmeta_system_other)
1289     //      |--> system_a.img
1290 
1291     // Generates a raw boot_b.img
1292     const size_t boot_image_size = 5 * 1024 * 1024;
1293     const size_t boot_partition_size = 10 * 1024 * 1024;
1294     base::FilePath boot_path = GenerateImage("boot_b.img", boot_image_size);
1295 
1296     // Adds AVB Hash Footer.
1297     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1298                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1299                  "--internal_release_string \"unit test\"");
1300 
1301     // Generates a raw system_a.img, use a smaller size to speed-up unit test.
1302     const size_t system_image_size = 10 * 1024 * 1024;
1303     const size_t system_partition_size = 15 * 1024 * 1024;
1304     base::FilePath system_path = GenerateImage("system_a.img", system_image_size);
1305     // Adds AVB Hashtree Footer.
1306     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1307                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1308                  "--internal_release_string \"unit test\"");
1309 
1310     // Generates chain partition descriptors.
1311     base::FilePath rsa2048_public_key =
1312             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1313     base::FilePath rsa4096_public_key =
1314             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1315     // Makes a vbmeta_system_b.img including the 'system' chained descriptor.
1316     auto vbmeta_system_path = GenerateVBMetaImage(
1317             "vbmeta_system_b.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1318             {},                                  /* include_descriptor_image_paths */
1319             {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1320             "--internal_release_string \"unit test\"");
1321 
1322     // Makes a vbmeta_a.img includeing 'boot_other' and 'vbmeta_system_other' chained descriptors.
1323     auto vbmeta_path = GenerateVBMetaImage(
1324             "vbmeta_a.img", "SHA256_RSA8192", 0, data_dir_.Append("testkey_rsa8192.pem"),
1325             {},                                     /* include_descriptor_image_paths */
1326             {{"boot_other", 1, rsa2048_public_key}, /* chain_partitions */
1327              {"vbmeta_system_other", 2, rsa4096_public_key}},
1328             "--internal_release_string \"unit test\"");
1329 
1330     // Starts to test LoadAndVerifyVbmetaByPartition with ab_suffix and ab_other_suffix.
1331     auto vbmeta_image_path = [this](const std::string& partition_name) {
1332         return test_dir_.Append(partition_name + ".img").value();
1333     };
1334 
1335     std::vector<VBMetaData> vbmeta_images;
1336     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1337               LoadAndVerifyVbmetaByPartition(
1338                   "vbmeta" /* partition_name */, "_a" /* ab_suffix */, "_b" /* other_suffix */,
1339                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1340                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1341                   false /* is_chained_vbmeta*/, &vbmeta_images));
1342 
1343     EXPECT_EQ(4UL, vbmeta_images.size());  // vbmeta, boot_other, vbmeta_system_other and system
1344     // Binary comparison for each vbmeta image.
1345     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1346     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1347     EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1348     EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1349 
1350     // Skips loading chained vbmeta images.
1351     vbmeta_images.clear();
1352     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1353               LoadAndVerifyVbmetaByPartition(
1354                   "vbmeta" /* partition_name */, "_a" /* ab_suffix */, "_b" /* other_suffix */,
1355                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1356                   false /* load_chained_vbmeta */, true /* rollback_protection */,
1357                   vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1358     // Only vbmeta is loaded.
1359     EXPECT_EQ(1UL, vbmeta_images.size());
1360     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1361 
1362     // Using an invalid suffix for 'other' slot, checks it returns error.
1363     EXPECT_EQ(VBMetaVerifyResult::kError,
1364               LoadAndVerifyVbmetaByPartition(
1365                   "vbmeta" /* partition_name */, "_a" /* ab_suffix */,
1366                   "_invalid_suffix" /* other_suffix */, "" /* expected_public_key_blob*/,
1367                   false /* allow_verification_error */, true /* load_chained_vbmeta */,
1368                   true /* rollback_protection */, vbmeta_image_path, false /* is_chained_vbmeta*/,
1369                   &vbmeta_images));
1370 }
1371 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionErrorVerification)1372 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionErrorVerification) {
1373     // Generates a raw boot.img
1374     const size_t boot_image_size = 5 * 1024 * 1024;
1375     const size_t boot_partition_size = 10 * 1024 * 1024;
1376     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1377 
1378     // Adds AVB Hash Footer.
1379     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1380                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1381                  "--internal_release_string \"unit test\"");
1382 
1383     // Generates a raw system.img, use a smaller size to speed-up unit test.
1384     const size_t system_image_size = 10 * 1024 * 1024;
1385     const size_t system_partition_size = 15 * 1024 * 1024;
1386     base::FilePath system_path = GenerateImage("system.img", system_image_size);
1387     // Adds AVB Hashtree Footer.
1388     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1389                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1390                  "--internal_release_string \"unit test\"");
1391 
1392     // Generates chain partition descriptors.
1393     base::FilePath rsa2048_public_key =
1394             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1395     base::FilePath rsa4096_public_key =
1396             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1397 
1398     // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1399     auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1400                                            data_dir_.Append("testkey_rsa8192.pem"),
1401                                            {}, /* include_descriptor_image_paths */
1402                                            {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1403                                             {"system", 2, rsa4096_public_key}},
1404                                            "--internal_release_string \"unit test\"");
1405 
1406     // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1407     EXPECT_EQ("abbe11b316901f3336e26630f64c4732dadbe14532186ac8640e4141a403721f",
1408               CalcVBMetaDigest("vbmeta.img", "sha256"));
1409 
1410     auto vbmeta = LoadVBMetaData("vbmeta.img");
1411 
1412     // Modifies hash, checks there is error if allow_verification_error is false.
1413     auto header = vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1414     size_t header_block_offset = 0;
1415     size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
1416 
1417     // Modifies the hash.
1418     ModifyFile(vbmeta_path, authentication_block_offset + header->hash_offset, header->hash_size);
1419 
1420     // Starts to test LoadAndVerifyVbmetaByPartition.
1421     std::vector<VBMetaData> vbmeta_images;
1422     auto vbmeta_image_path = [this](const std::string& partition_name) {
1423         return test_dir_.Append(partition_name + ".img").value();
1424     };
1425     EXPECT_EQ(VBMetaVerifyResult::kError,
1426               LoadAndVerifyVbmetaByPartition(
1427                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1428                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1429                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1430                   false /* is_chained_vbmeta*/, &vbmeta_images));
1431     // Stops to load vbmeta because the top-level vbmeta has verification error.
1432     EXPECT_EQ(0UL, vbmeta_images.size());
1433 
1434     // Tries again with verification error allowed.
1435     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1436               LoadAndVerifyVbmetaByPartition(
1437                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "", /* other_suffix */
1438                   "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1439                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1440                   false /* is_chained_vbmeta*/, &vbmeta_images));
1441 
1442     EXPECT_EQ(3UL, vbmeta_images.size());  // vbmeta, boot, and system
1443     // Binary comparison for each vbmeta image.
1444     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1445     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1446     EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[2]));
1447 
1448     // Resets the modification of the hash.
1449     ModifyFile(vbmeta_path, 0 /* offset */, -1 /* length */);
1450 
1451     // Modifies the auxiliary data of system.img
1452     auto fd = OpenUniqueReadFd(system_path);
1453     auto system_footer = GetAvbFooter(fd);
1454     auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system-vbmeta.img");
1455     auto system_header = system_vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1456     size_t auxiliary_block_offset =
1457             authentication_block_offset + system_header->authentication_data_block_size;
1458 
1459     // Modifies the auxiliary data block.
1460     ModifyFile(system_path, system_footer->vbmeta_offset + auxiliary_block_offset,
1461                system_header->auxiliary_data_block_size);
1462     vbmeta_images.clear();
1463     EXPECT_EQ(VBMetaVerifyResult::kError,
1464               LoadAndVerifyVbmetaByPartition(
1465                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1466                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1467                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1468                   false /* is_chained_vbmeta*/, &vbmeta_images));
1469     // 'vbmeta', 'boot' but no 'system', because of verification error.
1470     EXPECT_EQ(2UL, vbmeta_images.size());
1471     // Binary comparison for the loaded 'vbmeta' and 'boot'.
1472     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1473     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1474 
1475     // Resets the modification of the auxiliary data.
1476     ModifyFile(system_path, 0 /* offset */, -1 /* length */);
1477 
1478     // Sets the vbmeta header flags on a chained partition, which introduces an error.
1479     ModifyFile(system_path, system_footer->vbmeta_offset + offsetof(AvbVBMetaImageHeader, flags),
1480                sizeof(uint32_t));
1481     EXPECT_EQ(VBMetaVerifyResult::kError,
1482               LoadAndVerifyVbmetaByPartition(
1483                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1484                   "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1485                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1486                   false /* is_chained_vbmeta*/, &vbmeta_images));
1487 }
1488 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionVerificationDisabled)1489 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionVerificationDisabled) {
1490     // Generates a raw boot.img
1491     const size_t boot_image_size = 5 * 1024 * 1024;
1492     const size_t boot_partition_size = 10 * 1024 * 1024;
1493     base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1494 
1495     // Adds AVB Hash Footer.
1496     AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1497                  data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1498                  "--internal_release_string \"unit test\"");
1499 
1500     // Generates a raw system.img, use a smaller size to speed-up unit test.
1501     const size_t system_image_size = 10 * 1024 * 1024;
1502     const size_t system_partition_size = 15 * 1024 * 1024;
1503     base::FilePath system_path = GenerateImage("system.img", system_image_size);
1504     // Adds AVB Hashtree Footer.
1505     AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1506                  data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1507                  "--internal_release_string \"unit test\"");
1508 
1509     // Generates chain partition descriptors.
1510     base::FilePath rsa2048_public_key =
1511         ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1512     base::FilePath rsa4096_public_key =
1513         ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1514     // Makes a vbmeta_system.img including the 'system' chained descriptor.
1515     auto vbmeta_system_path = GenerateVBMetaImage(
1516         "vbmeta_system.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1517         {},                                  /* include_descriptor_image_paths */
1518         {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1519         "--internal_release_string \"unit test\"");
1520 
1521     // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1522     auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1523                                            data_dir_.Append("testkey_rsa8192.pem"),
1524                                            {}, /* include_descriptor_image_paths */
1525                                            {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1526                                             {"vbmeta_system", 2, rsa4096_public_key}},
1527                                            "--internal_release_string \"unit test\"");
1528 
1529     // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1530     EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
1531               CalcVBMetaDigest("vbmeta.img", "sha256"));
1532 
1533     // Starts to test LoadAndVerifyVbmetaByPartition.
1534     std::vector<VBMetaData> vbmeta_images;
1535     auto vbmeta_image_path = [this](const std::string& partition_name) {
1536         return test_dir_.Append(partition_name + ".img").value();
1537     };
1538 
1539     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1540               LoadAndVerifyVbmetaByPartition(
1541                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1542                   "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1543                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1544                   false /* is_chained_vbmeta*/, &vbmeta_images));
1545 
1546     EXPECT_EQ(4UL, vbmeta_images.size());  // vbmeta, boot, vbmeta_system and system
1547     // Binary comparison for each vbmeta image.
1548     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1549     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1550     EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1551     EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1552 
1553     // Sets VERIFICATION_DISABLED to the top-level vbmeta.img
1554     SetVBMetaFlags(vbmeta_path, AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
1555     vbmeta_images.clear();
1556     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1557               LoadAndVerifyVbmetaByPartition(
1558                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1559                   "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1560                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1561                   false /* is_chained_vbmeta*/, &vbmeta_images));
1562     EXPECT_EQ(1UL, vbmeta_images.size());  // Only vbmeta is loaded
1563     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1564 
1565     // HASHTREE_DISABLED still loads the chained vbmeta.
1566     SetVBMetaFlags(vbmeta_path, AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
1567     vbmeta_images.clear();
1568     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1569               LoadAndVerifyVbmetaByPartition(
1570                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1571                   "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1572                   true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1573                   false /* is_chained_vbmeta*/, &vbmeta_images));
1574     EXPECT_EQ(4UL, vbmeta_images.size());  // vbmeta, boot, vbmeta_system and system
1575     // Binary comparison for each vbmeta image.
1576     EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1577     EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1578     EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1579     EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1580 }
1581 
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionUnexpectedPublicKey)1582 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionUnexpectedPublicKey) {
1583     // Generates chain partition descriptors.
1584     base::FilePath rsa2048_public_key =
1585             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1586     base::FilePath rsa4096_public_key =
1587             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1588     base::FilePath rsa8192_public_key =
1589             ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa8192.pem"));
1590 
1591     // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1592     auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1593                                            data_dir_.Append("testkey_rsa8192.pem"),
1594                                            {}, /* include_descriptor_image_paths */
1595                                            {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1596                                             {"system", 2, rsa4096_public_key}},
1597                                            "--internal_release_string \"unit test\"");
1598     std::string expected_key_blob_4096;
1599     EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
1600     std::string expected_key_blob_8192;
1601     EXPECT_TRUE(base::ReadFileToString(rsa8192_public_key, &expected_key_blob_8192));
1602 
1603     auto vbmeta_image_path = [this](const std::string& partition_name) {
1604         return test_dir_.Append(partition_name + ".img").value();
1605     };
1606     std::vector<VBMetaData> vbmeta_images;
1607     // Uses the correct expected public key.
1608     EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1609               LoadAndVerifyVbmetaByPartition(
1610                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1611                   expected_key_blob_8192, true /* allow_verification_error */,
1612                   false /* load_chained_vbmeta */, true /* rollback_protection */,
1613                   vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1614 
1615     // Uses the wrong expected public key with allow_verification_error set to true.
1616     vbmeta_images.clear();
1617     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1618               LoadAndVerifyVbmetaByPartition(
1619                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1620                   expected_key_blob_4096, true /* allow_verification_error */,
1621                   false /* load_chained_vbmeta */, true /* rollback_protection */,
1622                   vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1623 
1624     // Uses the wrong expected public key with allow_verification_error set to false.
1625     vbmeta_images.clear();
1626     EXPECT_EQ(VBMetaVerifyResult::kError,
1627               LoadAndVerifyVbmetaByPartition(
1628                   "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1629                   expected_key_blob_4096, false /* allow_verification_error */,
1630                   false /* load_chained_vbmeta */, true /* rollback_protection */,
1631                   vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1632 }
1633 
1634 }  // namespace fs_avb_host_test
1635