KeyMaster VTS: improve attestation tests

Check that the various ATTESTATION_ID_* tags are included if they
have the correct value, and that keygen fails if they have an invalid
value.

Also fix the support libraries to add the missing fields to the ASN.1
schema and fix the existing ordering.

Bug: 190757200
Test: VtsHalKeymasterV4_1TargetTest, VtsHalKeymasterV4_0TargetTest
Merged-In: I11d28d71676d44ebdc79b25b2eb70947022bb1cf
Ignore-AOSP-First: to be cross-merged manually
Change-Id: I5e19880bbc9e2e667f1204bdc2247ae53a3dada7
diff --git a/keymaster/4.0/support/attestation_record.cpp b/keymaster/4.0/support/attestation_record.cpp
index bc294bd..342b3e2 100644
--- a/keymaster/4.0/support/attestation_record.cpp
+++ b/keymaster/4.0/support/attestation_record.cpp
@@ -71,6 +71,7 @@
     ASN1_INTEGER_SET* padding;
     ASN1_INTEGER* ec_curve;
     ASN1_INTEGER* rsa_public_exponent;
+    ASN1_NULL* rollback_resistance;
     ASN1_INTEGER* active_date_time;
     ASN1_INTEGER* origination_expire_date_time;
     ASN1_INTEGER* usage_expire_date_time;
@@ -78,56 +79,84 @@
     ASN1_INTEGER* user_auth_type;
     ASN1_INTEGER* auth_timeout;
     ASN1_NULL* allow_while_on_body;
+    ASN1_NULL* trusted_user_presence_required;
+    ASN1_NULL* trusted_confirmation_required;
+    ASN1_NULL* unlocked_device_required;
     ASN1_NULL* all_applications;
     ASN1_OCTET_STRING* application_id;
     ASN1_INTEGER* creation_date_time;
     ASN1_INTEGER* origin;
-    ASN1_NULL* rollback_resistance;
     KM_ROOT_OF_TRUST* root_of_trust;
     ASN1_INTEGER* os_version;
     ASN1_INTEGER* os_patchlevel;
     ASN1_OCTET_STRING* attestation_application_id;
-    ASN1_NULL* trusted_user_presence_required;
-    ASN1_NULL* trusted_confirmation_required;
-    ASN1_NULL* unlocked_device_required;
+    ASN1_OCTET_STRING* attestation_id_brand;
+    ASN1_OCTET_STRING* attestation_id_device;
+    ASN1_OCTET_STRING* attestation_id_product;
+    ASN1_OCTET_STRING* attestation_id_serial;
+    ASN1_OCTET_STRING* attestation_id_imei;
+    ASN1_OCTET_STRING* attestation_id_meid;
+    ASN1_OCTET_STRING* attestation_id_manufacturer;
+    ASN1_OCTET_STRING* attestation_id_model;
     ASN1_INTEGER* vendor_patchlevel;
     ASN1_INTEGER* boot_patchlevel;
 } KM_AUTH_LIST;
 
 ASN1_SEQUENCE(KM_AUTH_LIST) = {
-    ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()),
-    ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()),
-    ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
-                 TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, TAG_ROLLBACK_RESISTANCE.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
-                 TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
-                 TAG_USAGE_EXPIRE_DATETIME.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL, TAG_ALLOW_WHILE_ON_BODY.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL,
-                 TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL,
-                 TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL,
-                 TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER, TAG_CREATION_DATETIME.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, TAG_VENDOR_PATCHLEVEL.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
-    ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
-                 TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
+        ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()),
+        ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()),
+        ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
+                     TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
+                     TAG_ROLLBACK_RESISTANCE.maskedTag()),
+
+        ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
+                     TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
+                     TAG_USAGE_EXPIRE_DATETIME.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL,
+                     TAG_ALLOW_WHILE_ON_BODY.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL,
+                     TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL,
+                     TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL,
+                     TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER,
+                     TAG_CREATION_DATETIME.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_BRAND.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_DEVICE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_PRODUCT.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_SERIAL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_IMEI.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MEID.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MODEL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER,
+                     TAG_VENDOR_PATCHLEVEL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
 } ASN1_SEQUENCE_END(KM_AUTH_LIST);
 IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
 
@@ -259,6 +288,14 @@
     copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
     copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
     copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list);
