/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include "KeymasterHidlTest.h" namespace android::hardware::keymaster::V4_0::test { using ::std::string; using ::std::vector; // Since this test needs to talk to Keymaster HAL, it can only run as root. Thus, // bootloader can not be locked. class BootloaderStateTest : public KeymasterHidlTest { public: virtual void SetUp() override { KeymasterHidlTest::SetUp(); // Generate a key. auto ec = GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256)); ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate key."; // Generate attestation. hidl_vec> cert_chain; ec = AttestKey(AuthorizationSetBuilder() .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")), &cert_chain); ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate attestation."; X509_Ptr cert(parse_cert_blob(cert_chain[0])); ASSERT_TRUE(cert.get()) << "Failed to parse certificate blob."; ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); ASSERT_TRUE(attest_rec) << "Failed to get attestation record."; // Parse root of trust. auto result = parse_root_of_trust(attest_rec->data, attest_rec->length, &attestedVbKey_, &attestedVbState_, &attestedBootloaderState_, &attestedVbmetaDigest_); ASSERT_EQ(result, ErrorCode::OK) << "Failed to parse root of trust."; } hidl_vec attestedVbKey_; keymaster_verified_boot_t attestedVbState_; bool attestedBootloaderState_; hidl_vec attestedVbmetaDigest_; }; // Check that attested bootloader state is set to unlocked. TEST_P(BootloaderStateTest, BootloaderIsUnlocked) { ASSERT_FALSE(attestedBootloaderState_) << "This test runs as root. Bootloader must be unlocked."; } // Check that verified boot state is set to "unverified", i.e. "orange". TEST_P(BootloaderStateTest, VbStateIsUnverified) { // Unlocked bootloader implies that verified boot state must be "unverified". ASSERT_EQ(attestedVbState_, KM_VERIFIED_BOOT_UNVERIFIED) << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; // AVB spec stipulates that bootloader must set "androidboot.verifiedbootstate" parameter // on the kernel command-line. This parameter is exposed to userspace as // "ro.boot.verifiedbootstate" property. auto vbStateProp = ::android::base::GetProperty("ro.boot.verifiedbootstate", ""); ASSERT_EQ(vbStateProp, "orange") << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; } // Following error codes from avb_slot_data() mean that slot data was loaded // (even if verification failed). static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) { switch (result) { case AVB_SLOT_VERIFY_RESULT_OK: case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: return true; default: return false; } } // Check that attested vbmeta digest is correct. TEST_P(BootloaderStateTest, VbmetaDigest) { AvbSlotVerifyData* avbSlotData; auto suffix = fs_mgr_get_slot_suffix(); const char* partitions[] = {nullptr}; auto avbOps = avb_ops_user_new(); // For VTS, devices run with vendor_boot-debug.img, which is not release key // signed. Use AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR to bypass avb // verification errors. This is OK since we only care about the digest for // this test case. auto result = avb_slot_verify(avbOps, partitions, suffix.c_str(), AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR, AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData); ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data"; // Unfortunately, bootloader is not required to report the algorithm used // to calculate the digest. There are only two supported options though, // SHA256 and SHA512. Attested VBMeta digest must match one of these. vector digest256(AVB_SHA256_DIGEST_SIZE); vector digest512(AVB_SHA512_DIGEST_SIZE); avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256, digest256.data()); avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512, digest512.data()); ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512)) << "Attested digest does not match computed digest."; } INSTANTIATE_KEYMASTER_HIDL_TEST(BootloaderStateTest); } // namespace android::hardware::keymaster::V4_0::test