Merge "KeyMint: Fix device-unique attestation chain specification" am: 9c3bd29cab am: e52c1bb007 am: 7050121408 am: 5b9dbab850
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1757172
Change-Id: Ibe6a5b158c2f680e546ed708deae983b7e828546
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index ec5f3d3..b28ebcb 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -827,11 +827,22 @@
/**
* DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import
* operations. It indicates that attestation using a device-unique key is requested, rather
- * than a batch key. When a device-unique key is used, the returned chain should contain two
- * certificates:
+ * than a batch key. When a device-unique key is used, the returned chain should contain two or
+ * three certificates.
+ *
+ * In case the chain contains two certificates, they should be:
* * The attestation certificate, containing the attestation extension, as described in
- KeyCreationResult.aidl.
+ * KeyCreationResult.aidl.
* * A self-signed root certificate, signed by the device-unique key.
+ *
+ * In case the chain contains three certificates, they should be:
+ * * The attestation certificate, containing the attestation extension, as described in
+ * KeyCreationResult.aidl, signed by the device-unique key.
+ * * An intermediate certificate, containing the public portion of the device-unique key.
+ * * A self-signed root certificate, signed by a dedicated key, certifying the
+ * intermediate. Ideally, the dedicated key would be the same for all StrongBox
+ * instances of the same manufacturer to ease validation.
+ *
* No additional chained certificates are provided. Only SecurityLevel::STRONGBOX
* IKeyMintDevices may support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT
* IKeyMintDevices must return ErrorCode::INVALID_ARGUMENT if they receive
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index a3ed3ad..d7abf07 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -40,11 +40,16 @@
AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
- // The device-unique attestation chain should contain exactly two certificates:
+ // The device-unique attestation chain should contain exactly three certificates:
// * The leaf with the attestation extension.
- // * A self-signed root, signed using the device-unique key.
- ASSERT_EQ(cert_chain_.size(), 2);
- EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+ // * An intermediate, signing the leaf using the device-unique key.
+ // * A self-signed root, signed using some authority's key, certifying
+ // the device-unique key.
+ const size_t chain_length = cert_chain_.size();
+ ASSERT_TRUE(chain_length == 2 || chain_length == 3);
+ // TODO(b/191361618): Once StrongBox implementations use a correctly-issued
+ // certificate chain, do not skip issuers matching.
+ EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false));
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 5359b3b..2032411 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1493,7 +1493,8 @@
return authList;
}
-AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain) {
+AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
+ bool strict_issuer_check) {
std::stringstream cert_data;
for (size_t i = 0; i < chain.size(); ++i) {
@@ -1520,7 +1521,7 @@
string cert_issuer = x509NameToStr(X509_get_issuer_name(key_cert.get()));
string signer_subj = x509NameToStr(X509_get_subject_name(signing_cert.get()));
- if (cert_issuer != signer_subj) {
+ if (cert_issuer != signer_subj && strict_issuer_check) {
return AssertionFailure() << "Cert " << i << " has wrong issuer.\n"
<< " Signer subject is " << signer_subj
<< " Issuer subject is " << cert_issuer << endl
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index d592d36..ec3fcf6 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -349,7 +349,8 @@
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
-::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain);
+::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
+ bool strict_issuer_check = true);
#define INSTANTIATE_KEYMINT_AIDL_TEST(name) \
INSTANTIATE_TEST_SUITE_P(PerInstance, name, \