Change KeyCharacteristics

Support key characteristics with three security levels, do not store
unenforced authorizations with keys or bind them to keys.

Bug: 163606833
Test: atest VtsAidlKeyMintTargetTest
Change-Id: Idbc523f16d8ef66ec38e0d503ad579a93c49e7b4
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 94bc199..93a216f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -17,6 +17,7 @@
 #include "KeyMintAidlTestBase.h"
 
 #include <chrono>
+#include <unordered_set>
 #include <vector>
 
 #include <android-base/logging.h>
@@ -43,6 +44,34 @@
 
 namespace test {
 
+namespace {
+
+// Predicate for testing basic characteristics validity in generation or import.
+bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel,
+                                      const vector<KeyCharacteristics>& key_characteristics) {
+    if (key_characteristics.empty()) return false;
+
+    std::unordered_set<SecurityLevel> levels_seen;
+    for (auto& entry : key_characteristics) {
+        if (entry.authorizations.empty()) return false;
+
+        if (levels_seen.find(entry.securityLevel) != levels_seen.end()) return false;
+        levels_seen.insert(entry.securityLevel);
+
+        // Generally, we should only have one entry, at the same security level as the KM
+        // instance.  There is an exception: StrongBox KM can have some authorizations that are
+        // enforced by the TEE.
+        bool isExpectedSecurityLevel = secLevel == entry.securityLevel ||
+                                       (secLevel == SecurityLevel::STRONGBOX &&
+                                        entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT);
+
+        if (!isExpectedSecurityLevel) return false;
+    }
+    return true;
+}
+
+}  // namespace
+
 ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) {
     if (result.isOk()) return ErrorCode::OK;
 
@@ -78,35 +107,30 @@
 }
 
 ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
-                                           vector<uint8_t>* keyBlob, KeyCharacteristics* keyChar) {
-    EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null.  Test bug";
-    EXPECT_NE(keyChar, nullptr)
+                                           vector<uint8_t>* key_blob,
+                                           vector<KeyCharacteristics>* key_characteristics) {
+    EXPECT_NE(key_blob, nullptr) << "Key blob pointer must not be null.  Test bug";
+    EXPECT_NE(key_characteristics, nullptr)
             << "Previous characteristics not deleted before generating key.  Test bug.";
 
     // Aidl does not clear these output parameters if the function returns
     // error.  This is different from hal where output parameter is always
     // cleared due to hal returning void.  So now we need to do our own clearing
     // of the output variables prior to calling keyMint aidl libraries.
-    keyBlob->clear();
-    keyChar->softwareEnforced.clear();
-    keyChar->hardwareEnforced.clear();
-    certChain_.clear();
+    key_blob->clear();
+    key_characteristics->clear();
+    cert_chain_.clear();
 
-    Status result;
-    ByteArray blob;
+    KeyCreationResult creationResult;
+    Status result = keymint_->generateKey(key_desc.vector_data(), &creationResult);
 
-    result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_);
-
-    // On result, blob & characteristics should be empty.
     if (result.isOk()) {
-        if (SecLevel() != SecurityLevel::SOFTWARE) {
-            EXPECT_GT(keyChar->hardwareEnforced.size(), 0);
-        }
-        EXPECT_GT(keyChar->softwareEnforced.size(), 0);
-        // TODO(seleneh) in a later version where we return @nullable
-        // single Certificate, check non-null single certificate is always
-        // non-empty.
-        *keyBlob = blob.data;
+        EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+                     creationResult.keyCharacteristics);
+        EXPECT_GT(creationResult.keyBlob.size(), 0);
+        *key_blob = std::move(creationResult.keyBlob);
+        *key_characteristics = std::move(creationResult.keyCharacteristics);
+        cert_chain_ = std::move(creationResult.certificateChain);
     }
 
     return GetReturnErrorCode(result);
@@ -118,25 +142,26 @@
 
 ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                                          const string& key_material, vector<uint8_t>* key_blob,
-                                         KeyCharacteristics* key_characteristics) {
+                                         vector<KeyCharacteristics>* key_characteristics) {
     Status result;
 
-    certChain_.clear();
-    key_characteristics->softwareEnforced.clear();
-    key_characteristics->hardwareEnforced.clear();
+    cert_chain_.clear();
+    key_characteristics->clear();
     key_blob->clear();
 
-    ByteArray blob;
+    KeyCreationResult creationResult;
     result = keymint_->importKey(key_desc.vector_data(), format,
-                                 vector<uint8_t>(key_material.begin(), key_material.end()), &blob,
-                                 key_characteristics, &certChain_);
+                                 vector<uint8_t>(key_material.begin(), key_material.end()),
+                                 &creationResult);
 
     if (result.isOk()) {
-        if (SecLevel() != SecurityLevel::SOFTWARE) {
-            EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
-        }
-        EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
-        *key_blob = blob.data;
+        EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+                     creationResult.keyCharacteristics);
+        EXPECT_GT(creationResult.keyBlob.size(), 0);
+
+        *key_blob = std::move(creationResult.keyBlob);
+        *key_characteristics = std::move(creationResult.keyCharacteristics);
+        cert_chain_ = std::move(creationResult.certificateChain);
     }
 
     return GetReturnErrorCode(result);
