Add more tests for limited use key feature.
Verify that when keymint implementation supports rollback resistance,
it must also enforce the single use key in hardware by secure hardware.
Test: atest -c VtsAidlKeyMintTargetTest
Change-Id: Ib984003247906ded7266da620e2d82e826d916bc
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 88122ce..4a48f57 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -4596,6 +4596,57 @@
}
}
+/*
+ * UsageCountLimitTest.TestSingleUseKeyAndRollbackResistance
+ *
+ * Verifies that when rollback resistance is supported by the KeyMint implementation with
+ * the secure hardware, the single use key with usage count limit tag = 1 must also be enforced
+ * in hardware.
+ */
+TEST_P(UsageCountLimitTest, TestSingleUseKeyAndRollbackResistance) {
+ if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+ auto error = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
+ ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
+
+ if (error == ErrorCode::OK) {
+ // Rollback resistance is supported by KeyMint, verify it is enforced in hardware.
+ AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
+ ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
+ ASSERT_EQ(ErrorCode::OK, DeleteKey());
+
+ // The KeyMint should also enforce single use key in hardware when it supports rollback
+ // resistance.
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaSigningKey(1024, 65537)
+ .NoDigestOrPadding()
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
+ .SetDefaultValidity()));
+
+ // Check the usage count limit tag appears in the hardware authorizations.
+ AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_);
+ EXPECT_TRUE(hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ string message = "1234567890123456";
+ auto params = AuthorizationSetBuilder().NoDigestOrPadding();
+
+ // First usage of RSA key should work.
+ SignMessage(message, params);
+
+ // 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));
+ }
+}
+
INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest);
typedef KeyMintAidlTestBase AddEntropyTest;
@@ -4645,7 +4696,8 @@
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_ROLLBACK_RESISTANCE));
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
@@ -4678,7 +4730,8 @@
.Digest(Digest::NONE)
.Padding(PaddingMode::NONE)
.Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_ROLLBACK_RESISTANCE));
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .SetDefaultValidity());
ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented