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