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