Require attestation app ID.

Bug: 37318025
Test: Manually tested
Change-Id: Iaa992c8d22e0c88c2a2570355199befa484adc19
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
index 6b4524b..58102bb 100644
--- a/keymaster/3.0/default/KeymasterDevice.cpp
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -519,6 +519,7 @@
 
     hidl_vec<hidl_vec<uint8_t>> resultCertChain;
 
+    bool foundAttestationApplicationId = false;
     for (size_t i = 0; i < attestParams.size(); ++i) {
         switch (attestParams[i].tag) {
         case Tag::ATTESTATION_ID_BRAND:
@@ -532,11 +533,22 @@
             // never perform any device id attestation.
             _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
             return Void();
+
+        case Tag::ATTESTATION_APPLICATION_ID:
+            foundAttestationApplicationId = true;
+            break;
+
         default:
             break;
         }
     }
 
+    // KM3 devices reject missing attest application IDs. KM2 devices do not.
+    if (!foundAttestationApplicationId) {
+        _hidl_cb(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+                 resultCertChain);
+    }
+
     keymaster_cert_chain_t cert_chain{nullptr, 0};
 
     auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
diff --git a/keymaster/3.0/vts/functional/attestation_record.cpp b/keymaster/3.0/vts/functional/attestation_record.cpp
index 6cdd44c..5d96fff 100644
--- a/keymaster/3.0/vts/functional/attestation_record.cpp
+++ b/keymaster/3.0/vts/functional/attestation_record.cpp
@@ -244,6 +244,8 @@
     copyAuthTag(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list);
     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);
 
     return ErrorCode::OK;
 }
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index 656960b..3448398 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -892,10 +892,10 @@
     static hidl_string author_;
 };
 
