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