+    copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list);
+    copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list);
+    copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list);
+    copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list);
+    copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list);
+    copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list);
+    copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list);
+    copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list);
     copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list);
     copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
     copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED,
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 9e37ed0..01c502c 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -96,6 +96,18 @@
     return count > 0;
 }
 
+// If the given property is available, add it to the tag set under the given tag ID.
+template <Tag tag>
+void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
+                       const char* prop) {
+    char value[PROPERTY_VALUE_MAX];
+    int len = property_get(prop, value, /* default = */ "");
+    if (len > 0) {
+        tags->Authorization(ttag, reinterpret_cast<const uint8_t*>(value),
+                            static_cast<size_t>(len));
+    }
+}
+
 constexpr char hex_value[256] = {0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
                                  0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
                                  0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
@@ -4409,6 +4421,95 @@
 }
 
 /*
+ * AttestationTest.EcAttestationID
+ *
+ * Verifies that attesting to EC keys with correct attestation ID fields works and generates the
+ * expected output.
+ */
+TEST_P(AttestationTest, EcAttestationID) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .EcdsaSigningKey(EcCurve::P_256)
+                                                 .Digest(Digest::SHA_2_256)
+                                                 .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+    // 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) {
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                        .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo"));
+        // Include one of the (valid) attestation ID tags.
+        builder.push_back(tag);
+        hidl_vec<hidl_vec<uint8_t>> cert_chain;
+        auto result = AttestKey(builder, &cert_chain);
+        if (result == ErrorCode::CANNOT_ATTEST_IDS) {
+            continue;
+        }
+
+        ASSERT_EQ(ErrorCode::OK, result);
+        EXPECT_GE(cert_chain.size(), 2U);
+
+        std::vector<KeyParameter> expected_hw_enforced = key_characteristics_.hardwareEnforced;
+        expected_hw_enforced.push_back(tag);
+
+        EXPECT_TRUE(verify_attestation_record(
+                "challenge", "foo", key_characteristics_.softwareEnforced,
+                hidl_vec<KeyParameter>(expected_hw_enforced), SecLevel(), cert_chain[0]));
+    }
+}
+
+/*
+ * AttestationTest.EcAttestationMismatchID
+ *
+ * Verifies that attesting to EC keys with incorrect attestation ID fields fails.
+ */
+TEST_P(AttestationTest, EcAttestationMismatchID) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .EcdsaSigningKey(EcCurve::P_256)
+                                                 .Digest(Digest::SHA_2_256)
+                                                 .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+    // Collection of invalid attestation ID tags.
+    std::string invalid = "completely-invalid";
+    auto invalid_tags =
+            AuthorizationSetBuilder()
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(),
+                                   invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size());
+
+    for (const KeyParameter& invalid_tag : invalid_tags) {
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                        .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo"));
+        // Include one of the invalid attestation ID tags.
+        builder.push_back(invalid_tag);
+        hidl_vec<hidl_vec<uint8_t>> cert_chain;
+        auto result = AttestKey(builder, &cert_chain);
+
+        EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
+                << "result: " << static_cast<int32_t>(result);
+    }
+}
+
+/*
  * AttestationTest.EcAttestationRequiresAttestationAppId
  *
  * Verifies that attesting to EC keys requires app ID
diff --git a/keymaster/4.1/support/attestation_record.cpp b/keymaster/4.1/support/attestation_record.cpp
index 207a7e8..15230d5 100644
--- a/keymaster/4.1/support/attestation_record.cpp
+++ b/keymaster/4.1/support/attestation_record.cpp
@@ -79,6 +79,8 @@
     ASN1_INTEGER_SET* padding;
     ASN1_INTEGER* ec_curve;
     ASN1_INTEGER* rsa_public_exponent;
+    ASN1_NULL* rollback_resistance;
+    ASN1_NULL* early_boot_only;
     ASN1_INTEGER* active_date_time;
     ASN1_INTEGER* origination_expire_date_time;
     ASN1_INTEGER* usage_expire_date_time;
@@ -86,21 +88,27 @@
     ASN1_INTEGER* user_auth_type;
     ASN1_INTEGER* auth_timeout;
     ASN1_NULL* allow_while_on_body;
+    ASN1_NULL* trusted_user_presence_required;
+    ASN1_NULL* trusted_confirmation_required;
+    ASN1_NULL* unlocked_device_required;
     ASN1_NULL* all_applications;
     ASN1_OCTET_STRING* application_id;
     ASN1_INTEGER* creation_date_time;
     ASN1_INTEGER* origin;
-    ASN1_NULL* rollback_resistance;
     KM_ROOT_OF_TRUST* root_of_trust;
     ASN1_INTEGER* os_version;
     ASN1_INTEGER* os_patchlevel;
     ASN1_OCTET_STRING* attestation_application_id;
-    ASN1_NULL* trusted_user_presence_required;
-    ASN1_NULL* trusted_confirmation_required;
-    ASN1_NULL* unlocked_device_required;
+    ASN1_OCTET_STRING* attestation_id_brand;
+    ASN1_OCTET_STRING* attestation_id_device;
+    ASN1_OCTET_STRING* attestation_id_product;
+    ASN1_OCTET_STRING* attestation_id_serial;
+    ASN1_OCTET_STRING* attestation_id_imei;
+    ASN1_OCTET_STRING* attestation_id_meid;
+    ASN1_OCTET_STRING* attestation_id_manufacturer;
+    ASN1_OCTET_STRING* attestation_id_model;
     ASN1_INTEGER* vendor_patchlevel;
     ASN1_INTEGER* boot_patchlevel;
-    ASN1_NULL* early_boot_only;
     ASN1_NULL* device_unique_attestation;
     ASN1_NULL* identity_credential_key;
 } KM_AUTH_LIST;
@@ -116,6 +124,7 @@
                      TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
                      TAG_ROLLBACK_RESISTANCE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
                      TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
@@ -138,12 +147,27 @@
         ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_BRAND.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_DEVICE.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_PRODUCT.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_SERIAL.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_IMEI.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MEID.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_MODEL.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER,
                      TAG_VENDOR_PATCHLEVEL.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
-        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
-                     TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
-        ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL,
                      TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential_key, ASN1_NULL,
@@ -279,6 +303,14 @@
     copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
     copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
     copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list);
+    copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list);
+    copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list);
+    copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list);
+    copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list);
+    copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list);
+    copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list);
+    copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list);
+    copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list);
     copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list);
     copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
     copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED,
diff --git a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
index 40eb142..e8db56a 100644
--- a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
+++ b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
@@ -53,6 +53,14 @@
 using V4_0::TAG_ASSOCIATED_DATA;
 using V4_0::TAG_ATTESTATION_APPLICATION_ID;
 using V4_0::TAG_ATTESTATION_CHALLENGE;
+using V4_0::TAG_ATTESTATION_ID_BRAND;
+using V4_0::TAG_ATTESTATION_ID_DEVICE;
+using V4_0::TAG_ATTESTATION_ID_IMEI;
+using V4_0::TAG_ATTESTATION_ID_MANUFACTURER;
+using V4_0::TAG_ATTESTATION_ID_MEID;
+using V4_0::TAG_ATTESTATION_ID_MODEL;
+using V4_0::TAG_ATTESTATION_ID_PRODUCT;
+using V4_0::TAG_ATTESTATION_ID_SERIAL;
 using V4_0::TAG_AUTH_TIMEOUT;
 using V4_0::TAG_BLOB_USAGE_REQUIREMENTS;
 using V4_0::TAG_BLOCK_MODE;
diff --git a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
index 3d97daf..4a57f44 100644
--- a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -27,6 +27,8 @@
 #include <keymasterV4_1/attestation_record.h>
 #include <keymasterV4_1/authorization_set.h>
 
+using android::hardware::keymaster::V4_0::test::add_tag_from_prop;
+
 // Not to dump the attestation by default. Can enable by specify the parameter
 // "--dump_attestations" on lunching VTS
 static bool dumpAttestations = false;
@@ -173,10 +175,15 @@
     attestation.software_enforced.Sort();
     attestation.hardware_enforced.Sort();
 
-    EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(attestation.software_enforced))
-            << DIFFERENCE(expected_sw_enforced, attestation.software_enforced);
-    EXPECT_EQ(filter_tags(expected_hw_enforced), filter_tags(attestation.hardware_enforced))
-            << DIFFERENCE(expected_hw_enforced, attestation.hardware_enforced);
+    expected_sw_enforced = filter_tags(expected_sw_enforced);
+    expected_hw_enforced = filter_tags(expected_hw_enforced);
+    AuthorizationSet attestation_sw_enforced = filter_tags(attestation.software_enforced);
+    AuthorizationSet attestation_hw_enforced = filter_tags(attestation.hardware_enforced);
+
+    EXPECT_EQ(expected_sw_enforced, attestation_sw_enforced)
+            << DIFFERENCE(expected_sw_enforced, attestation_sw_enforced);
+    EXPECT_EQ(expected_hw_enforced, attestation_hw_enforced)
+            << DIFFERENCE(expected_hw_enforced, attestation_hw_enforced);
 }
 
 X509_Ptr parse_cert_blob(const std::vector<uint8_t>& blob) {
@@ -342,6 +349,106 @@
             SecLevel());
 }
 
+TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
+    if (SecLevel() != SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder()
+                                                         .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                         .EcdsaSigningKey(256)
+                                                         .Digest(Digest::SHA_2_256)
+                                                         .Authorization(TAG_INCLUDE_UNIQUE_ID))));
+
+    // Collection of valid attestation ID tags.
+    auto attestation_id_tags = AuthorizationSetBuilder();
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_SERIAL, "ro.serial");
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MANUFACTURER,
+                      "ro.product.manufacturer");
+    add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+
+    for (const KeyParameter& tag : attestation_id_tags) {
+        hidl_vec<hidl_vec<uint8_t>> cert_chain;
+        HidlBuf challenge("challenge");
+        HidlBuf app_id("foo");
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
+                        .Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
+                        .Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id);
+        builder.push_back(tag);
+        ErrorCode result = convert(AttestKey(builder, &cert_chain));
+
+        // It is optional for Strong box to support DeviceUniqueAttestation.
+        if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
+
+        ASSERT_EQ(ErrorCode::OK, result);
+        EXPECT_EQ(2U, cert_chain.size());
+        if (dumpAttestations) {
+            for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_));
+        }
+        auto [err, attestation] = parse_attestation_record(cert_chain[0]);
+        ASSERT_EQ(ErrorCode::OK, err);
+
+        AuthorizationSetBuilder hw_enforced =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
+                        .Authorization(TAG_NO_AUTH_REQUIRED)
+                        .EcdsaSigningKey(256)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
+                        .Authorization(TAG_OS_VERSION, os_version())
+                        .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
+        hw_enforced.push_back(tag);
+        check_attestation_record(
+                attestation, challenge,
+                /* sw_enforced */
+                AuthorizationSetBuilder().Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id),
+                hw_enforced, SecLevel());
+    }
+}
+
+TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
+    if (SecLevel() != SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder()
+                                                         .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                         .EcdsaSigningKey(256)
+                                                         .Digest(Digest::SHA_2_256)
+                                                         .Authorization(TAG_INCLUDE_UNIQUE_ID))));
+
+    // Collection of invalid attestation ID tags.
+    std::string invalid = "completely-invalid";
+    auto attestation_id_tags =
+            AuthorizationSetBuilder()
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(),
+                                   invalid.size())
+                    .Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size());
+
+    for (const KeyParameter& invalid_tag : attestation_id_tags) {
+        hidl_vec<hidl_vec<uint8_t>> cert_chain;
+        HidlBuf challenge("challenge");
+        HidlBuf app_id("foo");
+        AuthorizationSetBuilder builder =
+                AuthorizationSetBuilder()
+                        .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
+                        .Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
+                        .Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id);
+        builder.push_back(invalid_tag);
+        ErrorCode result = convert(AttestKey(builder, &cert_chain));
+
+        EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
+                << "result: " << static_cast<int32_t>(result);
+    }
+}
+
 INSTANTIATE_KEYMASTER_4_1_HIDL_TEST(DeviceUniqueAttestationTest);
 
 }  // namespace test
diff --git a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
index f8c1fad..670ccfb 100644
--- a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
+++ b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
@@ -18,6 +18,8 @@
 
 #include <android/hardware/keymaster/4.1/IKeymasterDevice.h>
 
+#include <android-base/properties.h>
+
 #include <KeymasterHidlTest.h>
 #include <keymasterV4_1/authorization_set.h>
 
@@ -159,3 +161,17 @@
                              android::hardware::PrintInstanceNameToString)
 
 }  // namespace android::hardware::keymaster::V4_1::test
+
+namespace android::hardware::keymaster::V4_0::test {
+
+// If the given property is available, add it to the tag set under the given tag ID.
+template <Tag tag>
+void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
+                       const char* prop) {
+    std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
+    if (!prop_value.empty()) {
+        tags->Authorization(ttag, prop_value.data(), prop_value.size());
+    }
+}
+
+}  // namespace android::hardware::keymaster::V4_0::test