From 6c9bdb839f86874ccff3b8d16c9275e02087b4fc Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 23 Jan 2024 09:32:04 +0000 Subject: [PATCH] KeyMint: test HAL version matches feature Test: VtsAidlKeyMintTargetTest Bug: 304309651 Change-Id: I7e38c2ab3ff4f6b5f9035af865ca5ebe6ff24cc1 --- .../vts/functional/KeyMintAidlTestBase.cpp | 44 ++++++++++ .../aidl/vts/functional/KeyMintAidlTestBase.h | 2 + .../aidl/vts/functional/KeyMintTest.cpp | 85 +++++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index d3f6ae393e..087f7632b0 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -64,6 +64,13 @@ namespace test { namespace { +// Possible values for the feature version. Assumes that future KeyMint versions +// will continue with the 100 * AIDL_version numbering scheme. +// +// Must be kept in numerically increasing order. +const int32_t kFeatureVersions[] = {10, 11, 20, 30, 40, 41, 100, 200, + 300, 400, 500, 600, 700, 800, 900}; + // Invalid value for a patchlevel (which is of form YYYYMMDD). const uint32_t kInvalidPatchlevel = 99998877; @@ -2278,6 +2285,43 @@ bool check_feature(const std::string& name) { return hasFeature; } +// Return the numeric value associated with a feature. +std::optional keymint_feature_value(bool strongbox) { + std::string name = strongbox ? FEATURE_STRONGBOX_KEYSTORE : FEATURE_HARDWARE_KEYSTORE; + ::android::String16 name16(name.c_str()); + ::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager()); + ::android::sp<::android::IBinder> binder( + sm->waitForService(::android::String16("package_native"))); + if (binder == nullptr) { + GTEST_LOG_(ERROR) << "waitForService package_native failed"; + return std::nullopt; + } + ::android::sp<::android::content::pm::IPackageManagerNative> packageMgr = + ::android::interface_cast<::android::content::pm::IPackageManagerNative>(binder); + if (packageMgr == nullptr) { + GTEST_LOG_(ERROR) << "Cannot find package manager"; + return std::nullopt; + } + + // Package manager has no mechanism to retrieve the version of a feature, + // only to indicate whether a certain version or above is present. + std::optional result = std::nullopt; + for (auto version : kFeatureVersions) { + bool hasFeature = false; + auto status = packageMgr->hasSystemFeature(name16, version, &hasFeature); + if (!status.isOk()) { + GTEST_LOG_(ERROR) << "hasSystemFeature('" << name << "', " << version + << ") failed: " << status; + return result; + } else if (hasFeature) { + result = version; + } else { + break; + } + } + return result; +} + } // namespace test } // namespace aidl::android::hardware::security::keymint diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 4fb711c7bb..4ed769878a 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -56,6 +56,7 @@ constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF; const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; +const string FEATURE_HARDWARE_KEYSTORE = "android.hardware.hardware_keystore"; // RAII class to ensure that a keyblob is deleted regardless of how a test exits. class KeyBlobDeleter { @@ -444,6 +445,7 @@ void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode, void p256_pub_key(const vector& coseKeyData, EVP_PKEY_Ptr* signingKey); void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result); bool check_feature(const std::string& name); +std::optional keymint_feature_value(bool strongbox); AuthorizationSet HwEnforcedAuthorizations(const vector& key_characteristics); AuthorizationSet SwEnforcedAuthorizations(const vector& key_characteristics); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index a2e20dcce5..3d2d7fb83b 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -8794,6 +8795,90 @@ TEST_P(VsrRequirementTest, Vsr14Test) { INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest); +class InstanceTest : public testing::Test { + protected: + static void SetUpTestSuite() { + auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor); + for (auto& param : params) { + ASSERT_TRUE(AServiceManager_isDeclared(param.c_str())) + << "IKeyMintDevice instance " << param << " found but not declared."; + ::ndk::SpAIBinder binder(AServiceManager_waitForService(param.c_str())); + auto keymint = IKeyMintDevice::fromBinder(binder); + ASSERT_NE(keymint, nullptr) << "Failed to get IKeyMintDevice instance " << param; + + KeyMintHardwareInfo info; + ASSERT_TRUE(keymint->getHardwareInfo(&info).isOk()); + ASSERT_EQ(keymints_.count(info.securityLevel), 0) + << "There must be exactly one IKeyMintDevice with security level " + << info.securityLevel; + + keymints_[info.securityLevel] = std::move(keymint); + } + } + + int32_t AidlVersion(shared_ptr keymint) { + int32_t version = 0; + auto status = keymint->getInterfaceVersion(&version); + if (!status.isOk()) { + ADD_FAILURE() << "Failed to determine interface version"; + } + return version; + } + + static std::map> keymints_; +}; + +std::map> InstanceTest::keymints_; + +// @VsrTest = VSR-3.10-017 +// Check that the AIDL version advertised by the HAL service matches +// the value in the package manager feature version. +TEST_F(InstanceTest, AidlVersionInFeature) { + if (is_gsi_image()) { + GTEST_SKIP() << "Versions not required to match under GSI"; + } + if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 1) { + auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second; + int32_t tee_aidl_version = AidlVersion(tee) * 100; + std::optional tee_feature_version = keymint_feature_value(/* strongbox */ false); + ASSERT_TRUE(tee_feature_version.has_value()); + EXPECT_EQ(tee_aidl_version, tee_feature_version.value()); + } + if (keymints_.count(SecurityLevel::STRONGBOX) == 1) { + auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second; + int32_t sb_aidl_version = AidlVersion(sb) * 100; + std::optional sb_feature_version = keymint_feature_value(/* strongbox */ true); + ASSERT_TRUE(sb_feature_version.has_value()); + EXPECT_EQ(sb_aidl_version, sb_feature_version.value()); + } +} + +// @VsrTest = VSR-3.10-017 +// Check that if package manager advertises support for KeyMint of a particular version, that +// version is present as a HAL service. +TEST_F(InstanceTest, FeatureVersionInAidl) { + if (is_gsi_image()) { + GTEST_SKIP() << "Versions not required to match under GSI"; + } + std::optional tee_feature_version = keymint_feature_value(/* strongbox */ false); + if (tee_feature_version.has_value() && tee_feature_version.value() >= 100) { + // Feature flag advertises the existence of KeyMint; check it is present. + ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1); + auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second; + int32_t tee_aidl_version = AidlVersion(tee) * 100; + EXPECT_EQ(tee_aidl_version, tee_feature_version.value()); + } + + std::optional sb_feature_version = keymint_feature_value(/* strongbox */ true); + if (sb_feature_version.has_value() && sb_feature_version.value() >= 100) { + // Feature flag advertises the existence of KeyMint; check it is present. + ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1); + auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second; + int32_t sb_aidl_version = AidlVersion(sb) * 100; + EXPECT_EQ(sb_aidl_version, sb_feature_version.value()); + } +} + } // namespace aidl::android::hardware::security::keymint::test using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;