xtest: pkcs11 test through libckteec and the PKCS11 TA

Introduce pkcs11 tests for PKCS#11 services through the PKCS11 TA.

Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Victor Chong <victor.chong@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/Android.mk b/Android.mk
index 6d846cc..2b040d3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -24,6 +24,10 @@
 
 TA_DIR ?= /vendor/lib/optee_armtz
 
+ifeq ($(CFG_PKCS11_TA),y)
+LOCAL_SHARED_LIBRARIES += libckteec
+endif
+
 srcs := regression_1000.c
 
 ifeq ($(CFG_GP_SOCKETS),y)
@@ -62,6 +66,10 @@
 srcs += sdp_basic.c
 endif
 
+ifeq ($(CFG_PKCS11_TA),y)
+srcs += pkcs11_1000.c
+endif
+
 define my-embed-file
 $(TARGET_OUT_HEADERS)/$(1).h: $(LOCAL_PATH)/$(2)
 	@echo '  GEN     $$@'
@@ -108,6 +116,10 @@
 LOCAL_CFLAGS += -DTA_DIR=\"$(TA_DIR)\"
 endif
 
+ifeq ($(CFG_PKCS11_TA),y)
+LOCAL_CFLAGS += -DCFG_PKCS11_TA
+endif
+
 ## $(OPTEE_BIN) is the path of tee.bin like
 ## out/target/product/hikey/optee/arm-plat-hikey/core/tee.bin
 ## it will be generated after build the optee_os with target BUILD_OPTEE_OS
diff --git a/host/xtest/CMakeLists.txt b/host/xtest/CMakeLists.txt
index cc28c8e..e29b045 100644
--- a/host/xtest/CMakeLists.txt
+++ b/host/xtest/CMakeLists.txt
@@ -81,6 +81,10 @@
 	list (APPEND SRC sdp_basic.c)
 endif()
 
+if (CFG_PKCS11_TA)
+	list (APPEND SRC pkcs11_1000.c)
+endif()
+
 ################################################################################
 # Built binary
 ################################################################################
@@ -102,6 +106,7 @@
 	PRIVATE teec
 	PRIVATE m
 	PRIVATE ${OPENSSL_PRIVATE_LINK}
+	PRIVATE ckteec
 )
 
 ################################################################################
diff --git a/host/xtest/Makefile b/host/xtest/Makefile
index 7b3de36..ff77b18 100644
--- a/host/xtest/Makefile
+++ b/host/xtest/Makefile
@@ -87,6 +87,15 @@
 srcs += sdp_basic.c
 endif
 
+ifeq ($(CFG_PKCS11_TA),y)
+srcs += pkcs11_1000.c
+
+OPTEE_PKCS11_TA_HEADERS ?= ../../../optee_client/libckteec/include
+CFLAGS += -DCFG_PKCS11_TA
+CFLAGS += -I$(OPTEE_PKCS11_TA_HEADERS)
+LDFLAGS += -L$(OPTEE_CLIENT_EXPORT)/lib -lckteec
+endif
+
 ifdef CFG_GP_PACKAGE_PATH
 CFLAGS += -DWITH_GP_TESTS
 
diff --git a/host/xtest/pkcs11_1000.c b/host/xtest/pkcs11_1000.c
new file mode 100644
index 0000000..d2805e0
--- /dev/null
+++ b/host/xtest/pkcs11_1000.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018, Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include <pkcs11.h>
+
+#include "xtest_test.h"
+#include "xtest_helpers.h"
+
+static void xtest_tee_test_1000(ADBG_Case_t *c)
+{
+	CK_RV rv;
+
+	rv = C_Initialize(NULL);
+	if (!ADBG_EXPECT_CK_OK(c, rv))
+		return;
+
+	rv = C_Finalize(NULL);
+	if (!ADBG_EXPECT_CK_OK(c, rv))
+		return;
+
+	rv = C_Initialize(NULL);
+	if (!ADBG_EXPECT_CK_OK(c, rv))
+		return;
+
+	rv = C_Initialize(NULL);
+	ADBG_EXPECT_CK_RESULT(c, CKR_CRYPTOKI_ALREADY_INITIALIZED, rv);
+
+	rv = C_Finalize(NULL);
+	ADBG_EXPECT_CK_OK(c, rv);
+}
+
+ADBG_CASE_DEFINE(pkcs11, 1000, xtest_tee_test_1000,
+		"Initialize and close Cryptoki library");
diff --git a/host/xtest/xtest_main.c b/host/xtest/xtest_main.c
index bd17ca4..2c7d439 100644
--- a/host/xtest/xtest_main.c
+++ b/host/xtest/xtest_main.c
@@ -40,17 +40,29 @@
 #ifdef WITH_GP_TESTS
 ADBG_SUITE_DEFINE(gp);
 #endif
+#ifdef CFG_PKCS11_TA
+ADBG_SUITE_DEFINE(pkcs11);
+#endif
 ADBG_SUITE_DEFINE(regression);
 
 char *_device = NULL;
 unsigned int level = 0;
 static const char glevel[] = "0";
+
 #ifdef WITH_GP_TESTS
