Require proper DICE if StrongBox is present
If a decice provides a StrongBox KeyMint instance then the default IRPC instance is required to use a proper, non-degenerate DICE chain. Expose a function to check whether the CSR contains a proper DICE chain and use that from VTS to implement the test. Bug: 302204396 Test: atest VtsHalRemotelyProvisionedComponentTargetTest Change-Id: I90cf070bc2279fc52e0a8e7fd0039d3fdb68c1d7
This commit is contained in:
parent
b959192690
commit
2146152db9
3 changed files with 74 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue