/*
 * 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 <android-base/logging.h>
#include <android-base/strings.h>
#include <cutils/log.h>
#include <cutils/properties.h>

#include <keymint_support/key_param_output.h>
#include <keymint_support/openssl_utils.h>

#include "KeyMintAidlTestBase.h"

namespace aidl::android::hardware::security::keymint::test {

namespace {
string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";

bool IsSelfSigned(const vector<Certificate>& chain) {
    if (chain.size() != 1) return false;
    return ChainSignaturesAreValid(chain);
}

/*
 * Run a shell command and collect the output of it. If any error, set an empty string as the
 * output.
 */
string exec_command(string command) {
    char buffer[128];
    string result = "";

    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        LOG(ERROR) << "popen failed.";
        return result;
    }

    // read till end of process:
    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != NULL) {
            result += buffer;
        }
    }

    pclose(pipe);
    return result;
}

/*
 * Get IMEI using Telephony service shell command. If any error while executing the command
 * then empty string will be returned as output.
 */
string get_imei(int slot) {
    string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
    string output = exec_command(cmd);

    if (output.empty()) {
        LOG(ERROR) << "Command failed. Cmd: " << cmd;
        return "";
    }

    vector<string> out = ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");

    if (out.size() != 1) {
        LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
        return "";
    }

    return ::android::base::Trim(out[0]);
}

}  // 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<AttestationKey>& attest_key,
                                vector<uint8_t>* key_blob,
                                vector<KeyCharacteristics>* key_characteristics,
                                vector<Certificate>* 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) < __ANDROID_API_T__) {
            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 T with
    // Keymaster 4.0 in StrongBox.
    bool is_chipset_allowed_km4_strongbox(void) const {
        std::array<char, PROPERTY_VALUE_MAX> buffer;

        const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0);
        if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false;

        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 {
        // Check the chipset first as that doesn't require a round-trip to Package Manager.
        if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() &&
            is_attest_key_feature_disabled()) {
            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<KeyCharacteristics> attest_key_characteristics;
        vector<Certificate> 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<uint8_t> attested_key_blob;
        vector<KeyCharacteristics> attested_key_characteristics;
        vector<Certificate> 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<uint8_t> attest_key_blob;
    vector<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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<uint8_t> 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<uint8_t> serial_blob(build_serial_blob(serial_int));

    /*
     * Create attestation key.
     */
    AttestationKey attest_key;
    vector<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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<uint8_t> attested_key_blob;
    vector<KeyCharacteristics> attested_key_characteristics;
    vector<Certificate> attested_key_cert_chain;

    auto subject2 = "cert subject";
    vector<uint8_t> subject_der2(make_name_from_str(subject2));

    uint64_t serial_int2 = 255;
    vector<uint8_t> 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<vector<uint8_t>> key_blob_list(chain_size);
    vector<vector<Certificate>> 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<uint8_t> subject_der(make_name_from_str(subject));

        uint64_t serial_int = 7000 + i;
        vector<uint8_t> serial_blob(build_serial_blob(serial_int));

        vector<KeyCharacteristics> attested_key_characteristics;
        AttestationKey attest_key;
        optional<AttestationKey> 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<vector<uint8_t>> key_blob_list(chain_size);
    vector<vector<Certificate>> 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<uint8_t> subject_der(make_name_from_str(subject));

        uint64_t serial_int = 800000 + i;
        vector<uint8_t> serial_blob(build_serial_blob(serial_int));

        vector<KeyCharacteristics> attested_key_characteristics;
        AttestationKey attest_key;
        optional<AttestationKey> 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<uint8_t> attest_key_blob;
    vector<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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<vector<uint8_t>> key_blob_list(chain_size);
    vector<vector<Certificate>> 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<uint8_t> subject_der(make_name_from_str(subject));

        uint64_t serial_int = 90000000 + i;
        vector<uint8_t> serial_blob(build_serial_blob(serial_int));

        vector<KeyCharacteristics> attested_key_characteristics;
        AttestationKey attest_key;
        optional<AttestationKey> 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<KeyCharacteristics> attest_key_characteristics;
        vector<Certificate> 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<uint8_t> attested_key_blob;
        vector<KeyCharacteristics> attested_key_characteristics;
        vector<Certificate> 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<KeyCharacteristics> attest_key_characteristics;
        vector<Certificate> 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<uint8_t> attested_key_blob;
        vector<KeyCharacteristics> attested_key_characteristics;
        vector<Certificate> 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<KeyCharacteristics> non_attest_key_characteristics;
    vector<Certificate> 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<uint8_t> attested_key_blob;
    vector<KeyCharacteristics> attested_key_characteristics;
    vector<Certificate> 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<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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();
    // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
    // to ro.product.brand
    std::string prop_value =
            ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
    if (!prop_value.empty()) {
        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
                          "ro.product.brand_for_attestation");
    } else {
        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");
    // Use ro.product.name_for_attestation property for attestation if it is present else fallback
    // to ro.product.name
    prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
    if (!prop_value.empty()) {
        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
                          "ro.product.name_for_attestation");
    } else {
        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.serialno");
    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
                      "ro.product.manufacturer");
    // Use ro.product.model_for_attestation property for attestation if it is present else fallback
    // to ro.product.model
    prop_value =
            ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
    if (!prop_value.empty()) {
        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
                          "ro.product.model_for_attestation");
    } else {
        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
    }

    string imei = get_imei(0);
    if (!imei.empty()) {
        attestation_id_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
    }

    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<uint8_t> attested_key_blob;
        vector<KeyCharacteristics> attested_key_characteristics;
        vector<Certificate> 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<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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");

    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
    if (SecLevel() != SecurityLevel::STRONGBOX) {
        if (isSecondImeiIdAttestationRequired()) {
            attestation_id_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI,
                                              "invalid-second-imei");
        }
    }
    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> 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<uint8_t> attested_key_blob;
        vector<KeyCharacteristics> attested_key_characteristics;
        vector<Certificate> 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;
        device_id_attestation_vsr_check(result);
    }
    CheckedDeleteKey(&attest_key.keyBlob);
}

TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
    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";
    }

    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
    if (SecLevel() == SecurityLevel::STRONGBOX) {
        GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
    }

    // Skip the test if there is no second IMEI exists.
    string second_imei = get_imei(1);
    if (second_imei.empty() || second_imei.compare("null") == 0) {
        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
    }

    if (!isSecondImeiIdAttestationRequired()) {
        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
    }

    // Create attestation key.
    AttestationKey attest_key;
    vector<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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");
    EXPECT_EQ(attest_key_cert_chain.size(), 1);
    EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));

    // 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();
    // b/264979486 - second imei doesn't depend on first imei.
    // Add second IMEI as attestation id without adding first IMEI as
    // attestation id.
    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());

    vector<uint8_t> attested_key_blob;
    vector<KeyCharacteristics> attested_key_characteristics;
    vector<Certificate> 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()) {
        GTEST_SKIP()
                << "Test not applicable as device does not support SECOND-IMEI ID attestation.";
    }

    ASSERT_EQ(result, ErrorCode::OK);

    device_id_attestation_vsr_check(result);

    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.
    vector<uint8_t> imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, imei_blob);
    hw_enforced.push_back(imei_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, MultipleIMEIAttestationIDSuccess) {
    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";
    }

    // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
    if (SecLevel() == SecurityLevel::STRONGBOX) {
        GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
    }

    // Skip the test if there is no first IMEI exists.
    string imei = get_imei(0);
    if (imei.empty() || imei.compare("null") == 0) {
        GTEST_SKIP() << "Test not applicable as there is no first IMEI";
    }

    // Skip the test if there is no second IMEI exists.
    string second_imei = get_imei(1);
    if (second_imei.empty() || second_imei.compare("null") == 0) {
        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
    }

    if (!isSecondImeiIdAttestationRequired()) {
        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
    }

    // Create attestation key.
    AttestationKey attest_key;
    vector<KeyCharacteristics> attest_key_characteristics;
    vector<Certificate> 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");
    EXPECT_EQ(attest_key_cert_chain.size(), 1);
    EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));

    // Use attestation key to sign an ECDSA key, but include both IMEI attestation ID fields.
    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
                                              .EcdsaSigningKey(EcCurve::P_256)
                                              .Authorization(TAG_NO_AUTH_REQUIRED)
                                              .AttestationChallenge("challenge")
                                              .AttestationApplicationId("foo")
                                              .SetDefaultValidity();
    builder.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());

    vector<uint8_t> attested_key_blob;
    vector<KeyCharacteristics> attested_key_characteristics;
    vector<Certificate> 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()) {
        GTEST_SKIP() << "Test not applicable as device does not support IMEI ID attestation.";
    }

    ASSERT_EQ(result, ErrorCode::OK);

    device_id_attestation_vsr_check(result);

    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.
    vector<uint8_t> imei_blob(imei.data(), imei.data() + imei.size());
    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_IMEI, imei_blob);
    hw_enforced.push_back(imei_tag);
    vector<uint8_t> sec_imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
    KeyParameter sec_imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, sec_imei_blob);
    hw_enforced.push_back(sec_imei_tag);

    EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
                                          hw_enforced, SecLevel(),
                                          attested_key_cert_chain[0].encodedCertificate));

    CheckedDeleteKey(&attest_key.keyBlob);
}

INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest);

}  // namespace aidl::android::hardware::security::keymint::test