@@ -151,25 +176,25 @@
                                                 const AuthorizationSet& wrapping_key_desc,
                                                 string masking_key,
                                                 const AuthorizationSet& unwrapping_params) {
-    Status result;
     EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key));
 
-    ByteArray outBlob;
-    key_characteristics_.softwareEnforced.clear();
-    key_characteristics_.hardwareEnforced.clear();
+    key_characteristics_.clear();
 
-    result = keymint_->importWrappedKey(vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()),
-                                        key_blob_,
-                                        vector<uint8_t>(masking_key.begin(), masking_key.end()),
-                                        unwrapping_params.vector_data(), 0 /* passwordSid */,
-                                        0 /* biometricSid */, &outBlob, &key_characteristics_);
+    KeyCreationResult creationResult;
+    Status result = keymint_->importWrappedKey(
+            vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()), key_blob_,
+            vector<uint8_t>(masking_key.begin(), masking_key.end()),
+            unwrapping_params.vector_data(), 0 /* passwordSid */, 0 /* biometricSid */,
+            &creationResult);
 
     if (result.isOk()) {
-        key_blob_ = outBlob.data;
-        if (SecLevel() != SecurityLevel::SOFTWARE) {
-            EXPECT_GT(key_characteristics_.hardwareEnforced.size(), 0);
-        }
-        EXPECT_GT(key_characteristics_.softwareEnforced.size(), 0);
+        EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+                     creationResult.keyCharacteristics);
+        EXPECT_GT(creationResult.keyBlob.size(), 0);
+
+        key_blob_ = std::move(creationResult.keyBlob);
+        key_characteristics_ = std::move(creationResult.keyCharacteristics);
+        cert_chain_ = std::move(creationResult.certificateChain);
     }
 
     return GetReturnErrorCode(result);
@@ -754,6 +779,15 @@
     return {};
 }
 
+static const vector<KeyParameter> kEmptyAuthList{};
+
+const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations(
+        const vector<KeyCharacteristics>& key_characteristics) {
+    auto found = std::find_if(key_characteristics.begin(), key_characteristics.end(),
+                              [this](auto& entry) { return entry.securityLevel == SecLevel(); });
+    return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
+}
+
 }  // namespace test
 
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index f73c26d..f36c397 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -56,13 +56,13 @@
 
     ErrorCode GetReturnErrorCode(const Status& result);
     ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
-                          KeyCharacteristics* key_characteristics);
+                          vector<KeyCharacteristics>* key_characteristics);
 
     ErrorCode GenerateKey(const AuthorizationSet& key_desc);
 
     ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                         const string& key_material, vector<uint8_t>* key_blob,
-                        KeyCharacteristics* key_characteristics);
+                        vector<KeyCharacteristics>* key_characteristics);
     ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                         const string& key_material);
 
@@ -147,8 +147,8 @@
 
     std::pair<ErrorCode, vector<uint8_t>> UpgradeKey(const vector<uint8_t>& key_blob);
 
-    bool IsSecure() { return securityLevel_ != SecurityLevel::SOFTWARE; }
-    SecurityLevel SecLevel() { return securityLevel_; }
+    bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
+    SecurityLevel SecLevel() const { return securityLevel_; }
 
     vector<uint32_t> ValidKeySizes(Algorithm algorithm);
     vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
@@ -164,9 +164,15 @@
     }
 
     std::shared_ptr<IKeyMintOperation> op_;
-    vector<Certificate> certChain_;
+    vector<Certificate> cert_chain_;
     vector<uint8_t> key_blob_;
-    KeyCharacteristics key_characteristics_;
+    vector<KeyCharacteristics> key_characteristics_;
+
+    const vector<KeyParameter>& SecLevelAuthorizations(
+            const vector<KeyCharacteristics>& key_characteristics);
+    inline const vector<KeyParameter>& SecLevelAuthorizations() {
+        return SecLevelAuthorizations(key_characteristics_);
+    }
 
   private:
     std::shared_ptr<IKeyMintDevice> keymint_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index eeb7491..bd36b8e 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -56,18 +56,16 @@
 template <>
 struct std::equal_to<KeyCharacteristics> {
     bool operator()(const KeyCharacteristics& a, const KeyCharacteristics& b) const {
-        // This isn't very efficient. Oh, well.
-        AuthorizationSet a_sw(a.softwareEnforced);
-        AuthorizationSet b_sw(b.softwareEnforced);
-        AuthorizationSet a_tee(b.hardwareEnforced);
-        AuthorizationSet b_tee(b.hardwareEnforced);
+        if (a.securityLevel != b.securityLevel) return false;
 
-        a_sw.Sort();
-        b_sw.Sort();
-        a_tee.Sort();
-        b_tee.Sort();
+        // this isn't very efficient. Oh, well.
+        AuthorizationSet a_auths(a.authorizations);
+        AuthorizationSet b_auths(b.authorizations);
 
-        return ((a_sw == b_sw) && (a_tee == b_tee));
+        a_auths.Sort();
+        b_auths.Sort();
+
+        return a_auths == b_auths;
     }
 };
 
