Generate nonce if caller doesn't provide one.
If the key has KM_TAG_CALLER_NONCE, then the caller is allowed to
provide a nonce. Previously the assumption was that the caller was
_required_ to provide a nonce. But to play nicer with the Java crypto
API, it's better to make the caller nonce optional if
KM_TAG_CALLER_NONCE is true.
Bug: 19919504
Change-Id: I6189e19017b9026b955f529c7267913de8b04a74
diff --git a/google_keymaster_test.cpp b/google_keymaster_test.cpp
index 6b0c861..45f6f29 100644
--- a/google_keymaster_test.cpp
+++ b/google_keymaster_test.cpp
@@ -1492,6 +1492,42 @@
EXPECT_EQ(message, plaintext);
}
+TEST_F(EncryptionOperationsTest, AesCallerNonce) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .AesEncryptionKey(128)
+ .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+ .Authorization(TAG_CALLER_NONCE)));
+ string message = "12345678901234567890123456789012";
+ string iv1;
+ // Don't specify nonce, should get a random one.
+ string ciphertext1 = EncryptMessage(message, &iv1);
+ EXPECT_EQ(message.size(), ciphertext1.size());
+ EXPECT_EQ(16U, iv1.size());
+
+ string plaintext = DecryptMessage(ciphertext1, iv1);
+ EXPECT_EQ(message, plaintext);
+
+ // Now specify a nonce, should also work.
+ AuthorizationSet input_params;
+ AuthorizationSet update_params;
+ AuthorizationSet output_params;
+ input_params.push_back(TAG_NONCE, "abcdefghijklmnop", 16);
+ string ciphertext2 =
+ ProcessMessage(KM_PURPOSE_ENCRYPT, message, input_params, update_params, &output_params);
+
+ // Decrypt with correct nonce.
+ plaintext = ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext2, input_params, update_params,
+ &output_params);
+ EXPECT_EQ(message, plaintext);
+
+ // Now try with wrong nonce.
+ input_params.Clear();
+ input_params.push_back(TAG_NONCE, "aaaaaaaaaaaaaaaa", 16);
+ plaintext = ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext2, input_params, update_params,
+ &output_params);
+ EXPECT_NE(message, plaintext);
+}
+
TEST_F(EncryptionOperationsTest, AesCbcIncrementalNoPadding) {
ASSERT_EQ(KM_ERROR_OK,
GenerateKey(AuthorizationSetBuilder().AesEncryptionKey(128).Authorization(