Add more vts tests related to limited use key.
1. Fix test case for usage count limit tag = 1 case, when
  hardware cannot enforce it, the tag should by enforced by keystore.
2. Add test case for usage count limit tag > 1.
3. Add test case to verify the usage count limit tag appears
  correctly in the attestation certificate for asymmetic key.

Test: atest -c VtsAidlKeyMintTargetTest

Change-Id: I01df278b42a91a78c8888c13c4f81b7ec70cfa22
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index bc07235..f52e32b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -27,7 +27,7 @@
  * data are stored in KeyParameter.
  */
 @VintfStability
-@Backing(type = "int")
+@Backing(type="int")
 enum Tag {
     /**
      * Tag::INVALID should never be set.  It means you hit an error.
@@ -82,7 +82,6 @@
      */
     BLOCK_MODE = (2 << 28) /* TagType:ENUM_REP */ | 4,
 
-
     /**
      * Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing
      * and verification operations.  This tag is relevant to RSA, ECDSA and HMAC keys.  Possible
@@ -187,21 +186,21 @@
      */
     INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202,
 
-     /**
-      * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with
-      * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP
-      * and this tag is absent then SHA1 digest is selected by default for MGF1.
-      *
-      * This tag is repeatable for key generation/import.  If this tag is present in the key
-      * characteristics with one or more values from @4.0::Digest, then for RSA cipher
-      * operations with OAEP Padding, the caller must specify a digest in the additionalParams
-      * argument of begin operation. If this tag is missing or the specified digest is not in
-      * the digests associated with the key then begin operation must fail with
-      * ErrorCode::INCOMPATIBLE_MGF_DIGEST.
-      *
-      * Must be hardware-enforced.
-      */
-     RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203,
+    /**
+     * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with
+     * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP
+     * and this tag is absent then SHA1 digest is selected by default for MGF1.
+     *
+     * This tag is repeatable for key generation/import.  If this tag is present in the key
+     * characteristics with one or more values from @4.0::Digest, then for RSA cipher
+     * operations with OAEP Padding, the caller must specify a digest in the additionalParams
+     * argument of begin operation. If this tag is missing or the specified digest is not in
+     * the digests associated with the key then begin operation must fail with
+     * ErrorCode::INCOMPATIBLE_MGF_DIGEST.
+     *
+     * Must be hardware-enforced.
+     */
+    RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203,
 
     /**
      * TODO(seleneh) this tag needs to be deleted from all codes.
@@ -346,14 +345,14 @@
      * At this point, if the caller specifies count > 1, it is not expected that any TEE will be
      * able to enforce this feature in the hardware due to limited resources of secure
      * storage. In this case, the tag with the value of maximum usage must be added to the key
-     * characteristics with SecurityLevel::SOFTWARE by the IKeyMintDevice.
+     * characteristics with SecurityLevel::KEYSTORE by the IKeyMintDevice.
      *
      * On the other hand, if the caller specifies count = 1, some TEEs may have the ability
      * to enforce this feature in the hardware with its secure storage. If the IKeyMintDevice
      * implementation can enforce this feature, the tag with value = 1 must be added to the key
      * characteristics with the SecurityLevel of the IKeyMintDevice. If the IKeyMintDevice can't
      * enforce this feature even when the count = 1, the tag must be added to the key
-     * characteristics with the SecurityLevel::SOFTWARE.
+     * characteristics with the SecurityLevel::KEYSTORE.
      *
      * When the key is attested, this tag with the same value must also be added to the attestation
      * record. This tag must have the same SecurityLevel as the tag that is added to the key
@@ -497,7 +496,8 @@
      */
     TRUSTED_USER_PRESENCE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 507,
 
-    /** Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
+    /**
+     * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
      *  specifies that this key must not be usable unless the user provides confirmation of the data
      *  to be signed.  Confirmation is proven to keyMint via an approval token.  See
      *  CONFIRMATION_TOKEN, as well as the ConfirmatinUI HAL.
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 766c02d..6555157 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -55,6 +55,9 @@
     for (auto& entry : key_characteristics) {
         if (entry.authorizations.empty()) return false;
 
+        // Just ignore the SecurityLevel::KEYSTORE as the KM won't do any enforcement on this.
+        if (entry.securityLevel == SecurityLevel::KEYSTORE) continue;
+
         if (levels_seen.find(entry.securityLevel) != levels_seen.end()) return false;
         levels_seen.insert(entry.securityLevel);
 
@@ -824,22 +827,36 @@
     return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
 }
 
-const vector<KeyParameter>& KeyMintAidlTestBase::HwEnforcedAuthorizations(
-        const vector<KeyCharacteristics>& key_characteristics) {
-    auto found =
-            std::find_if(key_characteristics.begin(), key_characteristics.end(), [](auto& entry) {
-                return entry.securityLevel == SecurityLevel::STRONGBOX ||
-                       entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
-            });
+const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations(
+        const vector<KeyCharacteristics>& key_characteristics, SecurityLevel securityLevel) {
+    auto found = std::find_if(
+            key_characteristics.begin(), key_characteristics.end(),
+            [securityLevel](auto& entry) { return entry.securityLevel == securityLevel; });
     return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
 }
 
-const vector<KeyParameter>& KeyMintAidlTestBase::SwEnforcedAuthorizations(
+AuthorizationSet KeyMintAidlTestBase::HwEnforcedAuthorizations(
         const vector<KeyCharacteristics>& key_characteristics) {
-    auto found = std::find_if(
-            key_characteristics.begin(), key_characteristics.end(),
-            [](auto& entry) { return entry.securityLevel == SecurityLevel::SOFTWARE; });
-    return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
+    AuthorizationSet authList;
+    for (auto& entry : key_characteristics) {
+        if (entry.securityLevel == SecurityLevel::STRONGBOX ||
+            entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT) {
+            authList.push_back(AuthorizationSet(entry.authorizations));
+        }
+    }
+    return authList;
+}
+
+AuthorizationSet KeyMintAidlTestBase::SwEnforcedAuthorizations(
+        const vector<KeyCharacteristics>& key_characteristics) {
+    AuthorizationSet authList;
+    for (auto& entry : key_characteristics) {
+        if (entry.securityLevel == SecurityLevel::SOFTWARE ||
+            entry.securityLevel == SecurityLevel::KEYSTORE) {
+            authList.push_back(AuthorizationSet(entry.authorizations));
+        }
+    }
+    return authList;
 }
 
 }  // namespace test
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index c1a1dd9..780971d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -175,9 +175,12 @@
     inline const vector<KeyParameter>& SecLevelAuthorizations() {
         return SecLevelAuthorizations(key_characteristics_);
     }
-    const vector<KeyParameter>& HwEnforcedAuthorizations(
+    const vector<KeyParameter>& SecLevelAuthorizations(
+            const vector<KeyCharacteristics>& key_characteristics, SecurityLevel securityLevel);
+
+    AuthorizationSet HwEnforcedAuthorizations(
             const vector<KeyCharacteristics>& key_characteristics);
-    const vector<KeyParameter>& SwEnforcedAuthorizations(
+    AuthorizationSet SwEnforcedAuthorizations(
             const vector<KeyCharacteristics>& key_characteristics);
 
   private:
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index c876440..c849bad 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -646,6 +646,61 @@
 }
 
 /*
+ * NewKeyGenerationTest.LimitedUsageRsaWithAttestation
+ *
+ * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the
+ * resulting keys have correct characteristics and attestation.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) {
+    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        auto challenge = "hello";
+        auto app_id = "foo";
+
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .RsaSigningKey(key_size, 65537)
+                                                     .Digest(Digest::NONE)
+                                                     .Padding(PaddingMode::NONE)
+                                                     .AttestationChallenge(challenge)
+                                                     .AttestationApplicationId(app_id)
+                                                     .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                     .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+        EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+        // Check the usage count limit tag appears in the authorizations.
+        AuthorizationSet auths;
+        for (auto& entry : key_characteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
+        EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+                << "key usage count limit " << 1U << " missing";
+
+        // Check the usage count limit tag also appears in the attestation.
+        EXPECT_TRUE(verify_chain(cert_chain_));
+        ASSERT_GT(cert_chain_.size(), 0);
+
+        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+                                              sw_enforced, hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.NoInvalidRsaSizes
  *
  * Verifies that keymint cannot generate any RSA key sizes that are designated as invalid.
@@ -4297,11 +4352,11 @@
 typedef KeyMintAidlTestBase UsageCountLimitTest;
 
 /*
- * UsageCountLimitTest.TestLimitAes
+ * UsageCountLimitTest.TestSingleUseAes
  *
- * Verifies that the usage count limit tag works correctly with AES keys.
+ * Verifies that the usage count limit tag = 1 works correctly with AES keys.
  */
-TEST_P(UsageCountLimitTest, TestLimitAes) {
+TEST_P(UsageCountLimitTest, TestSingleUseAes) {
     if (SecLevel() == SecurityLevel::STRONGBOX) return;
 
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -4322,31 +4377,75 @@
     string message = "1234567890123456";
     auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE);
 
+    AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+    AuthorizationSet keystore_auths =
+            SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE);
+
     // First usage of AES key should work.
     EncryptMessage(message, params);
 
-    AuthorizationSet hardware_auths;
-    for (auto& entry : key_characteristics_) {
-        if (entry.securityLevel != SecurityLevel::SOFTWARE) {
-            auths.push_back(AuthorizationSet(entry.authorizations));
-        }
-    }
     if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
         // Usage count limit tag is enforced by hardware. After using the key, the key blob
         // must be invalidated from secure storage (such as RPMB partition).
         EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params));
     } else {
-        // Usage count limit tag is enforced by software, keymint does nothing.
+        // Usage count limit tag is enforced by keystore, keymint does nothing.
+        EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     }
 }
 
 /*
- * UsageCountLimitTest.TestLimitRsa
+ * UsageCountLimitTest.TestLimitedUseAes
  *
- * Verifies that the usage count limit tag works correctly with RSA keys.
+ * Verifies that the usage count limit tag > 1 works correctly with AES keys.
  */
