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
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 516be3b..57bc27a 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -239,6 +239,30 @@
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 @@
ASSERT_TRUE(status.isOk());
vector<uint8_t> coseKeyData;
check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
+}
+
+/**
+ * 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");
- // 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);
- KeyMintHardwareInfo info;
- ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
-
// Generate an ECDSA key that is attested by the generated P256 keypair.
AuthorizationSet keyDesc = AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)