Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69a76131 authored by Karuna Wadhera's avatar Karuna Wadhera Committed by Gerrit Code Review
Browse files

Merge "Pass in allow_any_mode when verifying DICE chains" into main

parents 65355ad8 ca6d8cce
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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);
+24 −13
Original line number Diff line number Diff line
@@ -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) {
@@ -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;
@@ -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);
    }
@@ -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) {
@@ -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();
    }
@@ -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) {
@@ -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();
}
+13 −6
Original line number Diff line number Diff line
@@ -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();
}