Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50d605f8 authored by David Drysdale's avatar David Drysdale Committed by Automerger Merge Worker
Browse files

Merge "KeyMint: test HAL version matches feature" into main am: 922a49f2 am: 87e3ce17

parents dd9ec2ba 87e3ce17
Loading
Loading
Loading
Loading
+44 −0
Original line number Original line Diff line number Diff line
@@ -64,6 +64,13 @@ namespace test {


namespace {
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).
// Invalid value for a patchlevel (which is of form YYYYMMDD).
const uint32_t kInvalidPatchlevel = 99998877;
const uint32_t kInvalidPatchlevel = 99998877;


@@ -2278,6 +2285,43 @@ bool check_feature(const std::string& name) {
    return hasFeature;
    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 test


}  // namespace aidl::android::hardware::security::keymint
}  // namespace aidl::android::hardware::security::keymint
+2 −0
Original line number Original line Diff line number Diff line
@@ -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_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
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.
// RAII class to ensure that a keyblob is deleted regardless of how a test exits.
class KeyBlobDeleter {
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 p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
bool check_feature(const std::string& name);
bool check_feature(const std::string& name);
std::optional<int32_t> keymint_feature_value(bool strongbox);


AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
+85 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@


#include <algorithm>
#include <algorithm>
#include <iostream>
#include <iostream>
#include <map>


#include <openssl/curve25519.h>
#include <openssl/curve25519.h>
#include <openssl/ec.h>
#include <openssl/ec.h>
@@ -8794,6 +8795,90 @@ TEST_P(VsrRequirementTest, Vsr14Test) {


INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest);
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
}  // namespace aidl::android::hardware::security::keymint::test


using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;
using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;