@@ -229,19 +227,20 @@
 
 class NewKeyGenerationTest : public KeyMintAidlTestBase {
   protected:
-    void CheckBaseParams(const KeyCharacteristics& keyCharacteristics) {
+    void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
         // TODO(swillden): Distinguish which params should be in which auth list.
 
-        AuthorizationSet auths(keyCharacteristics.hardwareEnforced);
-        auths.push_back(AuthorizationSet(keyCharacteristics.softwareEnforced));
+        AuthorizationSet auths;
+        for (auto& entry : keyCharacteristics) {
+            auths.push_back(AuthorizationSet(entry.authorizations));
+        }
 
         EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
 
-        // Verify that App ID, App data and ROT are NOT included.
+        // Verify that App data and ROT are NOT included.
         EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
-        EXPECT_FALSE(auths.Contains(TAG_APPLICATION_ID));
         EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA));
 
         // Check that some unexpected tags/values are NOT present.
@@ -249,15 +248,13 @@
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
         EXPECT_FALSE(auths.Contains(TAG_AUTH_TIMEOUT, 301U));
 
-        // Now check that unspecified, defaulted tags are correct.
-        EXPECT_TRUE(auths.Contains(TAG_CREATION_DATETIME));
+        auto os_ver = auths.GetTagValue(TAG_OS_VERSION);
+        ASSERT_TRUE(os_ver);
+        EXPECT_EQ(*os_ver, os_version());
 
-        EXPECT_TRUE(auths.Contains(TAG_OS_VERSION, os_version()))
-                << "OS version is " << os_version() << " key reported "
-                << auths.GetTagValue(TAG_OS_VERSION)->get();
-        EXPECT_TRUE(auths.Contains(TAG_OS_PATCHLEVEL, os_patch_level()))
-                << "OS patch level is " << os_patch_level() << " key reported "
-                << auths.GetTagValue(TAG_OS_PATCHLEVEL)->get();
+        auto os_pl = auths.GetTagValue(TAG_OS_PATCHLEVEL);
+        ASSERT_TRUE(os_pl);
+        EXPECT_EQ(*os_pl, os_patch_level());
     }
 };
 
