diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl index 06bce19c82..5ff45f8a94 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl @@ -38,6 +38,7 @@ parcelable RpcHardwareInfo { int versionNumber; @utf8InCpp String rpcAuthorName; int supportedEekCurve = 0; + @nullable @utf8InCpp String uniqueId; const int CURVE_NONE = 0; const int CURVE_P256 = 1; const int CURVE_25519 = 2; diff --git a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl index d297f871fb..3a4c233cf5 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl @@ -53,4 +53,21 @@ parcelable RpcHardwareInfo { * a passing implementation does not provide CURVE_NONE. */ int supportedEekCurve = CURVE_NONE; + + /** + * uniqueId is an opaque identifier for this IRemotelyProvisionedComponent implementation. The + * client should NOT interpret the content of the identifier in any way. The client can only + * compare identifiers to determine if two IRemotelyProvisionedComponents share the same + * implementation. Each IRemotelyProvisionedComponent implementation must have a distinct + * identifier from all other implementations on the same device. + * + * This identifier must be consistent across reboots, as it is used to store and track + * provisioned keys in a persistent, on-device database. + * + * uniqueId may not be empty, and must not be any longer than 32 characters. + * + * This field was added in API version 2. + * + */ + @nullable @utf8InCpp String uniqueId; } diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index c9d506f788..829780d442 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include "KeyMintAidlTestBase.h" @@ -40,6 +42,8 @@ using ::std::vector; namespace { +constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2; + #define INSTANTIATE_REM_PROV_AIDL_TEST(name) \ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \ INSTANTIATE_TEST_SUITE_P( \ @@ -47,6 +51,7 @@ namespace { testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \ ::android::PrintInstanceNameToString) +using ::android::sp; using bytevec = std::vector; using testing::MatchesRegex; using namespace remote_prov; @@ -175,6 +180,67 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam provisionable_; }; +/** + * Verify that every implementation reports a different unique id. + */ +TEST(NonParameterizedTests, eachRpcHasAUniqueId) { + std::set uniqueIds; + for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) { + ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str())); + ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str())); + std::shared_ptr rpc = + IRemotelyProvisionedComponent::fromBinder(binder); + ASSERT_NE(rpc, nullptr); + + RpcHardwareInfo hwInfo; + ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk()); + + int32_t version; + ASSERT_TRUE(rpc->getInterfaceVersion(&version).isOk()); + if (version >= VERSION_WITH_UNIQUE_ID_SUPPORT) { + ASSERT_TRUE(hwInfo.uniqueId); + auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId); + EXPECT_TRUE(wasInserted); + } else { + ASSERT_FALSE(hwInfo.uniqueId); + } + } +} + +using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests; + +INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests); + +/** + * Verify that a valid curve is reported by the implementation. + */ +TEST_P(GetHardwareInfoTests, supportsValidCurve) { + RpcHardwareInfo hwInfo; + ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk()); + + const std::set validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519}; + ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1) + << "Invalid curve: " << hwInfo.supportedEekCurve; +} + +/** + * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl. + */ +TEST_P(GetHardwareInfoTests, uniqueId) { + int32_t version; + ASSERT_TRUE(provisionable_->getInterfaceVersion(&version).isOk()); + + if (version < VERSION_WITH_UNIQUE_ID_SUPPORT) { + return; + } + + RpcHardwareInfo hwInfo; + ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk()); + ASSERT_TRUE(hwInfo.uniqueId); + EXPECT_GE(hwInfo.uniqueId->size(), 1); + EXPECT_LE(hwInfo.uniqueId->size(), 32); +} + using GenerateKeyTests = VtsRemotelyProvisionedComponentTests; INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);