-static char gsuitename[] = "regression+gp";
+#define GP_SUITE	"+gp"
 #else
-static char gsuitename[] = "regression";
+#define GP_SUITE	""
 #endif
 
+#ifdef CFG_PKCS11_TA
+#define PKCS11_SUITE	"+pkcs11"
+#else
+#define PKCS11_SUITE	""
+#endif
+
+static char gsuitename[] = "regression" GP_SUITE PKCS11_SUITE;
+
 void usage(char *program);
 
 void usage(char *program)
@@ -65,6 +77,9 @@
 #ifdef WITH_GP_TESTS
 	printf(" gp");
 #endif
+#ifdef CFG_PKCS11_TA
+	printf(" pkcs11");
+#endif
 	printf("\n");
 	printf("\t                   To run several suites, use multiple names\n");
 	printf("\t                   separated by a '+')\n");
@@ -184,6 +199,10 @@
 		else if (!strcmp(token, "gp"))
 			ret = Do_ADBG_AppendToSuite(&all, &ADBG_Suite_gp);
 #endif
+#ifdef CFG_PKCS11_TA
+		else if (!strcmp(token, "pkcs11"))
+			ret = Do_ADBG_AppendToSuite(&all, &ADBG_Suite_pkcs11);
+#endif
 		else {
 			fprintf(stderr, "Unkown test suite: %s\n", token);
 			ret = -1;
diff --git a/host/xtest/xtest_test.c b/host/xtest/xtest_test.c
index a106ed0..97fc55d 100644
--- a/host/xtest/xtest_test.c
+++ b/host/xtest/xtest_test.c
@@ -85,6 +85,106 @@
 ADBG_ENUM_TABLE_ENTRY(TEEC_ORIGIN_TRUSTED_APP)
 ADBG_ENUM_TABLE_DEFINE_END(TEEC_ErrorOrigin);
 
+#ifdef CFG_PKCS11_TA
+ADBG_ENUM_TABLE_DEFINE_BEGIN(CK_RV)
+ADBG_ENUM_TABLE_ENTRY(CKR_OK),
+ADBG_ENUM_TABLE_ENTRY(CKR_CANCEL),
+ADBG_ENUM_TABLE_ENTRY(CKR_HOST_MEMORY),
+ADBG_ENUM_TABLE_ENTRY(CKR_SLOT_ID_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_GENERAL_ERROR),
+ADBG_ENUM_TABLE_ENTRY(CKR_FUNCTION_FAILED),
+ADBG_ENUM_TABLE_ENTRY(CKR_ARGUMENTS_BAD),
+ADBG_ENUM_TABLE_ENTRY(CKR_NO_EVENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_NEED_TO_CREATE_THREADS),
+ADBG_ENUM_TABLE_ENTRY(CKR_CANT_LOCK),
+ADBG_ENUM_TABLE_ENTRY(CKR_ATTRIBUTE_READ_ONLY),
+ADBG_ENUM_TABLE_ENTRY(CKR_ATTRIBUTE_SENSITIVE),
+ADBG_ENUM_TABLE_ENTRY(CKR_ATTRIBUTE_TYPE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_ATTRIBUTE_VALUE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_ACTION_PROHIBITED),
+ADBG_ENUM_TABLE_ENTRY(CKR_DATA_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_DATA_LEN_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_DEVICE_ERROR),
+ADBG_ENUM_TABLE_ENTRY(CKR_DEVICE_MEMORY),
+ADBG_ENUM_TABLE_ENTRY(CKR_DEVICE_REMOVED),
+ADBG_ENUM_TABLE_ENTRY(CKR_ENCRYPTED_DATA_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_ENCRYPTED_DATA_LEN_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_FUNCTION_CANCELED),
+ADBG_ENUM_TABLE_ENTRY(CKR_FUNCTION_NOT_PARALLEL),
+ADBG_ENUM_TABLE_ENTRY(CKR_FUNCTION_NOT_SUPPORTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_HANDLE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_SIZE_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_TYPE_INCONSISTENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_NOT_NEEDED),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_CHANGED),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_NEEDED),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_INDIGESTIBLE),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_FUNCTION_NOT_PERMITTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_NOT_WRAPPABLE),
+ADBG_ENUM_TABLE_ENTRY(CKR_KEY_UNEXTRACTABLE),
+ADBG_ENUM_TABLE_ENTRY(CKR_MECHANISM_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_MECHANISM_PARAM_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_OBJECT_HANDLE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_OPERATION_ACTIVE),
+ADBG_ENUM_TABLE_ENTRY(CKR_OPERATION_NOT_INITIALIZED),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_INCORRECT),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_LEN_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_EXPIRED),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_LOCKED),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_CLOSED),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_COUNT),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_HANDLE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_PARALLEL_NOT_SUPPORTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_READ_ONLY),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_EXISTS),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_READ_ONLY_EXISTS),
+ADBG_ENUM_TABLE_ENTRY(CKR_SESSION_READ_WRITE_SO_EXISTS),
+ADBG_ENUM_TABLE_ENTRY(CKR_SIGNATURE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_SIGNATURE_LEN_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_TEMPLATE_INCOMPLETE),
+ADBG_ENUM_TABLE_ENTRY(CKR_TEMPLATE_INCONSISTENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_TOKEN_NOT_PRESENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_TOKEN_NOT_RECOGNIZED),
+ADBG_ENUM_TABLE_ENTRY(CKR_TOKEN_WRITE_PROTECTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_UNWRAPPING_KEY_HANDLE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_UNWRAPPING_KEY_SIZE_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_ALREADY_LOGGED_IN),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_NOT_LOGGED_IN),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_PIN_NOT_INITIALIZED),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_TYPE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_ANOTHER_ALREADY_LOGGED_IN),
+ADBG_ENUM_TABLE_ENTRY(CKR_USER_TOO_MANY_TYPES),
+ADBG_ENUM_TABLE_ENTRY(CKR_WRAPPED_KEY_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_WRAPPED_KEY_LEN_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_WRAPPING_KEY_HANDLE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_WRAPPING_KEY_SIZE_RANGE),
+ADBG_ENUM_TABLE_ENTRY(CKR_WRAPPING_KEY_TYPE_INCONSISTENT),
+ADBG_ENUM_TABLE_ENTRY(CKR_RANDOM_SEED_NOT_SUPPORTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_RANDOM_NO_RNG),
+ADBG_ENUM_TABLE_ENTRY(CKR_DOMAIN_PARAMS_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_CURVE_NOT_SUPPORTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_BUFFER_TOO_SMALL),
+ADBG_ENUM_TABLE_ENTRY(CKR_SAVED_STATE_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_INFORMATION_SENSITIVE),
+ADBG_ENUM_TABLE_ENTRY(CKR_STATE_UNSAVEABLE),
+ADBG_ENUM_TABLE_ENTRY(CKR_CRYPTOKI_NOT_INITIALIZED),
+ADBG_ENUM_TABLE_ENTRY(CKR_CRYPTOKI_ALREADY_INITIALIZED),
+ADBG_ENUM_TABLE_ENTRY(CKR_MUTEX_BAD),
+ADBG_ENUM_TABLE_ENTRY(CKR_MUTEX_NOT_LOCKED),
+ADBG_ENUM_TABLE_ENTRY(CKR_NEW_PIN_MODE),
+ADBG_ENUM_TABLE_ENTRY(CKR_NEXT_OTP),
+ADBG_ENUM_TABLE_ENTRY(CKR_EXCEEDED_MAX_ITERATIONS),
+ADBG_ENUM_TABLE_ENTRY(CKR_FIPS_SELF_TEST_FAILED),
+ADBG_ENUM_TABLE_ENTRY(CKR_LIBRARY_LOAD_FAILED),
+ADBG_ENUM_TABLE_ENTRY(CKR_PIN_TOO_WEAK),
+ADBG_ENUM_TABLE_ENTRY(CKR_PUBLIC_KEY_INVALID),
+ADBG_ENUM_TABLE_ENTRY(CKR_FUNCTION_REJECTED),
+ADBG_ENUM_TABLE_ENTRY(CKR_VENDOR_DEFINED)
+ADBG_ENUM_TABLE_DEFINE_END(CK_RV);
+#endif /*CFG_PKCS11_TA*/
+
 #define ECC_SELF_TEST_UUID \
 		{ 0xf34f4f3c, 0xab30, 0x4573,  \
 		{ 0x91, 0xBF, 0x3C, 0x57, 0x02, 0x4D, 0x51, 0x99 } }
