regression: add tests for the supplicant plugin framework

Add test cases for checking functionality of supplicant plugins:
 - Ability to pass values and arrays to/from a plugin
 - Right handle situations with bad input parameters
 - Right handle situations with calling an unknown plugin

Signed-off-by: Aleksandr Anisimov <a.anisimov@omprussia.ru>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/host/xtest/CMakeLists.txt b/host/xtest/CMakeLists.txt
index b77b2fb..461d387 100644
--- a/host/xtest/CMakeLists.txt
+++ b/host/xtest/CMakeLists.txt
@@ -115,6 +115,7 @@
 
 target_include_directories(${PROJECT_NAME}
 	PRIVATE .
+	PRIVATE ../supp_plugin/include
 	PRIVATE adbg/include
 	PRIVATE ${OPTEE_TEST_SDK}/host_include
 	PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/host/xtest/Makefile b/host/xtest/Makefile
index 3ca8a28..297cd12 100644
--- a/host/xtest/Makefile
+++ b/host/xtest/Makefile
@@ -104,6 +104,7 @@
 
 CFLAGS += -I./
 CFLAGS += -I./adbg/include
+CFLAGS += -I../supp_plugin/include
 CFLAGS += -I$(out-dir)/xtest
 
 CFLAGS += -I$(OPTEE_CLIENT_EXPORT)/include
@@ -126,6 +127,7 @@
 CFLAGS += -I../../ta/socket/include
 CFLAGS += -I../../ta/sdp_basic/include
 CFLAGS += -I../../ta/tpm_log_test/include
+CFLAGS += -I../../ta/supp_plugin/include
 
 TA_DIR ?= /lib/optee_armtz
 CFLAGS += -DTA_DIR=\"$(TA_DIR)\"
diff --git a/host/xtest/regression_1000.c b/host/xtest/regression_1000.c
index 5e3c773..a819838 100644
--- a/host/xtest/regression_1000.c
+++ b/host/xtest/regression_1000.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2014, STMicroelectronics International N.V.
  */
 
+#include <errno.h>
 #include <limits.h>
 #include <pthread.h>
 #include <stdio.h>
@@ -29,9 +30,12 @@
 #include <ta_sims_keepalive_test.h>
 #include <ta_concurrent.h>
 #include <ta_tpm_log_test.h>
+#include <ta_supp_plugin.h>
 #include <sdp_basic.h>
 #include <pta_secstor_ta_mgmt.h>
 
+#include <test_supp_plugin.h>
+
 #ifndef MIN
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
@@ -2345,3 +2349,139 @@
 }
 ADBG_CASE_DEFINE(regression, 1032, xtest_tee_test_1032,
 		"Register read-only shared memory");
