diff --git a/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp index 6bd986c28d..9b74fbba8b 100644 --- a/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp +++ b/security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp @@ -79,9 +79,13 @@ void KeyMintRemoteProv::process() { while (mFdp.remaining_bytes()) { auto invokeProvAPI = mFdp.PickValueInArray>({ - [&]() { verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, - [&]() { verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, - [&]() { isCsrWithProperDiceChain(csr); }, + [&]() { + verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); + }, + [&]() { + verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); + }, + [&]() { isCsrWithProperDiceChain(csr, kServiceName); }, }); invokeProvAPI(); } 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 141f243cde..b56c90aa43 100644 --- a/security/keymint/support/include/remote_prov/remote_prov_utils.h +++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h @@ -89,6 +89,11 @@ inline constexpr uint8_t kCoseEncodedEcdsa256GeekCert[] = { */ bytevec randomBytes(size_t numBytes); +const std::string DEFAULT_INSTANCE_NAME = + "android.hardware.security.keymint.IRemotelyProvisionedComponent/default"; +const std::string RKPVM_INSTANCE_NAME = + "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf"; + struct EekChain { bytevec chain; bytevec last_pubkey; @@ -160,7 +165,8 @@ ErrMsgOr> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector& eekId, int32_t supportedEekCurve, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge); + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge); /** * Verify the protected data as if the device is a final production sample. */ @@ -168,8 +174,8 @@ ErrMsgOr> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector& eekId, int32_t supportedEekCurve, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowAnyMode = false); + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not @@ -177,22 +183,24 @@ ErrMsgOr> verifyProductionProtectedData( */ ErrMsgOr> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowDegenerate = true); + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowDegenerate = true); /** * Verify the CSR as if the device is a final production sample. */ ErrMsgOr> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowAnyMode = false); + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ -ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr); +ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr, + const std::string& instanceName); /** Verify the DICE chain. */ ErrMsgOr> validateBcc(const cppbor::Array* bcc, hwtrust::DiceChain::Kind kind, bool allowAnyMode, - bool allowDegenerate); + bool allowDegenerate, + const std::string& instanceName); } // 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 a6793403c9..497f4789a3 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -52,6 +52,14 @@ using EVP_PKEY_CTX_Ptr = bssl::UniquePtr; using X509_Ptr = bssl::UniquePtr; using CRYPTO_BUFFER_Ptr = bssl::UniquePtr; +std::string device_suffix(const std::string& name) { + size_t pos = name.find('/'); + if (pos == std::string::npos) { + return name; + } + return name.substr(pos + 1); +} + ErrMsgOr ecKeyGetPrivateKey(const EC_KEY* ecKey) { // Extract private key. const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey); @@ -325,7 +333,8 @@ bytevec getProdEekChain(int32_t supportedEekCurve) { ErrMsgOr> validateBcc(const cppbor::Array* bcc, hwtrust::DiceChain::Kind kind, bool allowAnyMode, - bool allowDegenerate) { + bool allowDegenerate, + const std::string& instanceName) { auto encodedBcc = bcc->encode(); // Use ro.build.type instead of ro.debuggable because ro.debuggable=1 for VTS testing @@ -334,7 +343,8 @@ ErrMsgOr> validateBcc(const cppbor::Array* bcc, allowAnyMode = true; } - auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind, allowAnyMode); + auto chain = + hwtrust::DiceChain::Verify(encodedBcc, kind, allowAnyMode, device_suffix(instanceName)); if (!chain.ok()) return chain.error().message(); if (!allowDegenerate && !chain->IsProper()) { @@ -649,8 +659,8 @@ ErrMsgOr> verifyProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector& eekId, int32_t supportedEekCurve, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool isFactory, bool allowAnyMode = false) { + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { return protDataErrMsg; @@ -707,7 +717,7 @@ ErrMsgOr> verifyProtectedData( // BCC is [ pubkey, + BccEntry] auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13, allowAnyMode, - /*allowDegenerate=*/true); + /*allowDegenerate=*/true, instanceName); if (!bccContents) { return bccContents.message() + "\n" + prettyPrint(bcc.get()); } @@ -750,9 +760,10 @@ ErrMsgOr> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector& eekId, int32_t supportedEekCurve, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge) { + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, - eekId, supportedEekCurve, provisionable, challenge, + eekId, supportedEekCurve, provisionable, instanceName, challenge, /*isFactory=*/true); } @@ -760,10 +771,10 @@ ErrMsgOr> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector& eekId, int32_t supportedEekCurve, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowAnyMode) { + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, - eekId, supportedEekCurve, provisionable, challenge, + eekId, supportedEekCurve, provisionable, instanceName, challenge, /*isFactory=*/false, allowAnyMode); } @@ -1003,6 +1014,7 @@ ErrMsgOr getDiceChainKind() { ErrMsgOr parseAndValidateAuthenticatedRequest(const std::vector& request, const std::vector& challenge, + const std::string& instanceName, bool allowAnyMode = false, bool allowDegenerate = true) { auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request); @@ -1042,7 +1054,8 @@ ErrMsgOr parseAndValidateAuthenticatedRequest(const std::vector parseAndValidateAuthenticatedRequest(const std::vector> verifyCsr(const cppbor::Array& keysToSign, const std::vector& csr, IRemotelyProvisionedComponent* provisionable, + const std::string& instanceName, const std::vector& challenge, bool isFactory, bool allowAnyMode = false, bool allowDegenerate = true) { @@ -1081,8 +1095,8 @@ ErrMsgOr> verifyCsr(const cppbor::Array& keysToSi ") does not match expected version (3)."; } - auto csrPayload = - parseAndValidateAuthenticatedRequest(csr, challenge, allowAnyMode, allowDegenerate); + auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge, instanceName, + allowAnyMode, allowDegenerate); if (!csrPayload) { return csrPayload.message(); } @@ -1092,20 +1106,22 @@ ErrMsgOr> verifyCsr(const cppbor::Array& keysToSi ErrMsgOr> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowDegenerate) { - return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true, + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowDegenerate) { + return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/true, /*allowAnyMode=*/false, allowDegenerate); } ErrMsgOr> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool allowAnyMode) { - return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false, allowAnyMode); + IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, + const std::vector& challenge, bool allowAnyMode) { + return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/false, + allowAnyMode); } -ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr) { +ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr, + const std::string& instanceName) { auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr); if (!parsedRequest) { return csrErrMsg; @@ -1136,8 +1152,8 @@ ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr) { } auto encodedDiceChain = diceCertChain->encode(); - auto chain = - hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind, /*allowAnyMode=*/false); + auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind, + /*allowAnyMode=*/false, device_suffix(instanceName)); if (!chain.ok()) return chain.error().message(); return chain->IsProper(); } diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp index 82121cb6a9..8b18b2931d 100644 --- a/security/keymint/support/remote_prov_utils_test.cpp +++ b/security/keymint/support/remote_prov_utils_test.cpp @@ -298,9 +298,11 @@ TEST(RemoteProvUtilsTest, validateBccDegenerate) { ASSERT_TRUE(bcc) << "Error: " << errMsg; EXPECT_TRUE(validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr16, - /*allowAnyMode=*/false, /*allowDegenerate=*/true)); + /*allowAnyMode=*/false, /*allowDegenerate=*/true, + DEFAULT_INSTANCE_NAME)); EXPECT_FALSE(validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr16, - /*allowAnyMode=*/false, /*allowDegenerate=*/false)); + /*allowAnyMode=*/false, /*allowDegenerate=*/false, + DEFAULT_INSTANCE_NAME)); } } // namespace } // 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 f68ff914d5..8f918af6ec 100644 --- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -55,10 +55,7 @@ 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"; @@ -188,7 +185,7 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParamgetHardwareInfo(&rpcHardwareInfo); - isRkpVmInstance_ = GetParam() == RKP_VM_INSTANCE_NAME; + isRkpVmInstance_ = GetParam() == RKPVM_INSTANCE_NAME; if (isRkpVmInstance_) { if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { GTEST_SKIP() << "The RKP VM is not supported on this system."; @@ -227,7 +224,7 @@ TEST(NonParameterizedTests, eachRpcHasAUniqueId) { RpcHardwareInfo hwInfo; auto status = rpc->getHardwareInfo(&hwInfo); - if (hal == RKP_VM_INSTANCE_NAME && status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + if (hal == RKPVM_INSTANCE_NAME && status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { GTEST_SKIP() << "The RKP VM is not supported on this system."; } ASSERT_TRUE(status.isOk()); @@ -268,7 +265,7 @@ TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) { auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr); EXPECT_TRUE(status.isOk()) << status.getDescription(); - auto result = isCsrWithProperDiceChain(csr); + auto result = isCsrWithProperDiceChain(csr, DEFAULT_INSTANCE_NAME); ASSERT_TRUE(result) << result.message(); ASSERT_TRUE(*result); } @@ -494,7 +491,7 @@ TEST_P(CertificateRequestTest, EmptyRequest_testMode) { auto result = verifyProductionProtectedData( deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_, - rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_); + rpcHardwareInfo.supportedEekCurve, provisionable_.get(), GetParam(), challenge_); ASSERT_TRUE(result) << result.message(); } } @@ -517,9 +514,10 @@ TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) { &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto firstBcc = verifyProductionProtectedData( - deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_, - eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_); + auto firstBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), + keysToSignMac, protectedData, testEekChain_, + eekId_, rpcHardwareInfo.supportedEekCurve, + provisionable_.get(), GetParam(), challenge_); ASSERT_TRUE(firstBcc) << firstBcc.message(); status = provisionable_->generateCertificateRequest( @@ -527,9 +525,10 @@ TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) { &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto secondBcc = verifyProductionProtectedData( - deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_, - eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_); + auto secondBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), + keysToSignMac, protectedData, testEekChain_, + eekId_, rpcHardwareInfo.supportedEekCurve, + provisionable_.get(), GetParam(), challenge_); ASSERT_TRUE(secondBcc) << secondBcc.message(); // Verify that none of the keys in the first BCC are repeated in the second one. @@ -579,7 +578,7 @@ TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) { auto result = verifyProductionProtectedData( deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_, - rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_); + rpcHardwareInfo.supportedEekCurve, provisionable_.get(), GetParam(), challenge_); ASSERT_TRUE(result) << result.message(); } } @@ -767,8 +766,8 @@ TEST_P(CertificateRequestV2Test, EmptyRequest) { provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge, - isRkpVmInstance_); + auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), GetParam(), + challenge, isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); } } @@ -789,8 +788,8 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequest) { auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge, - isRkpVmInstance_); + auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(), + challenge, isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); } } @@ -820,15 +819,15 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) { auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_, - isRkpVmInstance_); + auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(), + challenge_, isRkpVmInstance_); ASSERT_TRUE(firstCsr) << firstCsr.message(); status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_, - isRkpVmInstance_); + auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(), + challenge_, isRkpVmInstance_); ASSERT_TRUE(secondCsr) << secondCsr.message(); ASSERT_EQ(**firstCsr, **secondCsr); @@ -846,8 +845,8 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) { auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr); ASSERT_TRUE(status.isOk()) << status.getDescription(); - auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_, - isRkpVmInstance_); + auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), GetParam(), + challenge_, isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); } @@ -977,7 +976,8 @@ TEST_P(CertificateRequestV2Test, DeviceInfo) { provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr); ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription(); - auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_); + auto result = + verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), GetParam(), challenge_); ASSERT_TRUE(result) << result.message(); std::unique_ptr csrPayload = std::move(*result);