@@ -270,7 +267,7 @@
 TEST_P(NewKeyGenerationTest, Rsa) {
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
         vector<uint8_t> key_blob;
-        KeyCharacteristics key_characteristics;
+        vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .RsaSigningKey(key_size, 65537)
                                                      .Digest(Digest::NONE)
@@ -280,12 +277,7 @@
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
 
-        AuthorizationSet crypto_params;
-        if (IsSecure()) {
-            crypto_params = key_characteristics.hardwareEnforced;
-        } else {
-            crypto_params = key_characteristics.softwareEnforced;
-        }
+        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))
@@ -304,7 +296,7 @@
 TEST_P(NewKeyGenerationTest, NoInvalidRsaSizes) {
     for (auto key_size : InvalidKeySizes(Algorithm::RSA)) {
         vector<uint8_t> key_blob;
-        KeyCharacteristics key_characteristics;
+        vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
                   GenerateKey(AuthorizationSetBuilder()
                                       .RsaSigningKey(key_size, 65537)
@@ -337,7 +329,7 @@
 TEST_P(NewKeyGenerationTest, Ecdsa) {
     for (auto key_size : ValidKeySizes(Algorithm::EC)) {
         vector<uint8_t> key_blob;
-        KeyCharacteristics key_characteristics;
+        vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK,
                   GenerateKey(
                           AuthorizationSetBuilder().EcdsaSigningKey(key_size).Digest(Digest::NONE),
@@ -345,12 +337,7 @@
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
 
-        AuthorizationSet crypto_params;
-        if (IsSecure()) {
-            crypto_params = key_characteristics.hardwareEnforced;
-        } else {
-            crypto_params = key_characteristics.softwareEnforced;
-        }
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
         EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
@@ -383,7 +370,7 @@
 TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) {
     for (auto key_size : InvalidKeySizes(Algorithm::EC)) {
         vector<uint8_t> key_blob;
-        KeyCharacteristics key_characteristics;
+        vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
                   GenerateKey(
                           AuthorizationSetBuilder().EcdsaSigningKey(key_size).Digest(Digest::NONE),
@@ -454,7 +441,7 @@
 TEST_P(NewKeyGenerationTest, Hmac) {
     for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
         vector<uint8_t> key_blob;
-        KeyCharacteristics key_characteristics;
+        vector<KeyCharacteristics> key_characteristics;
         constexpr size_t key_size = 128;
         ASSERT_EQ(ErrorCode::OK,
                   GenerateKey(
@@ -465,17 +452,10 @@
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
 
-        AuthorizationSet hardwareEnforced = key_characteristics.hardwareEnforced;
-        AuthorizationSet softwareEnforced = key_characteristics.softwareEnforced;
-        if (IsSecure()) {
-            EXPECT_TRUE(hardwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC));
-            EXPECT_TRUE(hardwareEnforced.Contains(TAG_KEY_SIZE, key_size))
-                    << "Key size " << key_size << "missing";
-        } else {
-            EXPECT_TRUE(softwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC));
-            EXPECT_TRUE(softwareEnforced.Contains(TAG_KEY_SIZE, key_size))
-                    << "Key size " << key_size << "missing";
-        }
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
 
         CheckedDeleteKey(&key_blob);
     }
@@ -600,7 +580,7 @@
 /*
  * SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData
  *
- * Verifies that using an RSA key requires the correct app ID/data.
+ * Verifies that using an RSA key requires the correct app data.
  */
 TEST_P(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1412,7 +1392,7 @@
     string key_material = "HelloThisIsAKey";
 
     vector<uint8_t> signing_key, verification_key;
-    KeyCharacteristics signing_key_chars, verification_key_chars;
+    vector<KeyCharacteristics> signing_key_chars, verification_key_chars;
     EXPECT_EQ(ErrorCode::OK,
               ImportKey(AuthorizationSetBuilder()
                                 .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1466,28 +1446,22 @@
     template <TagType tag_type, Tag tag, typename ValueT>
     void CheckCryptoParam(TypedTag<tag_type, tag> ttag, ValueT expected) {
         SCOPED_TRACE("CheckCryptoParam");
-        if (IsSecure()) {
-            EXPECT_TRUE(contains(key_characteristics_.hardwareEnforced, ttag, expected))
-                    << "Tag " << tag << " with value " << expected << " not found";
-            EXPECT_FALSE(contains(key_characteristics_.softwareEnforced, ttag))
-                    << "Tag " << tag << " found";
-        } else {
-            EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, ttag, expected))
-                    << "Tag " << tag << " with value " << expected << " not found";
-            EXPECT_FALSE(contains(key_characteristics_.hardwareEnforced, ttag))
-                    << "Tag " << tag << " found";
+        for (auto& entry : key_characteristics_) {
+            if (entry.securityLevel == SecLevel()) {
+                EXPECT_TRUE(contains(entry.authorizations, ttag, expected))
+                        << "Tag " << tag << " with value " << expected
+                        << " not found at security level" << entry.securityLevel;
+            } else {
+                EXPECT_FALSE(contains(entry.authorizations, ttag, expected))
+                        << "Tag " << tag << " found at security level " << entry.securityLevel;
+            }
         }
     }
 
     void CheckOrigin() {
         SCOPED_TRACE("CheckOrigin");
-        if (IsSecure()) {
-            EXPECT_TRUE(contains(key_characteristics_.hardwareEnforced, TAG_ORIGIN,
-                                 KeyOrigin::IMPORTED));
-        } else {
-            EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, TAG_ORIGIN,
-                                 KeyOrigin::IMPORTED));
-        }
+        // Origin isn't a crypto param, but it always lives with them.
+        return CheckCryptoParam(TAG_ORIGIN, KeyOrigin::IMPORTED);
     }
 };
 
@@ -3950,7 +3924,7 @@
 
     // Delete must work if rollback protection is implemented
     if (error == ErrorCode::OK) {
-        AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+        AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
         ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
 
         ASSERT_EQ(ErrorCode::OK, DeleteKey(true /* keep key blob */));
@@ -3983,8 +3957,8 @@
 
     // Delete must work if rollback protection is implemented
     if (error == ErrorCode::OK) {
-        AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
-        ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
+        AuthorizationSet enforced(SecLevelAuthorizations());
+        ASSERT_TRUE(enforced.Contains(TAG_ROLLBACK_RESISTANCE));
 
         // Delete the key we don't care about the result at this point.
         DeleteKey();
@@ -4019,7 +3993,7 @@
 
     // Delete must work if rollback protection is implemented
     if (error == ErrorCode::OK) {
-        AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+        AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
         ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
 
         ASSERT_EQ(ErrorCode::OK, DeleteAllKeys());