+
+static void xtest_tee_test_1033(ADBG_Case_t *c)
+{
+	TEEC_Session session = { };
+	uint32_t ret_orig = 0;
+
+	/* TA will ping the test plugin during open session operation */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		xtest_teec_open_session(&session, &supp_plugin_test_ta_uuid,
+					NULL, &ret_orig)))
+		return;
+
+	Do_ADBG_BeginSubCase(c, "Pass values to/from a plugin");
+	{
+		TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+
+		op.params[0].value.a = 20;
+		op.params[0].value.b = 10;
+		op.params[1].value.a = '+';
+		op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,
+						 TEEC_VALUE_INPUT, TEEC_NONE,
+						 TEEC_NONE);
+
+		ADBG_EXPECT_TEEC_SUCCESS(c,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_PASS_VALUES, &op,
+					   &ret_orig));
+		ADBG_EXPECT(c, 30, op.params[0].value.a);
+
+		/* reassign, because the values was changed during previous op */
+		op.params[0].value.a = 20;
+		op.params[0].value.b = 10;
+		op.params[1].value.a = '-';
+		ADBG_EXPECT_TEEC_SUCCESS(c,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_PASS_VALUES, &op,
+					   &ret_orig));
+		ADBG_EXPECT(c, 10, op.params[0].value.a);
+	}
+	Do_ADBG_EndSubCase(c, "Pass values to/from a plugin");
+
+	Do_ADBG_BeginSubCase(c, "Pass array to a plugin");
+	{
+		TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+		char to_plugin[] = "Plugin must write this array to the test file";
+		char from_file[sizeof(to_plugin)] = { };
+		char test_fname[PATH_MAX] = { };
+		FILE *fp = NULL;
+
+		op.params[0].tmpref.buffer = to_plugin;
+		op.params[0].tmpref.size = sizeof(to_plugin);
+		op.params[1].tmpref.buffer = test_fname;
+		op.params[1].tmpref.size = PATH_MAX;
+		op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
+						 TEEC_MEMREF_TEMP_OUTPUT,
+						 TEEC_NONE, TEEC_NONE);
+
+		ADBG_EXPECT_TEEC_SUCCESS(c,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_WRITE_ARR,
+					   &op, &ret_orig));
+
+		/*
+		 * Test file is generated by the plugin with the help of
+		 * mkstemp(). Check the file content here.
+		 */
+		fp = fopen(test_fname, "r");
+		ADBG_EXPECT_NOT_NULL(c, fp);
+		if (fp) {
+			fread(from_file, sizeof(char), sizeof(to_plugin), fp);
+			ADBG_EXPECT_EQUAL(c, to_plugin, from_file, sizeof(to_plugin));
+			fclose(fp);
+			remove(test_fname);
+		}
+	}
+	Do_ADBG_EndSubCase(c, "Pass array to a plugin");
+
+	Do_ADBG_BeginSubCase(c, "Get array from a plugin");
+	{
+		TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+		char from_plugin[64] = { };
+		char expected_arr[] = "Array from plugin";
+		size_t expectes_size = sizeof(expected_arr);
+
+		op.params[0].tmpref.buffer = from_plugin;
+		op.params[0].tmpref.size = sizeof(from_plugin);
+		op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
+						 TEEC_VALUE_OUTPUT, TEEC_NONE,
+						 TEEC_NONE);
+		ADBG_EXPECT_TEEC_SUCCESS(c,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_GET_ARR, &op,
+					   &ret_orig));
+		ADBG_EXPECT(c, expectes_size, op.params[1].value.a);
+		ADBG_EXPECT_EQUAL(c, expected_arr, from_plugin, expectes_size);
+	}
+	Do_ADBG_EndSubCase(c, "Get array from a plugin");
+
+	Do_ADBG_BeginSubCase(c, "Not allow bad input to a plugin");
+	{
+		TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+
+		op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
+						 TEEC_NONE, TEEC_NONE);
+		ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_BAD_UUID, &op,
+					   &ret_orig));
+		ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_BAD_IN_DATA, &op,
+					   &ret_orig));
+		ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_BAD_PARAMETERS,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_BAD_IN_LEN, &op,
+					   &ret_orig));
+	}
+	Do_ADBG_EndSubCase(c, "Not allow bad input to a plugin");
+
+	Do_ADBG_BeginSubCase(c, "Call an unknown plugin");
+	{
+		TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+
+		op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
+						 TEEC_NONE, TEEC_NONE);	
+		ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
+			TEEC_InvokeCommand(&session,
+					   TA_SUPP_PLUGIN_CMD_UNKNOWN_UUID,
+					   &op, &ret_orig));
+	}
+	Do_ADBG_EndSubCase(c, "Call an unknown plugin");
+
+	TEEC_CloseSession(&session);
+}
+ADBG_CASE_DEFINE(regression, 1033, xtest_tee_test_1033,
+		 "Test the supplicant plugin framework");
diff --git a/host/xtest/xtest_test.c b/host/xtest/xtest_test.c
index d13e96d..b812057 100644
--- a/host/xtest/xtest_test.c
+++ b/host/xtest/xtest_test.c
@@ -20,6 +20,7 @@
 #include <ta_storage_benchmark.h>
 #include <ta_socket.h>
 #include <ta_tpm_log_test.h>
+#include <ta_supp_plugin.h>
 #include <tee_api_defines.h>
 #include <__tee_isocket_defines.h>
 #include <__tee_tcpsocket_defines.h>
@@ -196,3 +197,4 @@
 const TEEC_UUID socket_ta_uuid = TA_SOCKET_UUID;
 const TEEC_UUID sdp_basic_ta_uuid = TA_SDP_BASIC_UUID;
 const TEEC_UUID tpm_log_test_ta_uuid = TA_TPM_LOG_TEST_UUID;
+const TEEC_UUID supp_plugin_test_ta_uuid = TA_SUPP_PLUGIN_UUID;
diff --git a/host/xtest/xtest_test.h b/host/xtest/xtest_test.h
index aed4ca0..892c7f7 100644
--- a/host/xtest/xtest_test.h
+++ b/host/xtest/xtest_test.h
@@ -133,6 +133,7 @@
 extern const TEEC_UUID socket_ta_uuid;
 extern const TEEC_UUID sdp_basic_ta_uuid;
 extern const TEEC_UUID tpm_log_test_ta_uuid;
+extern const TEEC_UUID supp_plugin_test_ta_uuid;
 extern char *xtest_tee_name;
 
 #endif /*XTEST_TEST_H*/