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 1d7db6ae70..b7c32ca3bc 100644 --- a/security/keymint/support/include/remote_prov/remote_prov_utils.h +++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h @@ -167,7 +167,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); + IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, + bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not @@ -181,7 +182,8 @@ ErrMsgOr> verifyFactoryCsr( */ ErrMsgOr> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge); + IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, + bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr); diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index 6638775509..761ae4b06f 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -325,9 +325,16 @@ bytevec getProdEekChain(int32_t supportedEekCurve) { } ErrMsgOr> validateBcc(const cppbor::Array* bcc, - hwtrust::DiceChain::Kind kind) { + hwtrust::DiceChain::Kind kind, bool allowAnyMode) { auto encodedBcc = bcc->encode(); - auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind); + + // Use ro.build.type instead of ro.debuggable because ro.debuggable=1 for VTS testing + std::string build_type = ::android::base::GetProperty("ro.build.type", ""); + if (!build_type.empty() && build_type != "user") { + allowAnyMode = true; + } + + auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind, allowAnyMode); if (!chain.ok()) return chain.error().message(); auto keys = chain->CosePublicKeys(); if (!keys.ok()) return keys.error().message(); @@ -638,7 +645,7 @@ ErrMsgOr> verifyProtectedData( 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 isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { return protDataErrMsg; @@ -694,7 +701,7 @@ ErrMsgOr> verifyProtectedData( } // BCC is [ pubkey, + BccEntry] - auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13); + auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13, allowAnyMode); if (!bccContents) { return bccContents.message() + "\n" + prettyPrint(bcc.get()); } @@ -747,10 +754,11 @@ 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) { + IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, + bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, challenge, - /*isFactory=*/false); + /*isFactory=*/false, allowAnyMode); } ErrMsgOr parseX509Cert(const std::vector& cert) { @@ -987,7 +995,8 @@ ErrMsgOr getDiceChainKind() { } ErrMsgOr parseAndValidateAuthenticatedRequest(const std::vector& request, - const std::vector& challenge) { + const std::vector& challenge, + bool allowAnyMode = false) { auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request); if (!parsedRequest) { return csrErrMsg; @@ -1025,7 +1034,7 @@ ErrMsgOr parseAndValidateAuthenticatedRequest(const std::vector> verifyCsr(const cppbor::Array& keysToSi const std::vector& csr, IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, - bool isFactory) { + bool isFactory, bool allowAnyMode = false) { RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber != 3) { @@ -1062,7 +1071,7 @@ ErrMsgOr> verifyCsr(const cppbor::Array& keysToSi ") does not match expected version (3)."; } - auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge); + auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge, allowAnyMode); if (!csrPayload) { return csrPayload.message(); } @@ -1078,8 +1087,9 @@ ErrMsgOr> verifyFactoryCsr( ErrMsgOr> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector& csr, - IRemotelyProvisionedComponent* provisionable, const std::vector& challenge) { - return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false); + IRemotelyProvisionedComponent* provisionable, const std::vector& challenge, + bool allowAnyMode) { + return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false, allowAnyMode); } ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr) { @@ -1113,7 +1123,8 @@ ErrMsgOr isCsrWithProperDiceChain(const std::vector& csr) { } auto encodedDiceChain = diceCertChain->encode(); - auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind); + auto chain = + hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind, /*allowAnyMode=*/false); if (!chain.ok()) return chain.error().message(); return chain->IsProper(); } diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index 2dbc73f8e3..f68ff914d5 100644 --- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -188,7 +188,8 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParamgetHardwareInfo(&rpcHardwareInfo); - if (GetParam() == RKP_VM_INSTANCE_NAME) { + isRkpVmInstance_ = GetParam() == RKP_VM_INSTANCE_NAME; + if (isRkpVmInstance_) { if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { GTEST_SKIP() << "The RKP VM is not supported on this system."; } @@ -209,6 +210,7 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam provisionable_; RpcHardwareInfo rpcHardwareInfo; + bool isRkpVmInstance_; }; /** @@ -765,7 +767,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); + auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge, + isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); } } @@ -786,7 +789,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); + auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge, + isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); } } @@ -816,13 +820,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_); + auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), 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_); + auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_, + isRkpVmInstance_); ASSERT_TRUE(secondCsr) << secondCsr.message(); ASSERT_EQ(**firstCsr, **secondCsr); @@ -840,7 +846,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_); + auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_, + isRkpVmInstance_); ASSERT_TRUE(result) << result.message(); }