Add RSA verification.

Change-Id: Ie9ac37dba7ead62b0ca17054bbf6d2744cea5946
diff --git a/google_keymaster_test.cpp b/google_keymaster_test.cpp
index 4c8c28e..cb9c32e 100644
--- a/google_keymaster_test.cpp
+++ b/google_keymaster_test.cpp
@@ -277,9 +277,9 @@
         };
         GenerateKeyRequest generate_request;
         generate_request.key_description.Reinitialize(params, array_length(params));
-        if (digest != -1)
+        if (static_cast<int>(digest) != -1)
             generate_request.key_description.push_back(TAG_DIGEST, digest);
-        if (padding != -1)
+        if (static_cast<int>(padding) != -1)
             generate_request.key_description.push_back(TAG_PADDING, padding);
         device.GenerateKey(generate_request, &generate_response_);
         EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
@@ -316,11 +316,12 @@
     ASSERT_EQ(KM_ERROR_OK, update_response.error);
     EXPECT_EQ(0U, update_response.output.available_read());
 
+    FinishOperationRequest finish_request;
+    finish_request.op_handle = begin_response.op_handle;
     FinishOperationResponse finish_response;
-    device.FinishOperation(begin_response.op_handle, &finish_response);
+    device.FinishOperation(finish_request, &finish_response);
     ASSERT_EQ(KM_ERROR_OK, finish_response.error);
-    EXPECT_GT(finish_response.signature.available_read(), 0U);
-    EXPECT_EQ(0U, finish_response.output.available_read());
+    EXPECT_GT(finish_response.output.available_read(), 0U);
 
     EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
 }
@@ -433,10 +434,117 @@
     ASSERT_EQ(KM_ERROR_OK, update_response.error);
     EXPECT_EQ(0U, update_response.output.available_read());
 
+    FinishOperationRequest finish_request;
+    finish_request.op_handle = begin_response.op_handle;
     FinishOperationResponse finish_response;
-    device.FinishOperation(begin_response.op_handle, &finish_response);
+    device.FinishOperation(finish_request, &finish_response);
     ASSERT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, finish_response.error);
-    EXPECT_EQ(0U, finish_response.signature.available_read());
+    EXPECT_EQ(0U, finish_response.output.available_read());
+
+    EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
+}
+
+class VerificationOperationsTest : public KeymasterTest {
+  protected:
+    VerificationOperationsTest() {
+        generate_response_.error = KM_ERROR_UNKNOWN_ERROR;
+        finish_response_.error = KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    void GenerateKey(keymaster_digest_t digest, keymaster_padding_t padding,
+                                      uint32_t key_size) {
+        keymaster_key_param_t params[] = {
+            Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+            Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+            Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
+            Authorization(TAG_KEY_SIZE, key_size),
+            Authorization(TAG_USER_ID, 7),
+            Authorization(TAG_USER_AUTH_ID, 8),
+            Authorization(TAG_APPLICATION_ID, "app_id", 6),
+            Authorization(TAG_AUTH_TIMEOUT, 300),
+        };
+        GenerateKeyRequest generate_request;
+        generate_request.key_description.Reinitialize(params, array_length(params));
+        if (static_cast<int>(digest) != -1)
+            generate_request.key_description.push_back(TAG_DIGEST, digest);
+        if (static_cast<int>(padding) != -1)
+            generate_request.key_description.push_back(TAG_PADDING, padding);
+        device.GenerateKey(generate_request, &generate_response_);
+        EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
+
+        BeginOperationRequest begin_request;
+        BeginOperationResponse begin_response;
+        begin_request.key_blob = generate_response_.key_blob;
+        begin_request.purpose = KM_PURPOSE_SIGN;
+        begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
+
+        device.BeginOperation(begin_request, &begin_response);
+        ASSERT_EQ(KM_ERROR_OK, begin_response.error);
+
+        UpdateOperationRequest update_request;
+        UpdateOperationResponse update_response;
+        update_request.op_handle = begin_response.op_handle;
+        update_request.input.Reinitialize("012345678901234567890123456789012", 32);
+        EXPECT_EQ(32U, update_request.input.available_read());
+
+        device.UpdateOperation(update_request, &update_response);
+        ASSERT_EQ(KM_ERROR_OK, update_response.error);
+        EXPECT_EQ(0U, update_response.output.available_read());
+
+        FinishOperationRequest finish_request;
+        finish_request.op_handle = begin_response.op_handle;
+        device.FinishOperation(finish_request, &finish_response_);
+        ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
+        EXPECT_GT(finish_response_.output.available_read(), 0U);
+    }
+
+    keymaster_key_blob_t* key_blob() {
+        if (generate_response_.error == KM_ERROR_OK)
+            return &generate_response_.key_blob;
+        return NULL;
+    }
+
+    Buffer* signature() {
+        if (finish_response_.error == KM_ERROR_OK)
+            return &finish_response_.output;
+        return NULL;
+    }
+
+  private:
+    GenerateKeyResponse generate_response_;
+    FinishOperationResponse finish_response_;
+};
+
+TEST_F(VerificationOperationsTest, RsaSuccess) {
+    GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
+    ASSERT_TRUE(key_blob() != NULL);
+    ASSERT_TRUE(signature() != NULL);
+
+    BeginOperationRequest begin_request;
+    BeginOperationResponse begin_response;
+    begin_request.key_blob = *key_blob();
+    begin_request.purpose = KM_PURPOSE_VERIFY;
+    begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
+
+    device.BeginOperation(begin_request, &begin_response);
+    ASSERT_EQ(KM_ERROR_OK, begin_response.error);
+
+    UpdateOperationRequest update_request;
+    UpdateOperationResponse update_response;
+    update_request.op_handle = begin_response.op_handle;
+    update_request.input.Reinitialize("012345678901234567890123456789012", 32);
+    EXPECT_EQ(32U, update_request.input.available_read());
+
+    device.UpdateOperation(update_request, &update_response);
+    ASSERT_EQ(KM_ERROR_OK, update_response.error);
+    EXPECT_EQ(0U, update_response.output.available_read());
+
+    FinishOperationRequest finish_request;
+    finish_request.op_handle = begin_response.op_handle;
+    finish_request.signature.Reinitialize(*signature());
+    FinishOperationResponse finish_response;
+    device.FinishOperation(finish_request, &finish_response);
+    ASSERT_EQ(KM_ERROR_OK, finish_response.error);
     EXPECT_EQ(0U, finish_response.output.available_read());
 
     EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));