-TEST_P(UsageCountLimitTest, TestLimitRsa) {
+TEST_P(UsageCountLimitTest, TestLimitedUseAes) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .EcbMode()
+                                                 .Padding(PaddingMode::NONE)
+                                                 .Authorization(TAG_USAGE_COUNT_LIMIT, 3)));
+
+    // Check the usage count limit tag appears in the authorizations.
+    AuthorizationSet auths;
+    for (auto& entry : key_characteristics_) {
+        auths.push_back(AuthorizationSet(entry.authorizations));
+    }
+    EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U))
+            << "key usage count limit " << 3U << " missing";
+
+    string message = "1234567890123456";
+    auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE);
+
+    AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+    AuthorizationSet keystore_auths =
+            SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE);
+
+    EncryptMessage(message, params);
+    EncryptMessage(message, params);
+    EncryptMessage(message, params);
+
+    if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) {
+        // Usage count limit tag is enforced by hardware. After using the key, the key blob
+        // must be invalidated from secure storage (such as RPMB partition).
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params));
+    } else {
+        // Usage count limit tag is enforced by keystore, keymint does nothing.
+        EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+    }
+}
+
+/*
+ * UsageCountLimitTest.TestSingleUseRsa
+ *
+ * Verifies that the usage count limit tag = 1 works correctly with RSA keys.
+ */
+TEST_P(UsageCountLimitTest, TestSingleUseRsa) {
     if (SecLevel() == SecurityLevel::STRONGBOX) return;
 
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -4366,22 +4465,64 @@
     string message = "1234567890123456";
     auto params = AuthorizationSetBuilder().NoDigestOrPadding();
 
+    AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+    AuthorizationSet keystore_auths =
+            SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE);
+
     // First usage of RSA key should work.
     SignMessage(message, params);
 
