From 0e0f60cff1231f8cf7e9299d251f50b3345d0047 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Thu, 20 Apr 2023 22:48:39 +0000 Subject: Support for non-factory attestation in Strongbox. Updated the BootLoaderStateTest for strongbox implementations which do not support factory attestation. Bug: 255344624 Test: vts -m VtsAidlKeyMintTarget Change-Id: I8fe176a18fc0b9e2b2d0b012b7b63124d15c9e2f Merged-In: I8fe176a18fc0b9e2b2d0b012b7b63124d15c9e2f --- .../aidl/vts/functional/BootloaderStateTest.cpp | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'security/keymint/aidl/vts/functional/BootloaderStateTest.cpp') diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp index 723edeef3d..dff0498ce5 100644 --- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp +++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp @@ -34,20 +34,13 @@ 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 testing::TestWithParam { - public: - virtual void SetUp() override { - ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); - keyMint_ = IKeyMintDevice::fromBinder(binder); - ASSERT_TRUE(keyMint_) << "Failed to get KM device"; - } - - std::shared_ptr keyMint_; -}; +class BootloaderStateTest : public KeyMintAidlTestBase {}; // 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) @@ -55,15 +48,23 @@ TEST_P(BootloaderStateTest, IsUnlocked) { .AttestationApplicationId("bar") .Digest(Digest::NONE) .SetDefaultValidity(); - KeyCreationResult creationResult; - auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult); - ASSERT_TRUE(kmStatus.isOk()); - - vector key_cert_chain = std::move(creationResult.certificateChain); + 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. - const auto& attestation_cert = key_cert_chain[0].encodedCertificate; - X509_Ptr cert(parse_cert_blob(attestation_cert)); + X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); ASSERT_TRUE(cert.get()); ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); -- cgit v1.2.3 From dbb1c89347158dd6d3b573e4c157f1a260e43be7 Mon Sep 17 00:00:00 2001 From: Tri Vo Date: Tue, 2 May 2023 14:36:31 -0700 Subject: Test cases for attested Root-of-Trust Add tests for verfied boot state and VBMeta digest. Bug: 255344624 Test: VtsKeyMintAidlTargetTest Change-Id: I4f0697e1a7cb83ca87150b6683cac3084a593864 Merged-In: I4f0697e1a7cb83ca87150b6683cac3084a593864 --- .../aidl/vts/functional/BootloaderStateTest.cpp | 154 +++++++++++++++------ 1 file changed, 113 insertions(+), 41 deletions(-) (limited to 'security/keymint/aidl/vts/functional/BootloaderStateTest.cpp') 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()); - - ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); - ASSERT_TRUE(attest_rec); - - 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."; +} + +// 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_KEYMINT_AIDL_TEST(BootloaderStateTest); -- cgit v1.2.3