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

Commit f50a2e1c authored by Andrew Scull's avatar Andrew Scull Committed by Automerger Merge Worker
Browse files

Merge "Require proper DICE if StrongBox is present" into main am: 6cb40f35 am: ce5c85e2

parents b6553785 ce5c85e2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -183,4 +183,7 @@ 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);

/** Checks whether the CSR has a proper DICE chain. */
ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr);

}  // namespace aidl::android::hardware::security::keymint::remote_prov
+36 −0
Original line number Diff line number Diff line
@@ -1081,4 +1081,40 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
    return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
}

ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) {
    auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr);
    if (!parsedRequest) {
        return csrErrMsg;
    }
    if (!parsedRequest->asArray()) {
        return "AuthenticatedRequest is not a CBOR array.";
    }
    if (parsedRequest->asArray()->size() != 4U) {
        return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
               "signed data. However, the parsed AuthenticatedRequest has " +
               std::to_string(parsedRequest->asArray()->size()) + " entries.";
    }

    auto version = parsedRequest->asArray()->get(0)->asUint();
    auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();

    if (!version || version->value() != 1U) {
        return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
    }
    if (!diceCertChain) {
        return "AuthenticatedRequest DiceCertChain must be an Array.";
    }

    // DICE chain is [ pubkey, + DiceChainEntry ].
    auto diceChainKind = getDiceChainKind();
    if (!diceChainKind) {
        return diceChainKind.message();
    }

    auto encodedDiceChain = diceCertChain->encode();
    auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind);
    if (!chain.ok()) return chain.error().message();
    return chain->IsProper();
}

}  // namespace aidl::android::hardware::security::keymint::remote_prov
+35 −0
Original line number Diff line number Diff line
@@ -55,8 +55,12 @@ constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;

constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
const string DEFAULT_INSTANCE_NAME =
        "android.hardware.security.keymint.IRemotelyProvisionedComponent/default";
const string RKP_VM_INSTANCE_NAME =
        "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
const string KEYMINT_STRONGBOX_INSTANCE_NAME =
        "android.hardware.security.keymint.IKeyMintDevice/strongbox";

#define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
@@ -230,6 +234,37 @@ TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
    }
}

/**
 * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance
 * on the device.
 */
// @VsrTest = 3.10-015
TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) {
    int vsr_api_level = get_vsr_api_level();
    if (vsr_api_level < 35) {
        GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: "
                     << vsr_api_level;
    }

    if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
        GTEST_SKIP() << "Strongbox is not present on this device.";
    }

    ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str()));
    std::shared_ptr<IRemotelyProvisionedComponent> rpc =
            IRemotelyProvisionedComponent::fromBinder(binder);
    ASSERT_NE(rpc, nullptr);

    bytevec challenge = randomBytes(64);
    bytevec csr;
    auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
    EXPECT_TRUE(status.isOk()) << status.getDescription();

    auto result = isCsrWithProperDiceChain(csr);
    ASSERT_TRUE(result) << result.message();
    ASSERT_TRUE(*result);
}

using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;

INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);