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
This commit is contained in:
Karuna Wadhera
2024-07-18 14:08:36 +00:00
parent a7fffef352
commit ca6d8cce51
3 changed files with 41 additions and 21 deletions

View File

@@ -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
@@ -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);

View File

@@ -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();
@@ -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;
@@ -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());
}
@@ -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) {
@@ -987,7 +995,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;
@@ -1025,7 +1034,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);
}
@@ -1054,7 +1063,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) {
@@ -1062,7 +1071,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();
}
@@ -1078,8 +1087,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) {
@@ -1113,7 +1123,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();
}

View File

@@ -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.";
}
@@ -209,6 +210,7 @@ class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::
protected:
std::shared_ptr<IRemotelyProvisionedComponent> 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();
}