Merge "KeyMint: test HAL version matches feature" into main

This commit is contained in:
David Drysdale 2024-01-24 11:54:13 +00:00 committed by Gerrit Code Review
commit 922a49f278
3 changed files with 131 additions and 0 deletions

View file

@ -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<int32_t> 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<int32_t> 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

View file

@ -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<uint8_t>& 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<int32_t> keymint_feature_value(bool strongbox);
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);

View file

@ -21,6 +21,7 @@
#include <algorithm>
#include <iostream>
#include <map>
#include <openssl/curve25519.h>
#include <openssl/ec.h>
@ -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<IKeyMintDevice> 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<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
};
std::map<SecurityLevel, shared_ptr<IKeyMintDevice>> 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<int32_t> 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<int32_t> 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<int32_t> 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<int32_t> 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;