diff --git a/host/xtest/xtest_test.h b/host/xtest/xtest_test.h
index df82bf3..df9aea0 100644
--- a/host/xtest/xtest_test.h
+++ b/host/xtest/xtest_test.h
@@ -17,10 +17,17 @@
 #include <adbg.h>
 #include <tee_client_api.h>
 
+#ifdef CFG_PKCS11_TA
+#include <pkcs11.h>
+#endif
+
 ADBG_SUITE_DECLARE(benchmark);
 #ifdef WITH_GP_TESTS
 ADBG_SUITE_DECLARE(gp);
 #endif
+#ifdef CFG_PKCS11_TA
+ADBG_SUITE_DECLARE(pkcs11);
+#endif
 ADBG_SUITE_DECLARE(regression);
 
 /* TEEC_Result */
@@ -38,6 +45,17 @@
 #define ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, exp, got) \
 	ADBG_EXPECT_ENUM(c, exp, got, ADBG_EnumTable_TEEC_ErrorOrigin)
 
+#ifdef CFG_PKCS11_TA
+/* CK_RV */
+ADBG_ENUM_TABLE_DECLARE(CK_RV);
+
+#define ADBG_EXPECT_CK_RESULT(c, exp, got) \
+	ADBG_EXPECT_ENUM(c, exp, got, ADBG_EnumTable_CK_RV)
+
+#define ADBG_EXPECT_CK_OK(c, got) \
+	ADBG_EXPECT_ENUM(c, CKR_OK, got, ADBG_EnumTable_CK_RV)
+#endif
+
 extern const char crypt_user_ta[];
 extern const unsigned int crypt_user_ta_size;