Allow decryption operations to use caller nonce/IV.

Bug: 22069548
Change-Id: Ie40d877ee1f5551d18a37cb3281ccb953744c016
diff --git a/keymaster_enforcement.cpp b/keymaster_enforcement.cpp
index 2401a34..aac5d12 100644
--- a/keymaster_enforcement.cpp
+++ b/keymaster_enforcement.cpp
@@ -106,7 +106,7 @@
     uint32_t min_ops_timeout = UINT32_MAX;
 
     bool update_access_count = false;
-    bool found_caller_nonce = false;
+    bool caller_nonce_authorized_by_key = false;
     bool authentication_required = false;
     bool auth_token_matched = false;
 
@@ -161,7 +161,7 @@
             break;
 
         case KM_TAG_CALLER_NONCE:
-            found_caller_nonce = true;
+            caller_nonce_authorized_by_key = true;
             break;
 
         /* Tags should never be in key auths. */
@@ -217,7 +217,8 @@
         return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
     }
 
-    if (!found_caller_nonce && operation_params.find(KM_TAG_NONCE) != -1)
+    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
+        operation_params.find(KM_TAG_NONCE) != -1)
         return KM_ERROR_CALLER_NONCE_PROHIBITED;
 
     if (min_ops_timeout != UINT32_MAX &&
diff --git a/keymaster_enforcement_test.cpp b/keymaster_enforcement_test.cpp
index b43bcc5..ef8ae16 100644
--- a/keymaster_enforcement_test.cpp
+++ b/keymaster_enforcement_test.cpp
@@ -420,19 +420,27 @@
 
 TEST_F(KeymasterBaseTest, TestInvalidCallerNonce) {
     AuthorizationSet no_caller_nonce(AuthorizationSetBuilder()
-                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
-                                         .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
+                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT)
+                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT)
+                                         .Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
     AuthorizationSet caller_nonce(AuthorizationSetBuilder()
-                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
-                                      .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT)
+                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT)
+                                      .Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
                                       .Authorization(TAG_CALLER_NONCE));
     AuthorizationSet begin_params(AuthorizationSetBuilder().Authorization(TAG_NONCE, "foo", 3));
 
     EXPECT_EQ(KM_ERROR_OK,
-              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, caller_nonce, begin_params,
+              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, caller_nonce, begin_params,
+                                      0 /* challenge */, false /* is_begin_operation */));
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, caller_nonce, begin_params,
                                       0 /* challenge */, false /* is_begin_operation */));
     EXPECT_EQ(KM_ERROR_CALLER_NONCE_PROHIBITED,
-              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, no_caller_nonce, begin_params,
+              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, no_caller_nonce, begin_params,
+                                      0 /* challenge */, false /* is_begin_operation */));
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, no_caller_nonce, begin_params,
                                       0 /* challenge */, false /* is_begin_operation */));
 }