diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 7a4359d31a..41b161d11d 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -43,8 +43,11 @@ cc_defaults { "android.hardware.gatekeeper-V1-ndk", "android.hardware.security.rkp-V3-ndk", "android.hardware.security.secureclock-V1-ndk", + "libavb_user", + "libavb", "libcppbor_external", "libcppcose_rkp", + "libfs_mgr", "libjsoncpp", "libkeymint", "libkeymint_remote_prov_support", diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp index dff0498ce5..54f187c611 100644 --- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp +++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp @@ -21,7 +21,11 @@ #include #include +#include #include +#include +#include +#include #include #include "KeyMintAidlTestBase.h" @@ -34,50 +38,118 @@ using ::std::vector; // Since this test needs to talk to KeyMint HAL, it can only run as root. Thus, // bootloader can not be locked. -class BootloaderStateTest : public KeyMintAidlTestBase {}; +class BootloaderStateTest : public KeyMintAidlTestBase { + public: + virtual void SetUp() override { + KeyMintAidlTestBase::SetUp(); + + // Generate a key with attestation. + vector key_blob; + vector key_characteristics; + AuthorizationSet keyDesc = AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .AttestationChallenge("foo") + .AttestationApplicationId("bar") + .Digest(Digest::NONE) + .SetDefaultValidity(); + auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics); + // If factory provisioned attestation key is not supported by Strongbox, + // then create a key with self-signed attestation and use it as the + // attestation key instead. + if (SecLevel() == SecurityLevel::STRONGBOX && + result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) { + result = GenerateKeyWithSelfSignedAttestKey( + AuthorizationSetBuilder() + .EcdsaKey(EcCurve::P_256) + .AttestKey() + .SetDefaultValidity(), /* attest key params */ + keyDesc, &key_blob, &key_characteristics); + } + ASSERT_EQ(ErrorCode::OK, result); + + // Parse attested AVB values. + X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + ASSERT_TRUE(cert.get()); + + ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); + ASSERT_TRUE(attest_rec); + + auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &attestedVbKey_, + &attestedVbState_, &attestedBootloaderState_, + &attestedVbmetaDigest_); + ASSERT_EQ(error, ErrorCode::OK); + } + + vector attestedVbKey_; + VerifiedBoot attestedVbState_; + bool attestedBootloaderState_; + vector attestedVbmetaDigest_; +}; // Check that attested bootloader state is set to unlocked. -TEST_P(BootloaderStateTest, IsUnlocked) { - // Generate a key with attestation. - vector key_blob; - vector key_characteristics; - AuthorizationSet keyDesc = AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(EcCurve::P_256) - .AttestationChallenge("foo") - .AttestationApplicationId("bar") - .Digest(Digest::NONE) - .SetDefaultValidity(); - auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics); - // If factory provisioned attestation key is not supported by Strongbox, - // then create a key with self-signed attestation and use it as the - // attestation key instead. - if (SecLevel() == SecurityLevel::STRONGBOX && - result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) { - result = GenerateKeyWithSelfSignedAttestKey( - AuthorizationSetBuilder() - .EcdsaKey(EcCurve::P_256) - .AttestKey() - .SetDefaultValidity(), /* attest key params */ - keyDesc, &key_blob, &key_characteristics); +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_, VerifiedBoot::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; } - ASSERT_EQ(ErrorCode::OK, result); +} - // Parse attested AVB values. - X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); - ASSERT_TRUE(cert.get()); +// 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(); - ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); - ASSERT_TRUE(attest_rec); + // 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"; - vector key; - VerifiedBoot attestedVbState; - bool attestedBootloaderState; - vector attestedVbmetaDigest; - auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &key, &attestedVbState, - &attestedBootloaderState, &attestedVbmetaDigest); - ASSERT_EQ(error, ErrorCode::OK); - ASSERT_FALSE(attestedBootloaderState) << "This test runs as root. Bootloader must be unlocked."; + // 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_KEYMINT_AIDL_TEST(BootloaderStateTest);