diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h index b8c69eb7d6..1d7db6ae70 100644 --- a/security/keymint/support/include/remote_prov/remote_prov_utils.h +++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h @@ -183,4 +183,7 @@ ErrMsgOr> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector& csr, IRemotelyProvisionedComponent* provisionable, const std::vector& challenge); +/** Checks whether the CSR has a proper DICE chain. */ +ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr); + } // namespace aidl::android::hardware::security::keymint::remote_prov diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index a830041d64..b74fd59712 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -1081,4 +1081,40 @@ ErrMsgOr> verifyProductionCsr( return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false); } +ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr) { + auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr); + if (!parsedRequest) { + return csrErrMsg; + } + if (!parsedRequest->asArray()) { + return "AuthenticatedRequest is not a CBOR array."; + } + if (parsedRequest->asArray()->size() != 4U) { + return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and " + "signed data. However, the parsed AuthenticatedRequest has " + + std::to_string(parsedRequest->asArray()->size()) + " entries."; + } + + auto version = parsedRequest->asArray()->get(0)->asUint(); + auto diceCertChain = parsedRequest->asArray()->get(2)->asArray(); + + if (!version || version->value() != 1U) { + return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1."; + } + if (!diceCertChain) { + return "AuthenticatedRequest DiceCertChain must be an Array."; + } + + // DICE chain is [ pubkey, + DiceChainEntry ]. + auto diceChainKind = getDiceChainKind(); + if (!diceChainKind) { + return diceChainKind.message(); + } + + auto encodedDiceChain = diceCertChain->encode(); + auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind); + if (!chain.ok()) return chain.error().message(); + return chain->IsProper(); +} + } // namespace aidl::android::hardware::security::keymint::remote_prov diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index 68b966cda9..2a8fd96611 100644 --- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -55,8 +55,12 @@ constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3; constexpr uint8_t MIN_CHALLENGE_SIZE = 0; constexpr uint8_t MAX_CHALLENGE_SIZE = 64; +const string DEFAULT_INSTANCE_NAME = + "android.hardware.security.keymint.IRemotelyProvisionedComponent/default"; const string RKP_VM_INSTANCE_NAME = "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf"; +const string KEYMINT_STRONGBOX_INSTANCE_NAME = + "android.hardware.security.keymint.IKeyMintDevice/strongbox"; #define INSTANTIATE_REM_PROV_AIDL_TEST(name) \ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \ @@ -230,6 +234,37 @@ TEST(NonParameterizedTests, eachRpcHasAUniqueId) { } } +/** + * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance + * on the device. + */ +// @VsrTest = 3.10-015 +TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) { + int vsr_api_level = get_vsr_api_level(); + if (vsr_api_level < 35) { + GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: " + << vsr_api_level; + } + + if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) { + GTEST_SKIP() << "Strongbox is not present on this device."; + } + + ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str())); + std::shared_ptr rpc = + IRemotelyProvisionedComponent::fromBinder(binder); + ASSERT_NE(rpc, nullptr); + + bytevec challenge = randomBytes(64); + bytevec csr; + auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr); + EXPECT_TRUE(status.isOk()) << status.getDescription(); + + auto result = isCsrWithProperDiceChain(csr); + ASSERT_TRUE(result) << result.message(); + ASSERT_TRUE(*result); +} + using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests; INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);