-    AuthorizationSet hardware_auths;
-    for (auto& entry : key_characteristics_) {
-        if (entry.securityLevel != SecurityLevel::SOFTWARE) {
-            auths.push_back(AuthorizationSet(entry.authorizations));
-        }
-    }
-
     if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
         // Usage count limit tag is enforced by hardware. After using the key, the key blob
         // must be invalidated from secure storage (such as RPMB partition).
         EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params));
     } else {
-        // Usage count limit tag is enforced by software, keymint does nothing.
+        // Usage count limit tag is enforced by keystore, keymint does nothing.
+        EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
+        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+    }
+}
+
+/*
+ * UsageCountLimitTest.TestLimitUseRsa
+ *
+ * Verifies that the usage count limit tag > 1 works correctly with RSA keys.
+ */
+TEST_P(UsageCountLimitTest, TestLimitUseRsa) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .RsaSigningKey(1024, 65537)
+                                                 .NoDigestOrPadding()
+                                                 .Authorization(TAG_USAGE_COUNT_LIMIT, 3)));
+
+    // Check the usage count limit tag appears in the authorizations.
+    AuthorizationSet auths;
+    for (auto& entry : key_characteristics_) {
+        auths.push_back(AuthorizationSet(entry.authorizations));
+    }
+    EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U))
+            << "key usage count limit " << 3U << " missing";
+
+    string message = "1234567890123456";
+    auto params = AuthorizationSetBuilder().NoDigestOrPadding();
+
+    AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+    AuthorizationSet keystore_auths =
+            SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE);
+
+    SignMessage(message, params);
+    SignMessage(message, params);
+    SignMessage(message, params);
+
+    if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) {
+        // Usage count limit tag is enforced by hardware. After using the key, the key blob
+        // must be invalidated from secure storage (such as RPMB partition).
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params));
+    } else {
+        // Usage count limit tag is enforced by keystore, keymint does nothing.
+        EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
     }
 }
diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp
index 596b097..a48f770 100644
--- a/security/keymint/support/attestation_record.cpp
+++ b/security/keymint/support/attestation_record.cpp
@@ -97,6 +97,7 @@
     ASN1_NULL* device_unique_attestation;
     ASN1_NULL* storage_key;
     ASN1_NULL* identity_credential;
+    ASN1_INTEGER* usage_count_limit;
 } KM_AUTH_LIST;
 
 ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -143,7 +144,8 @@
         ASN1_EXP_OPT(KM_AUTH_LIST, storage_key, ASN1_NULL, TAG_STORAGE_KEY.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL,
                      TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()),
-
+        ASN1_EXP_OPT(KM_AUTH_LIST, usage_count_limit, ASN1_INTEGER,
+                     TAG_USAGE_COUNT_LIMIT.maskedTag()),
 } ASN1_SEQUENCE_END(KM_AUTH_LIST);
 IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
 
@@ -285,6 +287,7 @@
     copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list);
     copyAuthTag(record->storage_key, TAG_STORAGE_KEY, auth_list);
     copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list);
+    copyAuthTag(record->usage_count_limit, TAG_USAGE_COUNT_LIMIT, auth_list);
 
     return ErrorCode::OK;
 }