Merge "KeyMint: test HAL version matches feature" into main
This commit is contained in:
commit
922a49f278
3 changed files with 131 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue