Allow any padding mode to be used with keys with KM_PAD_NONE.
Cherry-picked from internal.
Bug: 22229156
Change-Id: I5de66c3ed86244452e7776bff9523e35030713e9
diff --git a/aes_operation.cpp b/aes_operation.cpp
index 2325ad4..face408 100644
--- a/aes_operation.cpp
+++ b/aes_operation.cpp
@@ -37,6 +37,19 @@
static const size_t GCM_MAX_TAG_LENGTH = 16;
static const size_t GCM_MIN_TAG_LENGTH = 12;
+inline bool allows_padding(keymaster_block_mode_t block_mode) {
+ switch (block_mode) {
+ case KM_MODE_CTR:
+ case KM_MODE_GCM:
+ return false;
+ case KM_MODE_ECB:
+ case KM_MODE_CBC:
+ return true;
+ }
+ assert(false /* Can't get here */);
+ return false;
+}
+
Operation* AesOperationFactory::CreateOperation(const Key& key,
const AuthorizationSet& begin_params,
keymaster_error_t* error) {
@@ -77,17 +90,10 @@
}
keymaster_padding_t padding;
- if (!begin_params.GetTagValue(TAG_PADDING, &padding)) {
- LOG_E("%d padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
- *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
- } else if (!supported(padding)) {
- LOG_E("Padding mode %d not supported", padding);
- *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
- } else if (block_mode == KM_MODE_CTR && padding != KM_PAD_NONE) {
- LOG_E("CTR mode does not support padding", 0);
- *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
- } else if (!key.authorizations().Contains(TAG_PADDING, padding)) {
- LOG_E("Padding mode %d was specified, but not authorized by key", padding);
+ if (!GetAndValidatePadding(begin_params, key, &padding, error))
+ return nullptr;
+ if (!allows_padding(block_mode) && padding != KM_PAD_NONE) {
+ LOG_E("Mode does not support padding", 0);
*error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
}
diff --git a/android_keymaster_test.cpp b/android_keymaster_test.cpp
index 49cff6e..341183b 100644
--- a/android_keymaster_test.cpp
+++ b/android_keymaster_test.cpp
@@ -2115,6 +2115,24 @@
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
+TEST_P(EncryptionOperationsTest, AesEcbNoPaddingKeyWithPkcs7Padding) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .AesEncryptionKey(128)
+ .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+ .Authorization(TAG_PADDING, KM_PAD_NONE)));
+
+ // Try various message lengths; all should work.
+ for (size_t i = 0; i < 32; ++i) {
+ string message(i, 'a');
+ string ciphertext = EncryptMessage(message, KM_MODE_ECB, KM_PAD_PKCS7);
+ EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
+ string plaintext = DecryptMessage(ciphertext, KM_MODE_ECB, KM_PAD_PKCS7);
+ EXPECT_EQ(message, plaintext);
+ }
+
+ EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
TEST_P(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.AesEncryptionKey(128)