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

Commit 4d3c298c authored by David Drysdale's avatar David Drysdale
Browse files

Use a heuristic to correlate devices

Every KeyMint device should have a corresponding
IRemotelyProvisionedComponent instance, but the converse is not true.

So given an IRPC instance under test, look for a corresponding KeyMint
device by comparing suffixes, but just skip the test if not found.

Test: VtsHalRemotelyProvisionedComponentTargetTest
Change-Id: I390aa7025eb77f75a3280e8d85dc453b784c23ee
parent f6fc5a63
Loading
Loading
Loading
Loading
+48 −11
Original line number Diff line number Diff line
@@ -239,6 +239,30 @@ ErrMsgOr<EekChain> corrupt_sig_chain(const EekChain& eek, int which) {
    return EekChain{corruptChain.encode(), eek.last_pubkey, eek.last_privkey};
}

string device_suffix(const string& name) {
    size_t pos = name.find('/');
    if (pos == string::npos) {
        return name;
    }
    return name.substr(pos + 1);
}

bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
    string rp_suffix = device_suffix(rp_name);

    vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
    for (const string& km_name : km_names) {
        // If the suffix of the KeyMint instance equals the suffix of the
        // RemotelyProvisionedComponent instance, assume they match.
        if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
            ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
            *keyMint = IKeyMintDevice::fromBinder(binder);
            return true;
        }
    }
    return false;
}

}  // namespace

class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
@@ -276,21 +300,34 @@ TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
    ASSERT_TRUE(status.isOk());
    vector<uint8_t> coseKeyData;
    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
    AttestationKey attestKey;
    attestKey.keyBlob = std::move(privateKeyBlob);
    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
}

    // Also talk to an IKeyMintDevice.
    // TODO: if there were multiple instances of IRemotelyProvisionedComponent and IKeyMintDevice,
    // what should the correlation between them be?
    vector<string> params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
    ASSERT_GT(params.size(), 0U);
    ASSERT_TRUE(AServiceManager_isDeclared(params[0].c_str()));
    ::ndk::SpAIBinder binder(AServiceManager_waitForService(params[0].c_str()));
    std::shared_ptr<IKeyMintDevice> keyMint = IKeyMintDevice::fromBinder(binder);
/**
 * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
 */
TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
    std::shared_ptr<IKeyMintDevice> keyMint;
    if (!matching_keymint_device(GetParam(), &keyMint)) {
        // No matching IKeyMintDevice.
        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
        return;
    }
    KeyMintHardwareInfo info;
    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());

    MacedPublicKey macedPubKey;
    bytevec privateKeyBlob;
    bool testMode = false;
    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
    ASSERT_TRUE(status.isOk());
    vector<uint8_t> coseKeyData;
    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);

    AttestationKey attestKey;
    attestKey.keyBlob = std::move(privateKeyBlob);
    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");

    // Generate an ECDSA key that is attested by the generated P256 keypair.
    AuthorizationSet keyDesc = AuthorizationSetBuilder()
                                       .Authorization(TAG_NO_AUTH_REQUIRED)