1 /*
2 * Copyright (C) 2021 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 <cstdint>
18 #include <regex>
19 #include <unordered_map>
20 #include <vector>
21
22 #include <android-base/file.h>
23 #include <android-base/logging.h>
24 #include <android-base/properties.h>
25 #include <android-base/unique_fd.h>
26 #include <android/api-level.h>
27 #include <bootimg.h>
28 #include <fs_avb/fs_avb_util.h>
29 #include <gtest/gtest.h>
30 #include <kver/kernel_release.h>
31 #include <libavb/libavb.h>
32 #include <openssl/sha.h>
33 #include <storage_literals/storage_literals.h>
34 #include <vintf/VintfObject.h>
35 #include <vintf/parse_string.h>
36
37 #include "gsi_validation_utils.h"
38 #include "ogki_builds_utils.h"
39
40 using namespace std::literals;
41 using namespace android::storage_literals;
42
43 namespace {
44
sha256(const std::string_view content)45 std::string sha256(const std::string_view content) {
46 unsigned char hash[SHA256_DIGEST_LENGTH];
47 const unsigned char *data = (const unsigned char *)content.data();
48 SHA256(data, content.size(), hash);
49 std::ostringstream os;
50 os << std::hex << std::setfill('0');
51 for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
52 os << std::setw(2) << static_cast<unsigned int>(hash[i]);
53 }
54 return os.str();
55 }
56
GetBlockDevicePath(const std::string & name)57 std::string GetBlockDevicePath(const std::string &name) {
58 return "/dev/block/by-name/" + name + fs_mgr_get_slot_suffix();
59 }
60
61 class GkiBootImage {
62 public:
GkiBootImage(const uint8_t * data,size_t size)63 GkiBootImage(const uint8_t *data, size_t size) : data_(data, data + size) {}
64
GetBootHeaderVersion(const void * data)65 static uint32_t GetBootHeaderVersion(const void *data) {
66 return static_cast<const boot_img_hdr_v0 *>(data)->header_version;
67 }
68
header_version() const69 uint32_t header_version() const { return GetBootHeaderVersion(data()); }
70
kernel_pages() const71 uint32_t kernel_pages() const { return GetNumberOfPages(kernel_size()); }
72
ramdisk_pages() const73 uint32_t ramdisk_pages() const { return GetNumberOfPages(ramdisk_size()); }
74
kernel_offset() const75 uint32_t kernel_offset() const {
76 // The first page must be the boot image header.
77 return page_size();
78 }
79
ramdisk_offset() const80 uint32_t ramdisk_offset() const {
81 return kernel_offset() + kernel_pages() * page_size();
82 }
83
84 virtual uint32_t page_size() const = 0;
85 virtual uint32_t os_version() const = 0;
86 virtual uint32_t kernel_size() const = 0;
87 virtual uint32_t ramdisk_size() const = 0;
88 virtual uint32_t signature_size() const = 0;
89 virtual uint32_t signature_offset() const = 0;
90
GetNumberOfPages(uint32_t value) const91 uint32_t GetNumberOfPages(uint32_t value) const {
92 return (value + page_size() - 1) / page_size();
93 }
94
GetKernel() const95 std::vector<uint8_t> GetKernel() const {
96 return Slice(kernel_offset(), kernel_size());
97 }
98
99 // Get "effective" boot image. The pure boot image without any boot signature.
GetBootImage() const100 std::vector<uint8_t> GetBootImage() const {
101 return Slice(0, signature_offset());
102 }
103
104 // Parse a vector of vbmeta image from the boot signature section.
GetBootSignatures() const105 std::vector<android::fs_mgr::VBMetaData> GetBootSignatures() const {
106 const auto begin_offset = std::clamp<size_t>(signature_offset(), 0, size());
107 const uint8_t *buffer = data() + begin_offset;
108 // begin_offset + remaining_bytes <= size() because boot_signature must be
109 // the last section.
110 size_t remaining_bytes =
111 std::clamp<size_t>(signature_size(), 0, size() - begin_offset);
112 // In case boot_signature is misaligned, shift to the first AVB magic, and
113 // treat it as the actual beginning of boot signature.
114 while (remaining_bytes >= AVB_MAGIC_LEN) {
115 if (!memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN)) {
116 break;
117 }
118 ++buffer;
119 --remaining_bytes;
120 }
121 std::vector<android::fs_mgr::VBMetaData> vbmeta_images;
122 while (remaining_bytes >= sizeof(AvbVBMetaImageHeader)) {
123 if (memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN) != 0) {
124 break;
125 }
126 // Extract only the header to calculate the vbmeta image size.
127 android::fs_mgr::VBMetaData vbmeta_header(
128 buffer, sizeof(AvbVBMetaImageHeader), "boot_signature");
129 if (!vbmeta_header.GetVBMetaHeader(/* update_vbmeta_size */ true)) {
130 GTEST_LOG_(ERROR) << __FUNCTION__
131 << "(): VBMetaData::GetVBMetaHeader() failed.";
132 return {};
133 }
134 const auto vbmeta_image_size = vbmeta_header.size();
135 GTEST_LOG_(INFO) << __FUNCTION__ << "(): Found vbmeta image with size "
136 << vbmeta_image_size;
137 if (vbmeta_image_size < sizeof(AvbVBMetaImageHeader)) {
138 GTEST_LOG_(ERROR) << __FUNCTION__
139 << "(): Impossible-sized vbmeta image: "
140 << vbmeta_image_size;
141 return {};
142 }
143
144 if (vbmeta_image_size > remaining_bytes) {
145 GTEST_LOG_(ERROR)
146 << __FUNCTION__
147 << "(): Premature EOF when parsing GKI boot signature.";
148 return {};
149 }
150
151 vbmeta_images.emplace_back(buffer, vbmeta_image_size, "boot_signature");
152 buffer += vbmeta_image_size;
153 remaining_bytes -= vbmeta_image_size;
154 }
155 return vbmeta_images;
156 }
157
158 virtual ~GkiBootImage() = default;
159
160 protected:
data() const161 const uint8_t *data() const { return data_.data(); }
162
size() const163 size_t size() const { return data_.size(); }
164
Slice(size_t offset,size_t length) const165 std::vector<uint8_t> Slice(size_t offset, size_t length) const {
166 const auto begin_offset = std::clamp<size_t>(offset, 0, size());
167 const auto end_offset =
168 std::clamp<size_t>(begin_offset + length, begin_offset, size());
169 const auto begin = data() + begin_offset;
170 const auto end = data() + end_offset;
171 return {begin, end};
172 }
173
174 private:
175 std::vector<uint8_t> data_;
176 };
177
178 class GkiBootImageV2 : public GkiBootImage {
179 public:
GkiBootImageV2(const uint8_t * data,size_t size)180 GkiBootImageV2(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
181
boot_header() const182 const boot_img_hdr_v2 *boot_header() const {
183 return reinterpret_cast<const boot_img_hdr_v2 *>(data());
184 }
185
page_size() const186 uint32_t page_size() const override { return boot_header()->page_size; }
187
os_version() const188 uint32_t os_version() const override { return boot_header()->os_version; }
189
kernel_size() const190 uint32_t kernel_size() const override { return boot_header()->kernel_size; }
191
ramdisk_size() const192 uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
193
signature_size() const194 uint32_t signature_size() const override {
195 // The last 16K bytes are by definition the GKI boot signature.
196 static constexpr uint32_t kBootSignatureSize = 16_KiB;
197 return kBootSignatureSize;
198 }
199
signature_offset() const200 uint32_t signature_offset() const override {
201 if (size() < signature_size()) {
202 return 0;
203 }
204 return size() - signature_size();
205 }
206
recovery_dtbo_size() const207 uint32_t recovery_dtbo_size() const {
208 return boot_header()->recovery_dtbo_size;
209 }
210
recovery_dtbo_offset() const211 uint64_t recovery_dtbo_offset() const {
212 return boot_header()->recovery_dtbo_offset;
213 }
214 };
215
216 class GkiBootImageV4 : public GkiBootImage {
217 public:
GkiBootImageV4(const uint8_t * data,size_t size)218 GkiBootImageV4(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
219
boot_header() const220 const boot_img_hdr_v4 *boot_header() const {
221 return reinterpret_cast<const boot_img_hdr_v4 *>(data());
222 }
223
page_size() const224 uint32_t page_size() const override {
225 static constexpr uint32_t kPageSize = 4096;
226 return kPageSize;
227 }
228
os_version() const229 uint32_t os_version() const override { return boot_header()->os_version; }
230
kernel_size() const231 uint32_t kernel_size() const override { return boot_header()->kernel_size; }
232
ramdisk_size() const233 uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
234
signature_size() const235 uint32_t signature_size() const override {
236 // For Android12 GKI, the |.signature_size| field is respected.
237 // For Android13+ GKI, the |.signature_size| field must be zero, and the
238 // last 16K bytes are by definition the GKI boot signature.
239 static constexpr uint32_t kBootSignatureSize = 16_KiB;
240 const uint32_t value = boot_header()->signature_size;
241 return value ? value : kBootSignatureSize;
242 }
243
signature_offset() const244 uint32_t signature_offset() const override {
245 return ramdisk_offset() + ramdisk_pages() * page_size();
246 }
247 };
248
GetAvbProperty(const std::string & name,const std::vector<android::fs_mgr::VBMetaData> & vbmeta_images)249 std::string GetAvbProperty(
250 const std::string &name,
251 const std::vector<android::fs_mgr::VBMetaData> &vbmeta_images) {
252 const std::string prop_name = "com.android.build." + name;
253 return android::fs_mgr::GetAvbPropertyDescriptor(prop_name, vbmeta_images);
254 }
255
LoadAndVerifyGkiBootImage(std::vector<android::fs_mgr::VBMetaData> * boot_signature_images)256 std::unique_ptr<GkiBootImage> LoadAndVerifyGkiBootImage(
257 std::vector<android::fs_mgr::VBMetaData> *boot_signature_images) {
258 const std::string block_device_path = GetBlockDevicePath("boot");
259 const std::string TAG = __FUNCTION__ + "("s + block_device_path + ")";
260 SCOPED_TRACE(TAG);
261
262 std::string block_device_data;
263 if (!android::base::ReadFileToString(block_device_path, &block_device_data,
264 /* follow_symlinks */ true)) {
265 ADD_FAILURE() << "Failed to read '" << block_device_path
266 << "': " << strerror(errno);
267 return nullptr;
268 }
269 if (block_device_data.size() <= 4096) {
270 ADD_FAILURE() << "Size of '" << block_device_path
271 << "' is impossibly small: " << block_device_data.size();
272 return nullptr;
273 }
274
275 if (block_device_data.substr(0, BOOT_MAGIC_SIZE) != BOOT_MAGIC) {
276 ADD_FAILURE() << "Device has invalid boot magic: " << block_device_path;
277 return nullptr;
278 }
279
280 // Remove the AVB footer and chained vbmeta image if there is any.
281 if (block_device_data.size() > AVB_FOOTER_SIZE) {
282 const uint8_t *footer_address =
283 reinterpret_cast<const uint8_t *>(block_device_data.data()) +
284 block_device_data.size() - AVB_FOOTER_SIZE;
285 AvbFooter vbmeta_footer;
286 if (avb_footer_validate_and_byteswap(
287 reinterpret_cast<const AvbFooter *>(footer_address),
288 &vbmeta_footer)) {
289 block_device_data.resize(vbmeta_footer.original_image_size);
290 }
291 }
292
293 std::unique_ptr<GkiBootImage> boot_image;
294 const auto boot_header_version =
295 GkiBootImage::GetBootHeaderVersion(block_device_data.data());
296 if (boot_header_version == 4) {
297 boot_image = std::make_unique<GkiBootImageV4>(
298 reinterpret_cast<const uint8_t *>(block_device_data.data()),
299 block_device_data.size());
300 } else if (boot_header_version == 2) {
301 boot_image = std::make_unique<GkiBootImageV2>(
302 reinterpret_cast<const uint8_t *>(block_device_data.data()),
303 block_device_data.size());
304 } else {
305 ADD_FAILURE() << "Unexpected boot header version: " << boot_header_version;
306 return nullptr;
307 }
308
309 *boot_signature_images = boot_image->GetBootSignatures();
310 if (boot_signature_images->empty()) {
311 ADD_FAILURE() << "Failed to load the boot signature.";
312 return nullptr;
313 }
314
315 // Verify that the vbmeta images in boot_signature are certified.
316 for (const auto &vbmeta_image : *boot_signature_images) {
317 size_t pk_len;
318 const uint8_t *pk_data;
319 const auto vbmeta_verify_result = avb_vbmeta_image_verify(
320 vbmeta_image.data(), vbmeta_image.size(), &pk_data, &pk_len);
321 if (vbmeta_verify_result != AVB_VBMETA_VERIFY_RESULT_OK) {
322 ADD_FAILURE() << "Failed to verify boot_signature: "
323 << avb_vbmeta_verify_result_to_string(vbmeta_verify_result);
324 return nullptr;
325 }
326 const std::string out_public_key_data(
327 reinterpret_cast<const char *>(pk_data), pk_len);
328 if (out_public_key_data.empty()) {
329 ADD_FAILURE() << "The GKI image descriptor is not signed.";
330 continue;
331 }
332 if (!ValidatePublicKeyBlob(out_public_key_data)) {
333 ADD_FAILURE()
334 << "The GKI image descriptor is not signed by an official key.";
335 continue;
336 }
337 }
338
339 GTEST_LOG_(INFO) << TAG << ": boot.fingerprint: "
340 << GetAvbProperty("boot.fingerprint",
341 *boot_signature_images);
342 GTEST_LOG_(INFO) << TAG
343 << ": header version: " << boot_image->header_version()
344 << ", kernel size: " << boot_image->kernel_size()
345 << ", ramdisk size: " << boot_image->ramdisk_size()
346 << ", signature size: " << boot_image->signature_size();
347
348 return boot_image;
349 }
350
351 // Verify image data integrity with an AVB hash descriptor.
VerifyImageDescriptor(const std::vector<uint8_t> & image,const android::fs_mgr::FsAvbHashDescriptor & descriptor)352 void VerifyImageDescriptor(
353 const std::vector<uint8_t> &image,
354 const android::fs_mgr::FsAvbHashDescriptor &descriptor) {
355 const std::string TAG = __FUNCTION__ + "("s + descriptor.partition_name + ")";
356 SCOPED_TRACE(TAG);
357
358 ASSERT_EQ(image.size(), descriptor.image_size);
359
360 const std::string &salt_str = descriptor.salt;
361 const std::string &expected_digest_str = descriptor.digest;
362
363 const std::string hash_algorithm(
364 reinterpret_cast<const char *>(descriptor.hash_algorithm));
365 GTEST_LOG_(INFO) << TAG << ": hash_algorithm = " << hash_algorithm;
366
367 std::unique_ptr<ShaHasher> hasher = CreateShaHasher(hash_algorithm);
368 ASSERT_NE(nullptr, hasher);
369
370 std::vector<uint8_t> salt, expected_digest, out_digest;
371
372 ASSERT_TRUE(HexToBytes(salt_str, &salt))
373 << "Invalid salt in descriptor: " << salt_str;
374 ASSERT_TRUE(HexToBytes(expected_digest_str, &expected_digest))
375 << "Invalid digest in descriptor: " << expected_digest_str;
376
377 ASSERT_EQ(expected_digest.size(), hasher->GetDigestSize());
378 out_digest.resize(hasher->GetDigestSize());
379
380 ASSERT_TRUE(hasher->CalculateDigest(image.data(), image.size(), salt.data(),
381 descriptor.salt_len, out_digest.data()))
382 << "Unable to calculate image digest.";
383
384 ASSERT_EQ(out_digest.size(), expected_digest.size())
385 << "Calculated digest size does not match expected digest size.";
386
387 ASSERT_EQ(out_digest, expected_digest)
388 << "Calculated digest does not match expected digest.";
389 }
390 } // namespace
391
392 class GkiComplianceTest : public testing::Test {
393 static const std::regex ogkiUnameRegex;
394
395 protected:
SetUp()396 void SetUp() override {
397 // Fetch device runtime information.
398 runtime_info = android::vintf::VintfObject::GetRuntimeInfo();
399 ASSERT_NE(nullptr, runtime_info);
400
401 product_first_api_level = GetProductFirstApiLevel();
402
403 /* Skip for non-arm64 kernels that do not mandate GKI yet. */
404 if (runtime_info->hardwareId() != "aarch64" &&
405 runtime_info->hardwareId() != "armv8l") {
406 GTEST_SKIP() << "Exempt from GKI test on non-arm64 kernel devices";
407 }
408
409 GTEST_LOG_(INFO) << runtime_info->osName() << " "
410 << runtime_info->osRelease();
411 GTEST_LOG_(INFO) << "Product first API level: " << product_first_api_level;
412 }
413
414 bool IsOgkiBuild() const;
415 bool ShouldSkipGkiComplianceV2();
416
417 std::shared_ptr<const android::vintf::RuntimeInfo> runtime_info;
418 int product_first_api_level;
419 };
420
421 const std::regex GkiComplianceTest::ogkiUnameRegex =
422 std::regex("-abogki[0-9]+(-|$)");
423
IsOgkiBuild() const424 bool GkiComplianceTest::IsOgkiBuild() const {
425 /* Android release version should at least be android14 for OGKI build. */
426 const auto kernel_release = android::kver::KernelRelease::Parse(
427 runtime_info->osRelease(), /* allow_suffix = */ true);
428 if (!kernel_release.has_value() || kernel_release->android_release() < 14) {
429 return false;
430 }
431
432 return std::regex_search(runtime_info->osRelease(), ogkiUnameRegex);
433 }
434
ShouldSkipGkiComplianceV2()435 bool GkiComplianceTest::ShouldSkipGkiComplianceV2() {
436 /* Skip for devices if the kernel version is not >= 5.10. */
437 if (runtime_info->kernelVersion().dropMinor() <
438 android::vintf::Version{5, 10}) {
439 GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on kernel version: "
440 << runtime_info->kernelVersion();
441 return true;
442 }
443 /* Skip for devices launched before Android S. */
444 if (product_first_api_level < __ANDROID_API_S__) {
445 GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on pre-S launched devices";
446 return true;
447 }
448 /* Skip for OGKI kernel builds. */
449 if (IsOgkiBuild()) {
450 GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on OGKI kernel";
451 return true;
452 }
453 /*
454 * Skip for automotive devices if the kernel version is not >= 5.15 or
455 * the device is launched before Android T.
456 */
457 if (IsAutomotiveDevice()) {
458 if (runtime_info->kernelVersion().dropMinor() <
459 android::vintf::Version{5, 15}) {
460 GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
461 << runtime_info->kernelVersion();
462 return true;
463 }
464 if (product_first_api_level < __ANDROID_API_T__) {
465 GTEST_LOG_(INFO) << "Exempt from GKI test on pre-T launched devices";
466 return true;
467 }
468 }
469 /*
470 * Skip for TV devices if the kernel version is not >= 5.15 or
471 * the device is launched before Android U.
472 */
473 if (IsTvDevice()) {
474 if (runtime_info->kernelVersion().dropMinor() <
475 android::vintf::Version{5, 15}) {
476 GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
477 << runtime_info->kernelVersion();
478 return true;
479 }
480 if (product_first_api_level < __ANDROID_API_U__) {
481 GTEST_LOG_(INFO) << "Exempt from GKI test on pre-U launched TV devices";
482 return true;
483 }
484 }
485 return false;
486 }
487
488 // Verify the entire boot image.
TEST_F(GkiComplianceTest,GkiComplianceV2)489 TEST_F(GkiComplianceTest, GkiComplianceV2) {
490 if (ShouldSkipGkiComplianceV2()) {
491 GTEST_SKIP() << "Skipping GkiComplianceV2 test";
492 }
493
494 // GKI 2.0 ensures getKernelLevel() to return valid value.
495 std::string error_msg;
496 const auto kernel_level =
497 android::vintf::VintfObject::GetInstance()->getKernelLevel(&error_msg);
498 ASSERT_NE(android::vintf::Level::UNSPECIFIED, kernel_level) << error_msg;
499
500 std::vector<android::fs_mgr::VBMetaData> boot_signature_images;
501 std::unique_ptr<GkiBootImage> boot_image =
502 LoadAndVerifyGkiBootImage(&boot_signature_images);
503 ASSERT_NE(nullptr, boot_image);
504 ASSERT_LE(1, boot_signature_images.size());
505 EXPECT_EQ(4, boot_image->header_version());
506
507 if (kernel_level >= android::vintf::Level::T) {
508 GTEST_LOG_(INFO)
509 << "Android T+ verification scheme. The GKI boot.img must contain only "
510 "the generic kernel but not the generic ramdisk.";
511 EXPECT_EQ(0, boot_image->ramdisk_size())
512 << "'boot' partition mustn't include a ramdisk image.";
513 EXPECT_EQ(0, boot_image->os_version())
514 << "OS version and security patch level should be defined in the "
515 "chained vbmeta image instead.";
516 }
517
518 std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> boot_descriptor =
519 android::fs_mgr::GetHashDescriptor("boot", boot_signature_images);
520 ASSERT_NE(nullptr, boot_descriptor)
521 << "Failed to load the 'boot' hash descriptor.";
522 ASSERT_NO_FATAL_FAILURE(
523 VerifyImageDescriptor(boot_image->GetBootImage(), *boot_descriptor));
524 }
525
526 // Verify OGKI build is approved.
TEST_F(GkiComplianceTest,OgkiCompliance)527 TEST_F(GkiComplianceTest, OgkiCompliance) {
528 if (!IsOgkiBuild()) {
529 GTEST_SKIP() << "OGKI build not detected";
530 }
531
532 const auto kernel_release =
533 android::kver::KernelRelease::Parse(runtime_info->osRelease(),
534 /* allow_suffix = */ true);
535 ASSERT_TRUE(kernel_release.has_value())
536 << "Failed to parse the kernel release string: "
537 << runtime_info->osRelease();
538
539 auto branch =
540 std::format("android{}-{}.{}", kernel_release->android_release(),
541 runtime_info->kernelVersion().version,
542 runtime_info->kernelVersion().majorRev);
543 auto approved_builds_result = ogki::GetApprovedBuilds(branch);
544 ASSERT_TRUE(approved_builds_result.ok())
545 << "Failed to get approved OGKI builds: "
546 << approved_builds_result.error().message();
547
548 const auto uname_hash = sha256(runtime_info->osRelease());
549 EXPECT_TRUE(approved_builds_result.value().contains(uname_hash));
550 }
551
main(int argc,char * argv[])552 int main(int argc, char *argv[]) {
553 ::testing::InitGoogleTest(&argc, argv);
554 android::base::InitLogging(argv, android::base::StderrLogger);
555 return RUN_ALL_TESTS();
556 }
557