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

Commit 6cb40f35 authored by Andrew Scull's avatar Andrew Scull Committed by Gerrit Code Review
Browse files

Merge "Require proper DICE if StrongBox is present" into main

parents 83b2267b 2146152d
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);