From ca6d8cce512562ce6efbf4d5d0e92f1d302c390b Mon Sep 17 00:00:00 2001 From: Karuna Wadhera Date: Thu, 18 Jul 2024 14:08:36 +0000 Subject: [PATCH] Pass in allow_any_mode when verifying DICE chains 1. allow_any_mode is set as true when the VM RKP instance is being tested (since the bootloader is unlocked for VTS tests and therefore the VM DICE chain will necessarily have at least one non-normal mode.) 2. allow_any_mode is set as true for non-user type builds. Bug: 318483637 Test: atest VtsHalRemotelyProvisionedComponentTargetTest Change-Id: I15ec3ad32f08eecd8478df14f8efa71fdb0b5d08 --- .../include/remote_prov/remote_prov_utils.h | 6 ++- .../keymint/support/remote_prov_utils.cpp | 37 ++++++++++++------- .../VtsRemotelyProvisionedComponentTests.cpp | 19 +++++++--- 3 files changed, 41 insertions(+), 21 deletions(-) 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(); }