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