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 <ranges>
19 #include <regex>
20 #include <unordered_map>
21 #include <vector>
22 
23 #include <android-base/file.h>
24 #include <android-base/logging.h>
25 #include <android-base/properties.h>
26 #include <android-base/unique_fd.h>
27 #include <android/api-level.h>
28 #include <bootimg.h>
29 #include <fs_avb/fs_avb_util.h>
30 #include <gtest/gtest.h>
31 #include <kver/kernel_release.h>
32 #include <libavb/libavb.h>
33 #include <openssl/sha.h>
34 #include <storage_literals/storage_literals.h>
35 #include <vintf/VintfObject.h>
36 #include <vintf/parse_string.h>
37 
38 #include "gsi_validation_utils.h"
39 #include "ogki_builds_utils.h"
40 
41 using namespace std::literals;
42 using namespace android::storage_literals;
43 
44 namespace {
45 
sha256(const std::string_view content)46 std::string sha256(const std::string_view content) {
47   unsigned char hash[SHA256_DIGEST_LENGTH];
48   const unsigned char *data = (const unsigned char *)content.data();
49   SHA256(data, content.size(), hash);
50   std::ostringstream os;
51   os << std::hex << std::setfill('0');
52   for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
53     os << std::setw(2) << static_cast<unsigned int>(hash[i]);
54   }
55   return os.str();
56 }
57 
GetBlockDevicePath(const std::string & name)58 std::string GetBlockDevicePath(const std::string &name) {
59   return "/dev/block/by-name/" + name + fs_mgr_get_slot_suffix();
60 }
61 
62 class GkiBootImage {
63  public:
GkiBootImage(const uint8_t * data,size_t size)64   GkiBootImage(const uint8_t *data, size_t size) : data_(data, data + size) {}
65 
GetBootHeaderVersion(const void * data)66   static uint32_t GetBootHeaderVersion(const void *data) {
67     return static_cast<const boot_img_hdr_v0 *>(data)->header_version;
68   }
69 
header_version() const70   uint32_t header_version() const { return GetBootHeaderVersion(data()); }
71 
kernel_pages() const72   uint32_t kernel_pages() const { return GetNumberOfPages(kernel_size()); }
73 
ramdisk_pages() const74   uint32_t ramdisk_pages() const { return GetNumberOfPages(ramdisk_size()); }
75 
kernel_offset() const76   uint32_t kernel_offset() const {
77     // The first page must be the boot image header.
78     return page_size();
79   }
80 
ramdisk_offset() const81   uint32_t ramdisk_offset() const {
82     return kernel_offset() + kernel_pages() * page_size();
83   }
84 
85   virtual uint32_t page_size() const = 0;
86   virtual uint32_t os_version() const = 0;
87   virtual uint32_t kernel_size() const = 0;
88   virtual uint32_t ramdisk_size() const = 0;
89   virtual uint32_t signature_size() const = 0;
90   virtual uint32_t signature_offset() const = 0;
91 
GetNumberOfPages(uint32_t value) const92   uint32_t GetNumberOfPages(uint32_t value) const {
93     return (value + page_size() - 1) / page_size();
94   }
95 
GetKernel() const96   std::vector<uint8_t> GetKernel() const {
97     return Slice(kernel_offset(), kernel_size());
98   }
99 
100   // Get "effective" boot image. The pure boot image without any boot signature.
GetBootImage() const101   std::vector<uint8_t> GetBootImage() const {
102     return Slice(0, signature_offset());
103   }
104 
105   // Parse a vector of vbmeta image from the boot signature section.
GetBootSignatures() const106   std::vector<android::fs_mgr::VBMetaData> GetBootSignatures() const {
107     const auto begin_offset = std::clamp<size_t>(signature_offset(), 0, size());
108     const uint8_t *buffer = data() + begin_offset;
109     // begin_offset + remaining_bytes <= size() because boot_signature must be
110     // the last section.
111     size_t remaining_bytes =
112         std::clamp<size_t>(signature_size(), 0, size() - begin_offset);
113     // In case boot_signature is misaligned, shift to the first AVB magic, and
114     // treat it as the actual beginning of boot signature.
115     while (remaining_bytes >= AVB_MAGIC_LEN) {
116       if (!memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN)) {
117         break;
118       }
119       ++buffer;
120       --remaining_bytes;
121     }
122     std::vector<android::fs_mgr::VBMetaData> vbmeta_images;
123     while (remaining_bytes >= sizeof(AvbVBMetaImageHeader)) {
124       if (memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN) != 0) {
125         break;
126       }
127       // Extract only the header to calculate the vbmeta image size.
128       android::fs_mgr::VBMetaData vbmeta_header(
129           buffer, sizeof(AvbVBMetaImageHeader), "boot_signature");
130       if (!vbmeta_header.GetVBMetaHeader(/* update_vbmeta_size */ true)) {
131         GTEST_LOG_(ERROR) << __FUNCTION__
132                           << "(): VBMetaData::GetVBMetaHeader() failed.";
133         return {};
134       }
135       const auto vbmeta_image_size = vbmeta_header.size();
136       GTEST_LOG_(INFO) << __FUNCTION__ << "(): Found vbmeta image with size "
137                        << vbmeta_image_size;
138       if (vbmeta_image_size < sizeof(AvbVBMetaImageHeader)) {
139         GTEST_LOG_(ERROR) << __FUNCTION__
140                           << "(): Impossible-sized vbmeta image: "
141                           << vbmeta_image_size;
142         return {};
143       }
144 
145       if (vbmeta_image_size > remaining_bytes) {
146         GTEST_LOG_(ERROR)
147             << __FUNCTION__
148             << "(): Premature EOF when parsing GKI boot signature.";
149         return {};
150       }
151 
152       vbmeta_images.emplace_back(buffer, vbmeta_image_size, "boot_signature");
153       buffer += vbmeta_image_size;
154       remaining_bytes -= vbmeta_image_size;
155     }
156     return vbmeta_images;
157   }
158 
159   virtual ~GkiBootImage() = default;
160 
161  protected:
data() const162   const uint8_t *data() const { return data_.data(); }
163 
size() const164   size_t size() const { return data_.size(); }
165 
Slice(size_t offset,size_t length) const166   std::vector<uint8_t> Slice(size_t offset, size_t length) const {
167     const auto begin_offset = std::clamp<size_t>(offset, 0, size());
168     const auto end_offset =
169         std::clamp<size_t>(begin_offset + length, begin_offset, size());
170     const auto begin = data() + begin_offset;
171     const auto end = data() + end_offset;
172     return {begin, end};
173   }
174 
175  private:
176   std::vector<uint8_t> data_;
177 };
178 
179 class GkiBootImageV2 : public GkiBootImage {
180  public:
GkiBootImageV2(const uint8_t * data,size_t size)181   GkiBootImageV2(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
182 
boot_header() const183   const boot_img_hdr_v2 *boot_header() const {
184     return reinterpret_cast<const boot_img_hdr_v2 *>(data());
185   }
186 
page_size() const187   uint32_t page_size() const override { return boot_header()->page_size; }
188 
os_version() const189   uint32_t os_version() const override { return boot_header()->os_version; }
190 
kernel_size() const191   uint32_t kernel_size() const override { return boot_header()->kernel_size; }
192 
ramdisk_size() const193   uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
194 
signature_size() const195   uint32_t signature_size() const override {
196     // The last 16K bytes are by definition the GKI boot signature.
197     static constexpr uint32_t kBootSignatureSize = 16_KiB;
198     return kBootSignatureSize;
199   }
200 
signature_offset() const201   uint32_t signature_offset() const override {
202     if (size() < signature_size()) {
203       return 0;
204     }
205     return size() - signature_size();
206   }
207 
recovery_dtbo_size() const208   uint32_t recovery_dtbo_size() const {
209     return boot_header()->recovery_dtbo_size;
210   }
211 
recovery_dtbo_offset() const212   uint64_t recovery_dtbo_offset() const {
213     return boot_header()->recovery_dtbo_offset;
214   }
215 };
216 
217 class GkiBootImageV4 : public GkiBootImage {
218  public:
GkiBootImageV4(const uint8_t * data,size_t size)219   GkiBootImageV4(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
220 
boot_header() const221   const boot_img_hdr_v4 *boot_header() const {
222     return reinterpret_cast<const boot_img_hdr_v4 *>(data());
223   }
224 
page_size() const225   uint32_t page_size() const override {
226     static constexpr uint32_t kPageSize = 4096;
227     return kPageSize;
228   }
229 
os_version() const230   uint32_t os_version() const override { return boot_header()->os_version; }
231 
kernel_size() const232   uint32_t kernel_size() const override { return boot_header()->kernel_size; }
233 
ramdisk_size() const234   uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
235 
signature_size() const236   uint32_t signature_size() const override {
237     // For Android12 GKI, the |.signature_size| field is respected.
238     // For Android13+ GKI, the |.signature_size| field must be zero, and the
239     // last 16K bytes are by definition the GKI boot signature.
240     static constexpr uint32_t kBootSignatureSize = 16_KiB;
241     const uint32_t value = boot_header()->signature_size;
242     return value ? value : kBootSignatureSize;
243   }
244 
signature_offset() const245   uint32_t signature_offset() const override {
246     return ramdisk_offset() + ramdisk_pages() * page_size();
247   }
248 };
249 
GetAvbProperty(const std::string & name,const std::vector<android::fs_mgr::VBMetaData> & vbmeta_images)250 std::string GetAvbProperty(
251     const std::string &name,
252     const std::vector<android::fs_mgr::VBMetaData> &vbmeta_images) {
253   const std::string prop_name = "com.android.build." + name;
254   return android::fs_mgr::GetAvbPropertyDescriptor(prop_name, vbmeta_images);
255 }
256 
LoadAndVerifyGkiBootImage(std::vector<android::fs_mgr::VBMetaData> * boot_signature_images)257 std::unique_ptr<GkiBootImage> LoadAndVerifyGkiBootImage(
258     std::vector<android::fs_mgr::VBMetaData> *boot_signature_images) {
259   const std::string block_device_path = GetBlockDevicePath("boot");
260   const std::string TAG = __FUNCTION__ + "("s + block_device_path + ")";
261   SCOPED_TRACE(TAG);
262 
263   std::string block_device_data;
264   if (!android::base::ReadFileToString(block_device_path, &block_device_data,
265                                        /* follow_symlinks */ true)) {
266     ADD_FAILURE() << "Failed to read '" << block_device_path
267                   << "': " << strerror(errno);
268     return nullptr;
269   }
270   if (block_device_data.size() <= 4096) {
271     ADD_FAILURE() << "Size of '" << block_device_path
272                   << "' is impossibly small: " << block_device_data.size();
273     return nullptr;
274   }
275 
276   if (block_device_data.substr(0, BOOT_MAGIC_SIZE) != BOOT_MAGIC) {
277     ADD_FAILURE() << "Device has invalid boot magic: " << block_device_path;
278     return nullptr;
279   }
280 
281   // Remove the AVB footer and chained vbmeta image if there is any.
282   if (block_device_data.size() > AVB_FOOTER_SIZE) {
283     const uint8_t *footer_address =
284         reinterpret_cast<const uint8_t *>(block_device_data.data()) +
285         block_device_data.size() - AVB_FOOTER_SIZE;
286     AvbFooter vbmeta_footer;
287     if (avb_footer_validate_and_byteswap(
288             reinterpret_cast<const AvbFooter *>(footer_address),
289             &vbmeta_footer)) {
290       block_device_data.resize(vbmeta_footer.original_image_size);
291     }
292   }
293 
294   std::unique_ptr<GkiBootImage> boot_image;
295   const auto boot_header_version =
296       GkiBootImage::GetBootHeaderVersion(block_device_data.data());
297   if (boot_header_version == 4) {
298     boot_image = std::make_unique<GkiBootImageV4>(
299         reinterpret_cast<const uint8_t *>(block_device_data.data()),
300         block_device_data.size());
301   } else if (boot_header_version == 2) {
302     boot_image = std::make_unique<GkiBootImageV2>(
303         reinterpret_cast<const uint8_t *>(block_device_data.data()),
304         block_device_data.size());
305   } else {
306     ADD_FAILURE() << "Unexpected boot header version: " << boot_header_version;
307     return nullptr;
308   }
309 
310   *boot_signature_images = boot_image->GetBootSignatures();
311   if (boot_signature_images->empty()) {
312     ADD_FAILURE() << "Failed to load the boot signature.";
313     return nullptr;
314   }
315 
316   // Verify that the vbmeta images in boot_signature are certified.
317   for (const auto &vbmeta_image : *boot_signature_images) {
318     size_t pk_len;
319     const uint8_t *pk_data;
320     const auto vbmeta_verify_result = avb_vbmeta_image_verify(
321         vbmeta_image.data(), vbmeta_image.size(), &pk_data, &pk_len);
322     if (vbmeta_verify_result != AVB_VBMETA_VERIFY_RESULT_OK) {
323       ADD_FAILURE() << "Failed to verify boot_signature: "
324                     << avb_vbmeta_verify_result_to_string(vbmeta_verify_result);
325       return nullptr;
326     }
327     const std::string out_public_key_data(
328         reinterpret_cast<const char *>(pk_data), pk_len);
329     if (out_public_key_data.empty()) {
330       ADD_FAILURE() << "The GKI image descriptor is not signed.";
331       continue;
332     }
333     if (!ValidatePublicKeyBlob(out_public_key_data)) {
334       ADD_FAILURE()
335           << "The GKI image descriptor is not signed by an official key.";
336       continue;
337     }
338   }
339 
340   GTEST_LOG_(INFO) << TAG << ": boot.fingerprint: "
341                    << GetAvbProperty("boot.fingerprint",
342                                      *boot_signature_images);
343   GTEST_LOG_(INFO) << TAG
344                    << ": header version: " << boot_image->header_version()
345                    << ", kernel size: " << boot_image->kernel_size()
346                    << ", ramdisk size: " << boot_image->ramdisk_size()
347                    << ", signature size: " << boot_image->signature_size();
348 
349   return boot_image;
350 }
351 
352 // Verify image data integrity with an AVB hash descriptor.
VerifyImageDescriptor(const std::vector<uint8_t> & image,const android::fs_mgr::FsAvbHashDescriptor & descriptor)353 void VerifyImageDescriptor(
354     const std::vector<uint8_t> &image,
355     const android::fs_mgr::FsAvbHashDescriptor &descriptor) {
356   const std::string TAG = __FUNCTION__ + "("s + descriptor.partition_name + ")";
357   SCOPED_TRACE(TAG);
358 
359   ASSERT_EQ(image.size(), descriptor.image_size);
360 
361   const std::string &salt_str = descriptor.salt;
362   const std::string &expected_digest_str = descriptor.digest;
363 
364   const std::string hash_algorithm(
365       reinterpret_cast<const char *>(descriptor.hash_algorithm));
366   GTEST_LOG_(INFO) << TAG << ": hash_algorithm = " << hash_algorithm;
367 
368   std::unique_ptr<ShaHasher> hasher = CreateShaHasher(hash_algorithm);
369   ASSERT_NE(nullptr, hasher);
370 
371   std::vector<uint8_t> salt, expected_digest, out_digest;
372 
373   ASSERT_TRUE(HexToBytes(salt_str, &salt))
374       << "Invalid salt in descriptor: " << salt_str;
375   ASSERT_TRUE(HexToBytes(expected_digest_str, &expected_digest))
376       << "Invalid digest in descriptor: " << expected_digest_str;
377 
378   ASSERT_EQ(expected_digest.size(), hasher->GetDigestSize());
379   out_digest.resize(hasher->GetDigestSize());
380 
381   ASSERT_TRUE(hasher->CalculateDigest(image.data(), image.size(), salt.data(),
382                                       descriptor.salt_len, out_digest.data()))
383       << "Unable to calculate image digest.";
384 
385   ASSERT_EQ(out_digest.size(), expected_digest.size())
386       << "Calculated digest size does not match expected digest size.";
387 
388   ASSERT_EQ(out_digest, expected_digest)
389       << "Calculated digest does not match expected digest.";
390 }
391 }  // namespace
392 
393 class GkiComplianceTest : public testing::Test {
394   static const std::regex ogkiUnameRegex;
395 
396  protected:
SetUp()397   void SetUp() override {
398     // Fetch device runtime information.
399     runtime_info = android::vintf::VintfObject::GetRuntimeInfo();
400     ASSERT_NE(nullptr, runtime_info);
401 
402     product_first_api_level = GetProductFirstApiLevel();
403 
404     /* Skip for non-arm64 kernels that do not mandate GKI yet. */
405     if (runtime_info->hardwareId() != "aarch64" &&
406         runtime_info->hardwareId() != "armv8l") {
407       GTEST_SKIP() << "Exempt from GKI test on non-arm64 kernel devices";
408     }
409 
410     GTEST_LOG_(INFO) << runtime_info->osName() << " "
411                      << runtime_info->osRelease();
412     GTEST_LOG_(INFO) << "Product first API level: " << product_first_api_level;
413   }
414 
415   bool IsOgkiBuild() const;
416   bool ShouldSkipGkiComplianceV2();
417 
418   std::shared_ptr<const android::vintf::RuntimeInfo> runtime_info;
419   int product_first_api_level;
420 };
421 
422 const std::regex GkiComplianceTest::ogkiUnameRegex =
423     std::regex("-abogki[0-9]+(-|$)");
424 
IsOgkiBuild() const425 bool GkiComplianceTest::IsOgkiBuild() const {
426   /* Android release version should at least be android14 for OGKI build. */
427   const auto kernel_release = android::kver::KernelRelease::Parse(
428       runtime_info->osRelease(), /* allow_suffix = */ true);
429   if (!kernel_release.has_value() || kernel_release->android_release() < 14) {
430     return false;
431   }
432 
433   return std::regex_search(runtime_info->osRelease(), ogkiUnameRegex);
434 }
435 
ShouldSkipGkiComplianceV2()436 bool GkiComplianceTest::ShouldSkipGkiComplianceV2() {
437   /* Skip for devices if the kernel version is not >= 5.10. */
438   if (runtime_info->kernelVersion().dropMinor() <
439       android::vintf::Version{5, 10}) {
440     GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on kernel version: "
441                      << runtime_info->kernelVersion();
442     return true;
443   }
444   /* Skip for devices launched before Android S. */
445   if (product_first_api_level < __ANDROID_API_S__) {
446     GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on pre-S launched devices";
447     return true;
448   }
449   /* Skip for OGKI kernel builds. */
450   if (IsOgkiBuild()) {
451     GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on OGKI kernel";
452     return true;
453   }
454   /*
455    * Skip for automotive devices if the kernel version is not >= 5.15 or
456    * the device is launched before Android T.
457    */
458   if (IsAutomotiveDevice()) {
459     if (runtime_info->kernelVersion().dropMinor() <
460         android::vintf::Version{5, 15}) {
461       GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
462                        << runtime_info->kernelVersion();
463       return true;
464     }
465     if (product_first_api_level < __ANDROID_API_T__) {
466       GTEST_LOG_(INFO) << "Exempt from GKI test on pre-T launched devices";
467       return true;
468     }
469   }
470   /*
471    * Skip for TV devices if the kernel version is not >= 5.15 or
472    * the device is launched before Android U.
473    */
474   if (IsTvDevice()) {
475     if (runtime_info->kernelVersion().dropMinor() <
476         android::vintf::Version{5, 15}) {
477       GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
478                        << runtime_info->kernelVersion();
479       return true;
480     }
481     if (product_first_api_level < __ANDROID_API_U__) {
482       GTEST_LOG_(INFO) << "Exempt from GKI test on pre-U launched TV devices";
483       return true;
484     }
485   }
486   return false;
487 }
488 
TEST_F(GkiComplianceTest,GkiComplianceV1)489 TEST_F(GkiComplianceTest, GkiComplianceV1) {
490   if (product_first_api_level < __ANDROID_API_R__) {
491     GTEST_SKIP() << "Exempt from GKI 1.0 test: product first API level ("
492                  << product_first_api_level << ") < " << __ANDROID_API_R__;
493   }
494   if (IsAutomotiveDevice()) {
495     GTEST_SKIP() << "Skip GKI vbmeta check for automotive devices";
496   }
497   if (IsTvDevice()) {
498     GTEST_SKIP() << "Exempt from GKI 1.0 test on TV devices";
499   }
500   /* Skip for devices if the kernel version is not 5.4. */
501   if (runtime_info->kernelVersion().dropMinor() !=
502       android::vintf::Version{5, 4}) {
503     GTEST_SKIP() << "Exempt from GKI 1.0 test on kernel version: "
504                  << runtime_info->kernelVersion();
505   }
506 
507   /* load vbmeta struct from boot, verify struct integrity */
508   std::string out_public_key_data;
509   android::fs_mgr::VBMetaVerifyResult out_verify_result;
510   const std::string boot_path = GetBlockDevicePath("boot");
511   std::unique_ptr<android::fs_mgr::VBMetaData> vbmeta =
512       android::fs_mgr::LoadAndVerifyVbmetaByPath(
513           boot_path, "boot", "" /* expected_key_blob */,
514           true /* allow verification error */, false /* rollback_protection */,
515           false /* is_chained_vbmeta */, &out_public_key_data,
516           nullptr /* out_verification_disabled */, &out_verify_result);
517 
518   ASSERT_TRUE(vbmeta) << "Verification of GKI vbmeta fails.";
519   ASSERT_FALSE(out_public_key_data.empty()) << "The GKI image is not signed.";
520   EXPECT_TRUE(ValidatePublicKeyBlob(out_public_key_data))
521       << "The GKI image is not signed by an official key.";
522   EXPECT_EQ(out_verify_result, android::fs_mgr::VBMetaVerifyResult::kSuccess)
523       << "Verification of the GKI vbmeta structure failed.";
524 
525   /* verify boot partition according to vbmeta structure */
526   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> descriptor =
527       android::fs_mgr::GetHashDescriptor("boot", std::move(*vbmeta));
528   ASSERT_TRUE(descriptor)
529       << "Failed to load hash descriptor from boot.img vbmeta";
530 
531   android::base::unique_fd fd(open(boot_path.c_str(), O_RDONLY));
532   ASSERT_TRUE(fd.ok()) << "Fail to open boot partition. Try 'adb root'.";
533 
534   std::vector<uint8_t> boot_partition_vector;
535   boot_partition_vector.resize(descriptor->image_size);
536   ASSERT_TRUE(android::base::ReadFully(fd, boot_partition_vector.data(),
537                                        descriptor->image_size))
538       << "Could not read boot partition to vector.";
539 
540   ASSERT_NO_FATAL_FAILURE(
541       VerifyImageDescriptor(boot_partition_vector, *descriptor));
542 }
543 
544 // Verify the entire boot image.
TEST_F(GkiComplianceTest,GkiComplianceV2)545 TEST_F(GkiComplianceTest, GkiComplianceV2) {
546   if (ShouldSkipGkiComplianceV2()) {
547     GTEST_SKIP() << "Skipping GkiComplianceV2 test";
548   }
549 
550   // GKI 2.0 ensures getKernelLevel() to return valid value.
551   std::string error_msg;
552   const auto kernel_level =
553       android::vintf::VintfObject::GetInstance()->getKernelLevel(&error_msg);
554   ASSERT_NE(android::vintf::Level::UNSPECIFIED, kernel_level) << error_msg;
555 
556   std::vector<android::fs_mgr::VBMetaData> boot_signature_images;
557   std::unique_ptr<GkiBootImage> boot_image =
558       LoadAndVerifyGkiBootImage(&boot_signature_images);
559   ASSERT_NE(nullptr, boot_image);
560   ASSERT_LE(1, boot_signature_images.size());
561   EXPECT_EQ(4, boot_image->header_version());
562 
563   if (kernel_level >= android::vintf::Level::T) {
564     GTEST_LOG_(INFO)
565         << "Android T+ verification scheme. The GKI boot.img must contain only "
566            "the generic kernel but not the generic ramdisk.";
567     EXPECT_EQ(0, boot_image->ramdisk_size())
568         << "'boot' partition mustn't include a ramdisk image.";
569     EXPECT_EQ(0, boot_image->os_version())
570         << "OS version and security patch level should be defined in the "
571            "chained vbmeta image instead.";
572   }
573 
574   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> boot_descriptor =
575       android::fs_mgr::GetHashDescriptor("boot", boot_signature_images);
576   ASSERT_NE(nullptr, boot_descriptor)
577       << "Failed to load the 'boot' hash descriptor.";
578   ASSERT_NO_FATAL_FAILURE(
579       VerifyImageDescriptor(boot_image->GetBootImage(), *boot_descriptor));
580 }
581 
582 // Verify only the 'generic_kernel' descriptor.
TEST_F(GkiComplianceTest,GkiComplianceV2_kernel)583 TEST_F(GkiComplianceTest, GkiComplianceV2_kernel) {
584   if (ShouldSkipGkiComplianceV2()) {
585     GTEST_SKIP() << "Skipping GkiComplianceV2 test";
586   }
587 
588   // GKI 2.0 ensures getKernelLevel() to return valid value.
589   std::string error_msg;
590   const auto kernel_level =
591       android::vintf::VintfObject::GetInstance()->getKernelLevel(&error_msg);
592   ASSERT_NE(android::vintf::Level::UNSPECIFIED, kernel_level) << error_msg;
593   if (kernel_level < android::vintf::Level::T) {
594     GTEST_SKIP() << "Skip for kernel level (" << kernel_level << ") < T ("
595                  << android::vintf::Level::T << ")";
596   }
597 
598   std::vector<android::fs_mgr::VBMetaData> boot_signature_images;
599   std::unique_ptr<GkiBootImage> boot_image =
600       LoadAndVerifyGkiBootImage(&boot_signature_images);
601   ASSERT_NE(nullptr, boot_image);
602   ASSERT_LE(1, boot_signature_images.size());
603 
604   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor>
605       generic_kernel_descriptor = android::fs_mgr::GetHashDescriptor(
606           "generic_kernel", boot_signature_images);
607   ASSERT_NE(nullptr, generic_kernel_descriptor)
608       << "Failed to load the 'generic_kernel' hash descriptor.";
609   ASSERT_NO_FATAL_FAILURE(VerifyImageDescriptor(boot_image->GetKernel(),
610                                                 *generic_kernel_descriptor));
611 }
612 
613 // Verify OGKI build is approved.
TEST_F(GkiComplianceTest,OgkiCompliance)614 TEST_F(GkiComplianceTest, OgkiCompliance) {
615   if (!IsOgkiBuild()) {
616     GTEST_SKIP() << "OGKI build not detected";
617   }
618 
619   const auto kernel_release =
620       android::kver::KernelRelease::Parse(runtime_info->osRelease(),
621                                           /* allow_suffix = */ true);
622   ASSERT_TRUE(kernel_release.has_value())
623       << "Failed to parse the kernel release string: "
624       << runtime_info->osRelease();
625 
626   auto branch =
627       std::format("android{}-{}.{}", kernel_release->android_release(),
628                   runtime_info->kernelVersion().version,
629                   runtime_info->kernelVersion().majorRev);
630   auto approved_builds_result = ogki::GetApprovedBuilds(branch);
631   ASSERT_TRUE(approved_builds_result.ok())
632       << "Failed to get approved OGKI builds: "
633       << approved_builds_result.error().message();
634 
635   const auto uname_hash = sha256(runtime_info->osRelease());
636   EXPECT_TRUE(approved_builds_result.value().contains(uname_hash));
637 }
638 
main(int argc,char * argv[])639 int main(int argc, char *argv[]) {
640   ::testing::InitGoogleTest(&argc, argv);
641   android::base::InitLogging(argv, android::base::StderrLogger);
642   return RUN_ALL_TESTS();
643 }
644