Loading security/keymint/support/include/remote_prov/remote_prov_utils.h +4 −2 Original line number Diff line number Diff line Loading @@ -167,7 +167,8 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not Loading @@ -181,7 +182,8 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr); Loading security/keymint/support/remote_prov_utils.cpp +24 −13 Original line number Diff line number Diff line Loading @@ -325,9 +325,16 @@ bytevec getProdEekChain(int32_t supportedEekCurve) { } ErrMsgOr<std::vector<BccEntryData>> 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(); Loading Loading @@ -638,7 +645,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool isFactory) { bool isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { return protDataErrMsg; Loading Loading @@ -694,7 +701,7 @@ ErrMsgOr<std::vector<BccEntryData>> 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()); } Loading Loading @@ -747,10 +754,11 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) { IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, challenge, /*isFactory=*/false); /*isFactory=*/false, allowAnyMode); } ErrMsgOr<X509_Ptr> parseX509Cert(const std::vector<uint8_t>& cert) { Loading Loading @@ -988,7 +996,8 @@ ErrMsgOr<hwtrust::DiceChain::Kind> getDiceChainKind() { } ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request, const std::vector<uint8_t>& challenge) { const std::vector<uint8_t>& challenge, bool allowAnyMode = false) { auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request); if (!parsedRequest) { return csrErrMsg; Loading Loading @@ -1026,7 +1035,7 @@ ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t return diceChainKind.message(); } auto diceContents = validateBcc(diceCertChain, *diceChainKind); auto diceContents = validateBcc(diceCertChain, *diceChainKind, allowAnyMode); if (!diceContents) { return diceContents.message() + "\n" + prettyPrint(diceCertChain); } Loading Loading @@ -1055,7 +1064,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(const cppbor::Array& keysToSi const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool isFactory) { bool isFactory, bool allowAnyMode = false) { RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber != 3) { Loading @@ -1063,7 +1072,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> 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(); } Loading @@ -1079,8 +1088,9 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) { return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false, allowAnyMode); } ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) { Loading Loading @@ -1114,7 +1124,8 @@ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& 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(); } Loading security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +13 −6 Original line number Diff line number Diff line Loading @@ -188,7 +188,8 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std:: } ASSERT_NE(provisionable_, nullptr); auto status = provisionable_->getHardwareInfo(&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."; } Loading @@ -209,6 +210,7 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std:: protected: std::shared_ptr<IRemotelyProvisionedComponent> provisionable_; RpcHardwareInfo rpcHardwareInfo; bool isRkpVmInstance_; }; /** Loading Loading @@ -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(); } } Loading @@ -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(); } } Loading Loading @@ -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); Loading @@ -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(); } Loading Loading
security/keymint/support/include/remote_prov/remote_prov_utils.h +4 −2 Original line number Diff line number Diff line Loading @@ -167,7 +167,8 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not Loading @@ -181,7 +182,8 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr); Loading
security/keymint/support/remote_prov_utils.cpp +24 −13 Original line number Diff line number Diff line Loading @@ -325,9 +325,16 @@ bytevec getProdEekChain(int32_t supportedEekCurve) { } ErrMsgOr<std::vector<BccEntryData>> 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(); Loading Loading @@ -638,7 +645,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool isFactory) { bool isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { return protDataErrMsg; Loading Loading @@ -694,7 +701,7 @@ ErrMsgOr<std::vector<BccEntryData>> 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()); } Loading Loading @@ -747,10 +754,11 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) { IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, challenge, /*isFactory=*/false); /*isFactory=*/false, allowAnyMode); } ErrMsgOr<X509_Ptr> parseX509Cert(const std::vector<uint8_t>& cert) { Loading Loading @@ -988,7 +996,8 @@ ErrMsgOr<hwtrust::DiceChain::Kind> getDiceChainKind() { } ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request, const std::vector<uint8_t>& challenge) { const std::vector<uint8_t>& challenge, bool allowAnyMode = false) { auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request); if (!parsedRequest) { return csrErrMsg; Loading Loading @@ -1026,7 +1035,7 @@ ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t return diceChainKind.message(); } auto diceContents = validateBcc(diceCertChain, *diceChainKind); auto diceContents = validateBcc(diceCertChain, *diceChainKind, allowAnyMode); if (!diceContents) { return diceContents.message() + "\n" + prettyPrint(diceCertChain); } Loading Loading @@ -1055,7 +1064,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(const cppbor::Array& keysToSi const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool isFactory) { bool isFactory, bool allowAnyMode = false) { RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber != 3) { Loading @@ -1063,7 +1072,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> 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(); } Loading @@ -1079,8 +1088,9 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) { return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false); IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false, allowAnyMode); } ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) { Loading Loading @@ -1114,7 +1124,8 @@ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& 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(); } Loading
security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +13 −6 Original line number Diff line number Diff line Loading @@ -188,7 +188,8 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std:: } ASSERT_NE(provisionable_, nullptr); auto status = provisionable_->getHardwareInfo(&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."; } Loading @@ -209,6 +210,7 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std:: protected: std::shared_ptr<IRemotelyProvisionedComponent> provisionable_; RpcHardwareInfo rpcHardwareInfo; bool isRkpVmInstance_; }; /** Loading Loading @@ -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(); } } Loading @@ -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(); } } Loading Loading @@ -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); Loading @@ -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(); } Loading