/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "keymint_1_attest_key_test" #include #include #include #include #include "KeyMintAidlTestBase.h" namespace aidl::android::hardware::security::keymint::test { namespace { bool IsSelfSigned(const vector& chain) { if (chain.size() != 1) return false; return ChainSignaturesAreValid(chain); } } // namespace class AttestKeyTest : public KeyMintAidlTestBase { public: void SetUp() override { check_skip_test(); KeyMintAidlTestBase::SetUp(); } protected: const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc, const optional& attest_key, vector* key_blob, vector* key_characteristics, vector* cert_chain) { // The original specification for KeyMint v1 required ATTEST_KEY not be combined // with any other key purpose, but the original VTS tests incorrectly did exactly that. // This means that a device that launched prior to Android T (API level 33) may // accept or even require KeyPurpose::SIGN too. if (property_get_int32("ro.board.first_api_level", 0) < 33) { AuthorizationSet key_desc_plus_sign = key_desc; key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN); auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics, cert_chain); if (result == ErrorCode::OK) { return result; } // If the key generation failed, it may be because the device is (correctly) // rejecting the combination of ATTEST_KEY+SIGN. Fall through to try again with // just ATTEST_KEY. } return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain); } // Check if ATTEST_KEY feature is disabled bool is_attest_key_feature_disabled(void) const { if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) { GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled"; return true; } return false; } // Check if StrongBox KeyStore is enabled bool is_strongbox_enabled(void) const { if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) { GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled"; return true; } return false; } // Check if chipset has received a waiver allowing it to be launched with // Android S (or later) with Keymaster 4.0 in StrongBox bool is_chipset_allowed_km4_strongbox(void) const { std::array buffer; auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr); if (res <= 0) return false; const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"}; for (const string model : allowed_soc_models) { if (model.compare(buffer.data()) == 0) { GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0"; return true; } } return false; } // Skip the test if all the following conditions hold: // 1. ATTEST_KEY feature is disabled // 2. STRONGBOX is enabled // 3. The device is running one of the chipsets that have received a waiver // allowing it to be launched with Android S (or later) with Keymaster 4.0 // in StrongBox void check_skip_test(void) const { if (is_attest_key_feature_disabled() && is_strongbox_enabled() && is_chipset_allowed_km4_strongbox()) { GTEST_SKIP() << "Test is not applicable"; } } }; /* * AttestKeyTest.AllRsaSizes * * This test creates self signed RSA attestation keys of various sizes, and verify they can be * used to sign other RSA and EC keys. */ TEST_P(AttestKeyTest, AllRsaSizes) { for (auto size : ValidKeySizes(Algorithm::RSA)) { /* * Create attestation key. */ AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::OK, GenerateAttestKey(AuthorizationSetBuilder() .RsaKey(size, 65537) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); ASSERT_GT(attest_key_cert_chain.size(), 0); EXPECT_EQ(attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size; /* * Use attestation key to sign RSA signing key */ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); CheckedDeleteKey(&attested_key_blob); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. attested_key_cert_chain.push_back(attest_key_cert_chain[0]); EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); EXPECT_EQ(attested_key_cert_chain.size(), 2); /* * Use attestation key to sign RSA decryption key */ attested_key_characteristics.resize(0); attested_key_cert_chain.resize(0); EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .RsaEncryptionKey(2048, 65537) .Digest(Digest::NONE) .Padding(PaddingMode::NONE) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo2") .AttestationApplicationId("bar2") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); CheckedDeleteKey(&attested_key_blob); hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo2", "bar2", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. attested_key_cert_chain.push_back(attest_key_cert_chain[0]); EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); EXPECT_EQ(attested_key_cert_chain.size(), 2); /* * Use attestation key to sign EC key. Specify a CREATION_DATETIME for this one. */ attested_key_characteristics.resize(0); attested_key_cert_chain.resize(0); uint64_t timestamp = 1619621648000; EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_CREATION_DATETIME, timestamp) .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); // The returned key characteristics will include CREATION_DATETIME (checked below) // in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics() // call below, to match what getKeyCharacteristics() returns (which doesn't include // any SecurityLevel::KEYSTORE characteristics). CheckCharacteristics(attested_key_blob, attested_key_characteristics); CheckedDeleteKey(&attested_key_blob); CheckedDeleteKey(&attest_key.keyBlob); hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); // The client-specified CREATION_DATETIME should be in sw_enforced. // Its presence will also trigger verify_attestation_record() to check that // it is in the attestation extension with a matching value. EXPECT_TRUE(sw_enforced.Contains(TAG_CREATION_DATETIME, timestamp)) << "expected CREATION_TIMESTAMP in sw_enforced:" << sw_enforced << " not in hw_enforced:" << hw_enforced; EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. attested_key_cert_chain.push_back(attest_key_cert_chain[0]); EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); // Bail early if anything failed. if (HasFailure()) return; } } /* * AttestKeyTest.RsaAttestKeyMultiPurposeFail * * This test attempts to create an RSA attestation key that also allows signing. */ TEST_P(AttestKeyTest, RsaAttestKeyMultiPurposeFail) { if (AidlVersion() < 2) { // The KeyMint v1 spec required that KeyPurpose::ATTEST_KEY not be combined // with other key purposes. However, this was not checked at the time // so we can only be strict about checking this for implementations of KeyMint // version 2 and above. GTEST_SKIP() << "Single-purpose for KeyPurpose::ATTEST_KEY only strict since KeyMint v2"; } vector attest_key_blob; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key_blob, &attest_key_characteristics, &attest_key_cert_chain)); } /* * AttestKeyTest.RsaAttestedAttestKeys * * This test creates an RSA attestation key signed by factory keys, and varifies it can be * used to sign other RSA and EC keys. */ TEST_P(AttestKeyTest, RsaAttestedAttestKeys) { auto challenge = "hello"; auto app_id = "foo"; auto subject = "cert subj 2"; vector subject_der(make_name_from_str(subject)); // An X.509 certificate serial number SHOULD be >0, but this is not policed. Check // that a zero value doesn't cause problems. uint64_t serial_int = 0; vector serial_blob(build_serial_blob(serial_int)); /* * Create attestation key. */ AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; auto result = GenerateAttestKey(AuthorizationSetBuilder() .RsaKey(2048, 65537) .AttestKey() .AttestationChallenge(challenge) .AttestationApplicationId(app_id) .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain); // Strongbox may not support factory provisioned attestation key. if (SecLevel() == SecurityLevel::STRONGBOX) { if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return; } ASSERT_EQ(ErrorCode::OK, result); EXPECT_GT(attest_key_cert_chain.size(), 1); verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false); EXPECT_TRUE(ChainSignaturesAreValid(attest_key_cert_chain)); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attest_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attest_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, // sw_enforced, hw_enforced, SecLevel(), attest_key_cert_chain[0].encodedCertificate)); /* * Use attestation key to sign RSA key */ attest_key.issuerSubjectName = subject_der; vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; auto subject2 = "cert subject"; vector subject_der2(make_name_from_str(subject2)); uint64_t serial_int2 = 255; vector serial_blob2(build_serial_blob(serial_int2)); EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob2) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der2) .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); CheckedDeleteKey(&attested_key_blob); CheckedDeleteKey(&attest_key.keyBlob); AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced2, hw_enforced2, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. attested_key_cert_chain.insert(attested_key_cert_chain.end(), attest_key_cert_chain.begin(), attest_key_cert_chain.end()); EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); EXPECT_GT(attested_key_cert_chain.size(), 2); verify_subject_and_serial(attested_key_cert_chain[0], serial_int2, subject2, false); } /* * AttestKeyTest.RsaAttestKeyChaining * * This test creates a chain of multiple RSA attest keys, each used to sign the next attest key, * with the last attest key signed by the factory chain. */ TEST_P(AttestKeyTest, RsaAttestKeyChaining) { const int chain_size = 6; vector> key_blob_list(chain_size); vector> cert_chain_list(chain_size); for (int i = 0; i < chain_size; i++) { string sub = "attest key chaining "; char index = '1' + i; string subject = sub + index; vector subject_der(make_name_from_str(subject)); uint64_t serial_int = 7000 + i; vector serial_blob(build_serial_blob(serial_int)); vector attested_key_characteristics; AttestationKey attest_key; optional attest_key_opt; if (i > 0) { attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1)); attest_key.keyBlob = key_blob_list[i - 1]; attest_key_opt = attest_key; } auto result = GenerateAttestKey(AuthorizationSetBuilder() .RsaKey(2048, 65537) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_NO_AUTH_REQUIRED) .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) .SetDefaultValidity(), attest_key_opt, &key_blob_list[i], &attested_key_characteristics, &cert_chain_list[i]); // Strongbox may not support factory provisioned attestation key. if (SecLevel() == SecurityLevel::STRONGBOX) { if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return; } ASSERT_EQ(ErrorCode::OK, result); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); ASSERT_GT(cert_chain_list[i].size(), 0); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), cert_chain_list[i][0].encodedCertificate)); if (i > 0) { /* * The first key is attestated with factory chain, but all the rest of the keys are * not supposed to be returned in attestation certificate chains. */ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i])); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. cert_chain_list[i].insert(cert_chain_list[i].end(), // cert_chain_list[i - 1].begin(), // cert_chain_list[i - 1].end()); } EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i])); EXPECT_GT(cert_chain_list[i].size(), i + 1); verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false); } for (int i = 0; i < chain_size; i++) { CheckedDeleteKey(&key_blob_list[i]); } } /* * AttestKeyTest.EcAttestKeyChaining * * This test creates a chain of multiple Ec attest keys, each used to sign the next attest key, * with the last attest key signed by the factory chain. */ TEST_P(AttestKeyTest, EcAttestKeyChaining) { const int chain_size = 6; vector> key_blob_list(chain_size); vector> cert_chain_list(chain_size); for (int i = 0; i < chain_size; i++) { string sub = "Ec attest key chaining "; char index = '1' + i; string subject = sub + index; vector subject_der(make_name_from_str(subject)); uint64_t serial_int = 800000 + i; vector serial_blob(build_serial_blob(serial_int)); vector attested_key_characteristics; AttestationKey attest_key; optional attest_key_opt; if (i > 0) { attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1)); attest_key.keyBlob = key_blob_list[i - 1]; attest_key_opt = attest_key; } auto result = GenerateAttestKey(AuthorizationSetBuilder() .EcdsaKey(EcCurve::P_256) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(), attest_key_opt, &key_blob_list[i], &attested_key_characteristics, &cert_chain_list[i]); // Strongbox may not support factory provisioned attestation key. if (SecLevel() == SecurityLevel::STRONGBOX) { if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return; } ASSERT_EQ(ErrorCode::OK, result); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); ASSERT_GT(cert_chain_list[i].size(), 0); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), cert_chain_list[i][0].encodedCertificate)); if (i > 0) { /* * The first key is attestated with factory chain, but all the rest of the keys are * not supposed to be returned in attestation certificate chains. */ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i])); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. cert_chain_list[i].insert(cert_chain_list[i].end(), // cert_chain_list[i - 1].begin(), // cert_chain_list[i - 1].end()); } EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i])); EXPECT_GT(cert_chain_list[i].size(), i + 1); verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false); } for (int i = 0; i < chain_size; i++) { CheckedDeleteKey(&key_blob_list[i]); } } /* * AttestKeyTest.EcAttestKeyMultiPurposeFail * * This test attempts to create an EC attestation key that also allows signing. */ TEST_P(AttestKeyTest, EcAttestKeyMultiPurposeFail) { if (AidlVersion() < 2) { // The KeyMint v1 spec required that KeyPurpose::ATTEST_KEY not be combined // with other key purposes. However, this was not checked at the time // so we can only be strict about checking this for implementations of KeyMint // version 2 and above. GTEST_SKIP() << "Single-purpose for KeyPurpose::ATTEST_KEY only strict since KeyMint v2"; } vector attest_key_blob; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key_blob, &attest_key_characteristics, &attest_key_cert_chain)); } /* * AttestKeyTest.AlternateAttestKeyChaining * * This test creates a chain of multiple attest keys, in the order Ec - RSA - Ec - RSA .... * Each attest key is used to sign the next attest key, with the last attest key signed by * the factory chain. This is to verify different algorithms of attest keys can * cross sign each other and be chained together. */ TEST_P(AttestKeyTest, AlternateAttestKeyChaining) { const int chain_size = 6; vector> key_blob_list(chain_size); vector> cert_chain_list(chain_size); for (int i = 0; i < chain_size; i++) { string sub = "Alt attest key chaining "; char index = '1' + i; string subject = sub + index; vector subject_der(make_name_from_str(subject)); uint64_t serial_int = 90000000 + i; vector serial_blob(build_serial_blob(serial_int)); vector attested_key_characteristics; AttestationKey attest_key; optional attest_key_opt; if (i > 0) { attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1)); attest_key.keyBlob = key_blob_list[i - 1]; attest_key_opt = attest_key; } ErrorCode result; if ((i & 0x1) == 1) { result = GenerateAttestKey(AuthorizationSetBuilder() .EcdsaKey(EcCurve::P_256) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(), attest_key_opt, &key_blob_list[i], &attested_key_characteristics, &cert_chain_list[i]); } else { result = GenerateAttestKey(AuthorizationSetBuilder() .RsaKey(2048, 65537) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(), attest_key_opt, &key_blob_list[i], &attested_key_characteristics, &cert_chain_list[i]); } // Strongbox may not support factory provisioned attestation key. if (SecLevel() == SecurityLevel::STRONGBOX) { if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return; } ASSERT_EQ(ErrorCode::OK, result); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); ASSERT_GT(cert_chain_list[i].size(), 0); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), cert_chain_list[i][0].encodedCertificate)); if (i > 0) { /* * The first key is attestated with factory chain, but all the rest of the keys are * not supposed to be returned in attestation certificate chains. */ EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i])); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. cert_chain_list[i].insert(cert_chain_list[i].end(), // cert_chain_list[i - 1].begin(), // cert_chain_list[i - 1].end()); } EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i])); EXPECT_GT(cert_chain_list[i].size(), i + 1); verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false); } for (int i = 0; i < chain_size; i++) { CheckedDeleteKey(&key_blob_list[i]); } } TEST_P(AttestKeyTest, MissingChallenge) { for (auto size : ValidKeySizes(Algorithm::RSA)) { /* * Create attestation key. */ AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::OK, GenerateAttestKey(AuthorizationSetBuilder() .RsaKey(size, 65537) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); EXPECT_EQ(attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size; /* * Use attestation key to sign RSA / ECDSA key but forget to provide a challenge */ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; EXPECT_EQ(ErrorCode::ATTESTATION_CHALLENGE_MISSING, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationApplicationId("bar") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); EXPECT_EQ(ErrorCode::ATTESTATION_CHALLENGE_MISSING, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationApplicationId("bar") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); CheckedDeleteKey(&attest_key.keyBlob); } } TEST_P(AttestKeyTest, AllEcCurves) { for (auto curve : ValidCurves()) { /* * Create attestation key. */ AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ( ErrorCode::OK, GenerateAttestKey( AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); ASSERT_GT(attest_key_cert_chain.size(), 0); EXPECT_EQ(attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on curve " << curve; /* * Use attestation key to sign RSA key */ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); ASSERT_GT(attested_key_cert_chain.size(), 0); CheckedDeleteKey(&attested_key_blob); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. if (attest_key_cert_chain.size() > 0) { attested_key_cert_chain.push_back(attest_key_cert_chain[0]); } EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); /* * Use attestation key to sign EC key */ EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .SetDefaultValidity(), attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); ASSERT_GT(attested_key_cert_chain.size(), 0); CheckedDeleteKey(&attested_key_blob); CheckedDeleteKey(&attest_key.keyBlob); hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); // Attestation by itself is not valid (last entry is not self-signed). EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain)); // Appending the attest_key chain to the attested_key_chain should yield a valid chain. if (attest_key_cert_chain.size() > 0) { attested_key_cert_chain.push_back(attest_key_cert_chain[0]); } EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain)); // Bail early if anything failed. if (HasFailure()) return; } } TEST_P(AttestKeyTest, AttestWithNonAttestKey) { // Create non-attestation key. AttestationKey non_attest_key; vector non_attest_key_characteristics; vector non_attest_key_cert_chain; ASSERT_EQ( ErrorCode::OK, GenerateKey( AuthorizationSetBuilder().EcdsaSigningKey(EcCurve::P_256).SetDefaultValidity(), {} /* attestation signing key */, &non_attest_key.keyBlob, &non_attest_key_characteristics, &non_attest_key_cert_chain)); ASSERT_GT(non_attest_key_cert_chain.size(), 0); EXPECT_EQ(non_attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(non_attest_key_cert_chain)); // Attempt to sign attestation with non-attest key. vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("foo") .AttestationApplicationId("bar") .SetDefaultValidity(), non_attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); } TEST_P(AttestKeyTest, EcdsaAttestationID) { if (is_gsi_image()) { // GSI sets up a standard set of device identifiers that may not match // the device identifiers held by the device. GTEST_SKIP() << "Test not applicable under GSI"; } // Create attestation key. AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::OK, GenerateAttestKey(AuthorizationSetBuilder() .EcdsaKey(EcCurve::P_256) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); ASSERT_GT(attest_key_cert_chain.size(), 0); EXPECT_EQ(attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)); // Collection of valid attestation ID tags. auto attestation_id_tags = AuthorizationSetBuilder(); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand"); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device"); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name"); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial"); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, "ro.product.manufacturer"); add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model"); for (const KeyParameter& tag : attestation_id_tags) { SCOPED_TRACE(testing::Message() << "+tag-" << tag); // Use attestation key to sign an ECDSA key, but include an attestation ID field. AuthorizationSetBuilder builder = AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("challenge") .AttestationApplicationId("foo") .SetDefaultValidity(); builder.push_back(tag); vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; auto result = GenerateKey(builder, attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain); if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) { continue; } ASSERT_EQ(result, ErrorCode::OK); CheckedDeleteKey(&attested_key_blob); AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); // The attested key characteristics will not contain APPLICATION_ID_* fields (their // spec definitions all have "Must never appear in KeyCharacteristics"), but the // attestation extension should contain them, so make sure the extra tag is added. hw_enforced.push_back(tag); EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced, hw_enforced, SecLevel(), attested_key_cert_chain[0].encodedCertificate)); } CheckedDeleteKey(&attest_key.keyBlob); } TEST_P(AttestKeyTest, EcdsaAttestationMismatchID) { // Create attestation key. AttestationKey attest_key; vector attest_key_characteristics; vector attest_key_cert_chain; ASSERT_EQ(ErrorCode::OK, GenerateAttestKey(AuthorizationSetBuilder() .EcdsaKey(EcCurve::P_256) .AttestKey() .SetDefaultValidity(), {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); ASSERT_GT(attest_key_cert_chain.size(), 0); EXPECT_EQ(attest_key_cert_chain.size(), 1); EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)); // Collection of invalid attestation ID tags. auto attestation_id_tags = AuthorizationSetBuilder() .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand") .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device") .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product") .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial") .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei") .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid") .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer") .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model"); vector key_blob; vector key_characteristics; for (const KeyParameter& invalid_tag : attestation_id_tags) { SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag); // Use attestation key to sign an ECDSA key, but include an invalid // attestation ID field. AuthorizationSetBuilder builder = AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) .AttestationChallenge("challenge") .AttestationApplicationId("foo") .SetDefaultValidity(); builder.push_back(invalid_tag); vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; auto result = GenerateKey(builder, attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain); ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG) << "result = " << result; } CheckedDeleteKey(&attest_key.keyBlob); } INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest); } // namespace aidl::android::hardware::security::keymint::test