-bool verify_attestation_record(const string& challenge, AuthorizationSet expected_sw_enforced,
+bool verify_attestation_record(const string& challenge, const string& app_id,
+                               AuthorizationSet expected_sw_enforced,
                                AuthorizationSet expected_tee_enforced,
                                const hidl_vec<uint8_t>& attestation_cert) {
-
     X509_Ptr cert(parse_cert_blob(attestation_cert));
     EXPECT_TRUE(!!cert.get());
     if (!cert.get()) return false;
@@ -912,6 +912,7 @@
     SecurityLevel att_keymaster_security_level;
     HidlBuf att_challenge;
     HidlBuf att_unique_id;
+    HidlBuf att_app_id;
     EXPECT_EQ(ErrorCode::OK,
               parse_attestation_record(attest_rec->data,                 //
                                        attest_rec->length,               //
@@ -930,6 +931,9 @@
         EXPECT_EQ(1U, att_attestation_version);
     }
 
+    expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID,
+                                   HidlBuf(app_id));
+
     if (!KeymasterHidlTest::IsSecure()) {
         // SW is KM2
         EXPECT_EQ(att_keymaster_version, 2U);
@@ -3835,15 +3839,41 @@
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
 
     hidl_vec<hidl_vec<uint8_t>> cert_chain;
-    EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization(
-                                           TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
-                                       &cert_chain));
+    EXPECT_EQ(
+        ErrorCode::OK,
+        AttestKey(
+            AuthorizationSetBuilder()
+                .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+            &cert_chain));
     EXPECT_GE(cert_chain.size(), 2U);
     EXPECT_TRUE(verify_chain(cert_chain));
-    EXPECT_TRUE(verify_attestation_record("challenge",                            //
-                                          key_characteristics_.softwareEnforced,  //
-                                          key_characteristics_.teeEnforced,       //
-                                          cert_chain[0]));
+    EXPECT_TRUE(
+        verify_attestation_record("challenge", "foo",                     //
+                                  key_characteristics_.softwareEnforced,  //
+                                  key_characteristics_.teeEnforced,       //
+                                  cert_chain[0]));
+}
+
+/*
+ * AttestationTest.RsaAttestationRequiresAppId
+ *
+ * Verifies that attesting to RSA requires app ID.
+ */
+TEST_F(AttestationTest, RsaAttestationRequiresAppId) {
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                              .RsaSigningKey(1024, 3)
+                              .Digest(Digest::NONE)
+                              .Padding(PaddingMode::NONE)
+                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
+
+    hidl_vec<hidl_vec<uint8_t>> cert_chain;
+    EXPECT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+              AttestKey(AuthorizationSetBuilder().Authorization(
+                            TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
+                        &cert_chain));
 }
 
 /*
@@ -3859,16 +3889,41 @@
                                              .Authorization(TAG_INCLUDE_UNIQUE_ID)));
 
     hidl_vec<hidl_vec<uint8_t>> cert_chain;
-    EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization(
-                                           TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
-                                       &cert_chain));
+    EXPECT_EQ(
+        ErrorCode::OK,
+        AttestKey(
+            AuthorizationSetBuilder()
+                .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+                .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
+            &cert_chain));
     EXPECT_GE(cert_chain.size(), 2U);
     EXPECT_TRUE(verify_chain(cert_chain));
 
-    EXPECT_TRUE(verify_attestation_record("challenge",                            //
-                                          key_characteristics_.softwareEnforced,  //
-                                          key_characteristics_.teeEnforced,       //
-                                          cert_chain[0]));
+    EXPECT_TRUE(
+        verify_attestation_record("challenge", "foo",                     //
+                                  key_characteristics_.softwareEnforced,  //
+                                  key_characteristics_.teeEnforced,       //
+                                  cert_chain[0]));
+}
+
+/*
+ * AttestationTest.EcAttestationRequiresAttestationAppId
+ *
+ * Verifies that attesting to EC keys requires app ID
+ */
+TEST_F(AttestationTest, EcAttestationRequiresAttestationAppId) {
+    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)));
+
+    hidl_vec<hidl_vec<uint8_t>> cert_chain;
+    EXPECT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+              AttestKey(AuthorizationSetBuilder().Authorization(
+                            TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")),
+                        &cert_chain));
 }
 
 /*
@@ -3940,15 +3995,18 @@
     AuthorizationSet begin_out_params;
 
     if (rollback_protected) {
-        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
-                Begin(KeyPurpose::SIGN, key_blob_,
-                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
-                        &begin_out_params, &op_handle_));
+        EXPECT_EQ(
+            ErrorCode::INVALID_KEY_BLOB,
+            Begin(KeyPurpose::SIGN, key_blob_, AuthorizationSetBuilder()
+                                                   .Digest(Digest::NONE)
+                                                   .Padding(PaddingMode::NONE),
+                  &begin_out_params, &op_handle_));
     } else {
-        EXPECT_EQ(ErrorCode::OK,
-                Begin(KeyPurpose::SIGN, key_blob_,
-                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
-                        &begin_out_params, &op_handle_));
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_,
+                                       AuthorizationSetBuilder()
+                                           .Digest(Digest::NONE)
+                                           .Padding(PaddingMode::NONE),
+                                       &begin_out_params, &op_handle_));
     }
     AbortIfNeeded();
     key_blob_ = HidlBuf();
@@ -4014,15 +4072,18 @@
     AuthorizationSet begin_out_params;
 
     if (rollback_protected) {
-        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
-                Begin(KeyPurpose::SIGN, key_blob_,
-                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
-                        &begin_out_params, &op_handle_));
+        EXPECT_EQ(
+            ErrorCode::INVALID_KEY_BLOB,
+            Begin(KeyPurpose::SIGN, key_blob_, AuthorizationSetBuilder()
+                                                   .Digest(Digest::NONE)
+                                                   .Padding(PaddingMode::NONE),
+                  &begin_out_params, &op_handle_));
     } else {
-        EXPECT_EQ(ErrorCode::OK,
-                Begin(KeyPurpose::SIGN, key_blob_,
-                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
-                        &begin_out_params, &op_handle_));
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_,
+                                       AuthorizationSetBuilder()
+                                           .Digest(Digest::NONE)
+                                           .Padding(PaddingMode::NONE),
+                                       &begin_out_params, &op_handle_));
     }
     AbortIfNeeded();
     key_blob_ = HidlBuf();