Test: Add positive test suite to IPC build config

This patch adds support for positive core test suite under IPC mode.
Auto signal generation still not implemented that's why
tfm_ss_core_test*_signal.h files are created manually.

Details:
 * enable CORE_TEST in ConfigCoreIPC.cmake
 * implement secure function calls using the PSA API in test services
   and in the test suite
 * define signals for test services
 * update partition manifest files for test services to enumerate the
   available secure functions

Change-Id: I7cbb0acaabbed7cd44650c6a2f9ff3c632e05500
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/ConfigCoreIPC.cmake b/ConfigCoreIPC.cmake
index 545fd49..b87a834 100644
--- a/ConfigCoreIPC.cmake
+++ b/ConfigCoreIPC.cmake
@@ -27,7 +27,7 @@
 #various project specific settings (e.g. what files to build, macro
 #definitions) based on these.
 set (REGRESSION False)
-set (CORE_TEST False)
+set (CORE_TEST True)
 set (CORE_IPC True)
 
 # TF-M isolation level: 1..3
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index c9b9fa2..df8f1e7 100755
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -21,7 +21,7 @@
 set(APP_DIR ${CMAKE_CURRENT_LIST_DIR})
 get_filename_component(TFM_ROOT_DIR ${APP_DIR}/.. ABSOLUTE)
 set(INTERFACE_DIR ${TFM_ROOT_DIR}/interface)
-set(TEST_INTERFACE_DIR ${TFM_ROOT_DIR}/test/interface)
+set(TEST_DIR ${TFM_ROOT_DIR}/test)
 
 #Include BL2 bootloader related functions
 set(MCUBOOT_DIR "${TFM_ROOT_DIR}/bl2/ext/mcuboot")
diff --git a/app/tfm_integ_test.c b/app/tfm_integ_test.c
index 63ec8f3..2d01809 100644
--- a/app/tfm_integ_test.c
+++ b/app/tfm_integ_test.c
@@ -42,16 +42,51 @@
                                                                    "generic!");\
         } \
     } while(0)
+
+#ifdef TFM_PSA_API
+static psa_status_t psa_test_common(uint32_t sid, uint32_t minor_version,
+                                    const psa_invec *in_vecs, size_t in_len,
+                                    psa_outvec *out_vecs, size_t out_len)
+{
+    psa_handle_t handle;
+    psa_status_t status;
+
+    handle = psa_connect(sid, minor_version);
+    if (handle <= 0) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    status = psa_call(handle, in_vecs, in_len, out_vecs, out_len);
+    if (status < 0) {
+        status = CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
+    }
+
+    psa_close(handle);
+    return status;
+}
+#endif /* TFM_PSA_API */
+
 /**
  * \brief secure_decrement_ns_lock_1
  *
  */
 void secure_decrement_ns_lock_1(void)
 {
+#ifndef TFM_PSA_API
     uint32_t testcase_id = CORE_TEST_ID_BLOCK;
     psa_invec in_vec = {&testcase_id, sizeof(testcase_id)};
 
     TRY_SFN(tfm_spm_core_test_sfn_veneer, &in_vec, 1, NULL, 0);
+#else
+    psa_status_t err;
+
+    err = psa_test_common(SPM_CORE_TEST_BLOCK_SID,
+                          SPM_CORE_TEST_BLOCK_MIN_VER,
+                          NULL, 0, NULL, 0);
+    if (err != PSA_SUCCESS) {
+        LOG_MSG("Secure call to sfn block failed, generic!");
+    }
+#endif
 }
 
 /**
@@ -60,10 +95,21 @@
  */
 void secure_decrement_ns_lock_2(void)
 {
+#ifndef TFM_PSA_API
     uint32_t testcase_id = CORE_TEST_ID_BLOCK;
     psa_invec in_vec = {&testcase_id, sizeof(testcase_id)};
 
     TRY_SFN(tfm_spm_core_test_sfn_veneer, &in_vec, 1, NULL, 0);
+#else
+    psa_status_t err;
+
+    err = psa_test_common(SPM_CORE_TEST_BLOCK_SID,
+                          SPM_CORE_TEST_BLOCK_MIN_VER,
+                          NULL, 0, NULL, 0);
+    if (err != PSA_SUCCESS) {
+        LOG_MSG("Secure call to sfn block failed, generic!");
+    }
+#endif
 }
 /**
  * \brief Test definition for the RTX - TFM integration tests
diff --git a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
index e632354..924de1f 100644
--- a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
+++ b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,5 +8,7 @@
 #define __TFM_SPM_SIGNAL_DEFS_H__
 
 #include "test/test_services/tfm_ipc_service/tfm_ipc_service_partition.h"
+#include "test/test_services/tfm_core_test/tfm_ss_core_test_signal.h"
+#include "test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h"
 
 #endif
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 12213a6..72da66f 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -41,6 +41,7 @@
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
 PARTITION_DECLARE(TFM_SP_CORE_TEST, 0
+    | SPM_PART_FLAG_IPC
     , "APPLICATION-ROT", 0x00000002, NORMAL);
 PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init);
 PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST, TFM_PERIPHERAL_FPGA_IO);
@@ -49,6 +50,7 @@
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST_2 ********/
 PARTITION_DECLARE(TFM_SP_CORE_TEST_2, 0
+    | SPM_PART_FLAG_IPC
     , "APPLICATION-ROT", 0x00000003, NORMAL);
 PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST_2, core_test_2_init);
 #endif /* TFM_PARTITION_TEST_CORE */
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index e953f2d..696724b 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -22,10 +22,27 @@
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
+{"SPM_CORE_TEST_INIT_SUCCESS_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_INIT_SUCCESS_SIGNAL, 0x00002100, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_DIRECT_RECURSION_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL, 0x00002101, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_MPU_ACCESS_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_MPU_ACCESS_SIGNAL, 0x00002102, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_MEMORY_PERMISSIONS_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_MEMORY_PERMISSIONS_SIGNAL, 0x00002103, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_SHARE_REDIRECTION_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_SHARE_REDIRECTION_SIGNAL, 0x00002104, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_SS_TO_SS_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_SS_TO_SS_SIGNAL, 0x00002105, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_SS_TO_SS_BUFFER_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL, 0x00002106, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_OUTVEC_WRITE_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL, 0x00002107, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_PERIPHERAL_ACCESS_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL, 0x00002108, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL, 0x00002109, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_SPM_REQUEST_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_SPM_REQUEST_SIGNAL, 0x0000210A, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_BLOCK_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_BLOCK_SIGNAL, 0x0000210B, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_NS_THREAD_SID", TFM_SP_CORE_TEST_ID, SPM_CORE_TEST_NS_THREAD_SIGNAL, 0x0000210C, true, 1, TFM_VERSION_POLICY_STRICT},
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST_2 ********/
+{"SPM_CORE_TEST_2_SLAVE_SERVICE_SID", TFM_SP_CORE_TEST_2_ID, SPM_CORE_TEST_2_SLAVE_SERVICE_SIGNAL, 0x00002200, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SID", TFM_SP_CORE_TEST_2_ID, SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL, 0x00002201, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID", TFM_SP_CORE_TEST_2_ID, SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL, 0x00002202, true, 1, TFM_VERSION_POLICY_STRICT},
+{"SPM_CORE_TEST_2_INVERT_SID", TFM_SP_CORE_TEST_2_ID, SPM_CORE_TEST_2_INVERT_SIGNAL, 0x00002203, true, 1, TFM_VERSION_POLICY_STRICT},
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
diff --git a/test/suites/core/non_secure/core_ns_positive_testsuite.c b/test/suites/core/non_secure/core_ns_positive_testsuite.c
index aaf86a8..320b8fb 100644
--- a/test/suites/core/non_secure/core_ns_positive_testsuite.c
+++ b/test/suites/core/non_secure/core_ns_positive_testsuite.c
@@ -7,9 +7,11 @@
 
 #include "core_ns_tests.h"
 #include "tfm_api.h"
-#include "tfm_veneers.h"
 #include "test/suites/core/non_secure/core_test_api.h"
 #include "test/test_services/tfm_core_test/core_test_defs.h"
+#ifndef TFM_PSA_API
+#include "tfm_veneers.h"
+#endif /* TFM_PSA_API */
 
 #include <stdio.h>
 #include <string.h>
@@ -22,17 +24,19 @@
     {fn, "TFM_CORE_TEST_"TOSTRING(number),\
      description, {0} }
 
+#ifndef TFM_PSA_API
+static void tfm_core_test_permissions(struct test_result_t *ret);
+static void tfm_core_test_mpu_access(struct test_result_t *ret);
+static void tfm_core_test_share_change(struct test_result_t *ret);
+static void tfm_core_test_get_caller_client_id(struct test_result_t *ret);
+#endif /* TFM_PSA_API */
 static void tfm_core_test_ns_thread(struct test_result_t *ret);
 static void tfm_core_test_check_init(struct test_result_t *ret);
 static void tfm_core_test_recursion(struct test_result_t *ret);
-static void tfm_core_test_permissions(struct test_result_t *ret);
-static void tfm_core_test_mpu_access(struct test_result_t *ret);
 static void tfm_core_test_buffer_check(struct test_result_t *ret);
 static void tfm_core_test_ss_to_ss(struct test_result_t *ret);
-static void tfm_core_test_share_change(struct test_result_t *ret);
 static void tfm_core_test_ss_to_ss_buffer(struct test_result_t *ret);
 static void tfm_core_test_peripheral_access(struct test_result_t *ret);
-static void tfm_core_test_get_caller_client_id(struct test_result_t *ret);
 static void tfm_core_test_spm_request(struct test_result_t *ret);
 static void tfm_core_test_iovec_sanitization(struct test_result_t *ret);
 static void tfm_core_test_outvec_write(struct test_result_t *ret);
@@ -44,27 +48,33 @@
     "Test the success of service init"),
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_RECURSION, tfm_core_test_recursion,
     "Test direct recursion of secure services (DEPRECATED)"),
+#ifndef TFM_PSA_API
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_MEMORY_PERMISSIONS,
     tfm_core_test_permissions,
     "Test secure service memory access permissions"),
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_MPU_ACCESS, tfm_core_test_mpu_access,
     "Test secure service MPU accesses"),
+#endif /* TFM_PSA_API */
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_BUFFER_CHECK, tfm_core_test_buffer_check,
     "Test secure service buffer accesses"),
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_SS_TO_SS, tfm_core_test_ss_to_ss,
     "Test secure service to service call"),
+#ifndef TFM_PSA_API
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_SHARE_REDIRECTION,
     tfm_core_test_share_change,
     "Test secure service share change request"),
+#endif /* TFM_PSA_API */
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_SS_TO_SS_BUFFER,
     tfm_core_test_ss_to_ss_buffer,
     "Test secure service to service call with buffer handling"),
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_PERIPHERAL_ACCESS,
     tfm_core_test_peripheral_access,
     "Test service peripheral access"),
+#ifndef TFM_PSA_API
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_GET_CALLER_CLIENT_ID,
     tfm_core_test_get_caller_client_id,
     "Test get caller client ID function"),
+#endif /* TFM_PSA_API */
 CORE_TEST_DESCRIPTION(CORE_TEST_ID_SPM_REQUEST,
     tfm_core_test_spm_request,
     "Test SPM request function"),
@@ -86,13 +96,42 @@
                   core_tests, list_size, p_test_suite);
 }
 
+#ifdef TFM_PSA_API
+static psa_status_t psa_test_common(uint32_t sid, uint32_t minor_version,
+                                    const psa_invec *in_vecs, size_t in_len,
+                                    psa_outvec *out_vecs, size_t out_len)
+{
+    psa_handle_t handle;
+    psa_status_t status;
+
+    handle = psa_connect(sid, minor_version);
+    if (handle <= 0) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    status = psa_call(handle, in_vecs, in_len, out_vecs, out_len);
+    if (status < 0) {
+        status = CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
+    }
+
+    psa_close(handle);
+    return status;
+}
+#endif /* TFM_PSA_API */
+
 static void tfm_core_test_ns_thread(struct test_result_t *ret)
 {
     int32_t err;
+#ifndef TFM_PSA_API
     int32_t test_case_id = CORE_TEST_ID_NS_THREAD;
     psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
 
     err = tfm_spm_core_test_sfn_veneer(in_vec, 1, NULL, 0);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_NS_THREAD_SID,
+                          SPM_CORE_TEST_NS_THREAD_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("Secure function call from thread mode should be successful");
@@ -105,11 +144,19 @@
 static void tfm_core_test_peripheral_access(struct test_result_t *ret)
 {
     int32_t err;
+
+#ifndef TFM_PSA_API
     int32_t test_case_id = CORE_TEST_ID_PERIPHERAL_ACCESS;
     psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
     struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
 
     err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_PERIPHERAL_ACCESS_SID,
+                          SPM_CORE_TEST_PERIPHERAL_ACCESS_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
+
     switch (err) {
     case CORE_TEST_ERRNO_SUCCESS:
         ret->val = TEST_PASSED;
@@ -153,17 +200,27 @@
                                    {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
     psa_outvec out_vec[PSA_MAX_IOVEC] = {
                                    {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0} };
+
+#ifndef TFM_PSA_API
     struct tfm_core_test_call_args_t args = {NULL, 0, NULL, 0};
+#endif /* TFM_PSA_API */
 
     /* Check a few valid cases */
 
     /* Execute a call with valid iovecs (empty) */
     empty_iovecs(in_vec, out_vec);
+
+#ifndef TFM_PSA_API
     args.in_vec = NULL;
     args.in_len = 0;
     args.out_vec = NULL;
     args.out_len = 0;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("iovec sanitization failed on empty vectors.");
         return;
@@ -171,11 +228,17 @@
 
     /* Execute a call with valid iovecs (full) */
     full_iovecs(in_vec, out_vec);
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = PSA_MAX_IOVEC - args.in_len;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 2);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("iovec sanitization failed on full vectors.");
         return;
@@ -183,11 +246,17 @@
 
     /* Execute a call with valid iovecs (different number of vectors) */
     full_iovecs(in_vec, out_vec);
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = 1;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 1);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL(
                  "iovec sanitization failed on valid, partially full vectors.");
@@ -202,12 +271,18 @@
      * range
      */
     full_iovecs(in_vec, out_vec);
+    out_vec[1].base = NULL;
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = 1;
-    out_vec[1].base = NULL;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 1);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("content of an outvec out of range should not be checked");
         return;
@@ -217,12 +292,18 @@
      * range
      */
     full_iovecs(in_vec, out_vec);
+    in_vec[2].len = 0;
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = 1;
-    in_vec[2].len = 0;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 1);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("content of an outvec out of range should not be checked");
         return;
@@ -230,13 +311,19 @@
 
     /* Execute a call with len = 0 in single vector in invec */
     full_iovecs(in_vec, out_vec);
+    in_vec[1].len = 0;
+    in_vec[1].base = NULL;
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = 2;
-    in_vec[1].len = 0;
-    in_vec[1].base = NULL;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 2);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("If the len of an invec is 0, the base should be ignored");
         return;
@@ -244,13 +331,19 @@
 
     /* Execute a call with len = 0 in single vector in outvec */
     full_iovecs(in_vec, out_vec);
+    out_vec[1].len = 0;
+    out_vec[1].base = NULL;
+#ifndef TFM_PSA_API
     args.in_vec = in_vec;
     args.in_len = 2;
     args.out_vec = out_vec;
     args.out_len = 2;
-    out_vec[1].len = 0;
-    out_vec[1].base = NULL;
     err = tfm_core_test_call(tfm_spm_core_test_2_slave_service_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          in_vec, 2, out_vec, 2);
+#endif /* TFM_PSA_API */
     if (err != CORE_TEST_ERRNO_SUCCESS_2) {
         TEST_FAIL("If the len of an outvec is 0, the base should be ignored");
         return;
@@ -262,7 +355,6 @@
 static void tfm_core_test_outvec_write(struct test_result_t *ret)
 {
     int32_t err;
-    int32_t test_case_id = CORE_TEST_ID_OUTVEC_WRITE;
     int i;
     uint8_t in_buf_0[] = {0, 1, 2, 3, 4};
     uint8_t in_buf_1[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
@@ -273,11 +365,18 @@
                                         {in_buf_1, sizeof(in_buf_1)} };
     psa_outvec out_vec[PSA_MAX_IOVEC] = { {out_buf_0, sizeof(out_buf_0) },
                                         {out_buf_1, sizeof(out_buf_1)} };
+#ifndef TFM_PSA_API
+    int32_t test_case_id = CORE_TEST_ID_OUTVEC_WRITE;
     struct tfm_core_test_call_args_t args1 = {in_vec, 2, out_vec, 2};
     struct tfm_core_test_call_args_t args2 = {in_vec, 1, NULL, 0};
 
     err = tfm_core_test_call(tfm_spm_core_test_2_get_every_second_byte_veneer,
                                                                         &args1);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID,
+                          SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_MIN_VER,
+                          in_vec, 2, out_vec, 2);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("call to secure function should be successful");
@@ -303,9 +402,15 @@
     }
 
     /* do the same test on the secure side */
+#ifndef TFM_PSA_API
     in_vec[0].base = &test_case_id;
     in_vec[0].len = sizeof(int32_t);
     err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args2);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_OUTVEC_WRITE_SID,
+                          SPM_CORE_TEST_OUTVEC_WRITE_MIN_VER,
+                          in_vec, 0, out_vec, 0);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("Failed to execute secure side test");
@@ -323,9 +428,15 @@
 static void tfm_core_test_check_init(struct test_result_t *ret)
 {
     int32_t err;
+#ifndef TFM_PSA_API
     struct tfm_core_test_call_args_t args = {NULL, 0, NULL, 0};
 
     err = tfm_core_test_call(tfm_spm_core_test_sfn_init_success_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_INIT_SUCCESS_SID,
+                          SPM_CORE_TEST_INIT_SUCCESS_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("Failed to initialise test service.");
@@ -345,6 +456,7 @@
     ret->val = TEST_PASSED;
 }
 
+#ifndef TFM_PSA_API
 static char *error_to_string(const char *desc, int32_t err)
 {
     static char info[80];
@@ -405,6 +517,7 @@
 
     ret->val = TEST_PASSED;
 }
+#endif /* TFM_PSA_API */
 
 static void tfm_core_test_buffer_check(struct test_result_t *ret)
 {
@@ -416,9 +529,15 @@
     psa_invec in_vec[] = { {inbuf, sizeof(inbuf)} };
     psa_outvec outvec[] = { {outbuf, sizeof(outbuf)},
                            {&result, sizeof(int32_t)} };
+#ifndef TFM_PSA_API
     struct tfm_core_test_call_args_t args = {in_vec, 1, outvec, 2};
 
     res = tfm_core_test_call(tfm_spm_core_test_2_sfn_invert_veneer, &args);
+#else /* TFM_PSA_API */
+    res = psa_test_common(SPM_CORE_TEST_2_INVERT_SID,
+                          SPM_CORE_TEST_2_INVERT_MIN_VER,
+                          in_vec, 1, outvec, 2);
+#endif /* TFM_PSA_API */
     if (res != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("Call to secure service should be successful.");
         return;
@@ -448,11 +567,17 @@
 {
     int32_t err;
 
+#ifndef TFM_PSA_API
     int32_t test_case_id = CORE_TEST_ID_SS_TO_SS;
     psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
     struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
 
     err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_SS_TO_SS_SID,
+                          SPM_CORE_TEST_SS_TO_SS_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("The internal service call failed.");
@@ -462,6 +587,7 @@
     ret->val = TEST_PASSED;
 }
 
+#ifndef TFM_PSA_API
 static void tfm_core_test_share_change(struct test_result_t *ret)
 {
     int32_t err;
@@ -478,6 +604,7 @@
 
     ret->val = TEST_PASSED;
 }
+#endif /* TFM_PSA_API */
 
 static void tfm_core_test_ss_to_ss_buffer(struct test_result_t *ret)
 {
@@ -486,14 +613,23 @@
     uint32_t inbuf[] = {1, 2, 3, 4, 0xAAAFFF, 0xFFFFFFFF};
     uint32_t outbuf[16] = {0};
     int32_t len = (int32_t)sizeof(inbuf) >> 2;
+    psa_outvec out_vec[] = { {outbuf, sizeof(outbuf)} };
+#ifndef TFM_PSA_API
     int32_t test_case_id = CORE_TEST_ID_SS_TO_SS_BUFFER;
     psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)},
                           {inbuf, sizeof(inbuf)},
                           {&len, sizeof(int32_t)} };
-    psa_outvec outvec[] = { {outbuf, sizeof(outbuf)} };
-    struct tfm_core_test_call_args_t args = {in_vec, 3, outvec, 1};
+    struct tfm_core_test_call_args_t args = {in_vec, 3, out_vec, 1};
 
     res = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
+#else /* TFM_PSA_API */
+    psa_invec in_vec[] = {{inbuf, sizeof(inbuf)},
+                          {&len, sizeof(int32_t)} };
+
+    res = psa_test_common(SPM_CORE_TEST_SS_TO_SS_BUFFER_SID,
+                          SPM_CORE_TEST_SS_TO_SS_BUFFER_MIN_VER,
+                          in_vec, 2, out_vec, 1);
+#endif /* TFM_PSA_API */
     switch (res) {
     case CORE_TEST_ERRNO_SUCCESS:
         for (i = 0; i < sizeof(inbuf) >> 2; i++) {
@@ -525,6 +661,7 @@
     }
 }
 
+#ifndef TFM_PSA_API
 static void tfm_core_test_get_caller_client_id(struct test_result_t *ret)
 {
     int32_t err;
@@ -541,15 +678,22 @@
 
     ret->val = TEST_PASSED;
 }
+#endif /* TFM_PSA_API */
 
 static void tfm_core_test_spm_request(struct test_result_t *ret)
 {
     int32_t err;
+#ifndef TFM_PSA_API
     int32_t test_case_id = CORE_TEST_ID_SPM_REQUEST;
     psa_invec in_vec[] = { {&test_case_id, sizeof(int32_t)} };
     struct tfm_core_test_call_args_t args = {in_vec, 1, NULL, 0};
 
     err = tfm_core_test_call(tfm_spm_core_test_sfn_veneer, &args);
+#else /* TFM_PSA_API */
+    err = psa_test_common(SPM_CORE_TEST_SPM_REQUEST_SID,
+                          SPM_CORE_TEST_SPM_REQUEST_MIN_VER,
+                          NULL, 0, NULL, 0);
+#endif /* TFM_PSA_API */
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         TEST_FAIL("The SPM request failed.");
diff --git a/test/test_services/tfm_core_test/core_test_defs.h b/test/test_services/tfm_core_test/core_test_defs.h
index c34d7a2..3a36619 100644
--- a/test/test_services/tfm_core_test/core_test_defs.h
+++ b/test/test_services/tfm_core_test/core_test_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -33,6 +33,42 @@
 #define CORE_TEST_ID_OUTVEC_WRITE         1016
 #define CORE_TEST_ID_BLOCK                2001
 
+#define SPM_CORE_TEST_INIT_SUCCESS_SID                 0x00002100
+#define SPM_CORE_TEST_DIRECT_RECURSION_SID             0x00002101
+#define SPM_CORE_TEST_MPU_ACCESS_SID                   0x00002102
+#define SPM_CORE_TEST_MEMORY_PERMISSIONS_SID           0x00002103
+#define SPM_CORE_TEST_SHARE_REDIRECTION_SID            0x00002104
+#define SPM_CORE_TEST_SS_TO_SS_SID                     0x00002105
+#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SID              0x00002106
+#define SPM_CORE_TEST_OUTVEC_WRITE_SID                 0x00002107
+#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SID            0x00002108
+#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SID         0x00002109
+#define SPM_CORE_TEST_SPM_REQUEST_SID                  0x0000210A
+#define SPM_CORE_TEST_BLOCK_SID                        0x0000210B
+#define SPM_CORE_TEST_NS_THREAD_SID                    0x0000210C
+#define SPM_CORE_TEST_INIT_SUCCESS_MIN_VER                 0x0001
+#define SPM_CORE_TEST_DIRECT_RECURSION_MIN_VER             0x0001
+#define SPM_CORE_TEST_MPU_ACCESS_MIN_VER                   0x0001
+#define SPM_CORE_TEST_MEMORY_PERMISSIONS_MIN_VER           0x0001
+#define SPM_CORE_TEST_SHARE_REDIRECTION_MIN_VER            0x0001
+#define SPM_CORE_TEST_SS_TO_SS_MIN_VER                     0x0001
+#define SPM_CORE_TEST_SS_TO_SS_BUFFER_MIN_VER              0x0001
+#define SPM_CORE_TEST_OUTVEC_WRITE_MIN_VER                 0x0001
+#define SPM_CORE_TEST_PERIPHERAL_ACCESS_MIN_VER            0x0001
+#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_MIN_VER         0x0001
+#define SPM_CORE_TEST_SPM_REQUEST_MIN_VER                  0x0001
+#define SPM_CORE_TEST_BLOCK_MIN_VER                        0x0001
+#define SPM_CORE_TEST_NS_THREAD_MIN_VER                    0x0001
+
+#define SPM_CORE_TEST_2_SLAVE_SERVICE_SID              0x00002200
+#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SID     0x00002201
+#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID      0x00002202
+#define SPM_CORE_TEST_2_INVERT_SID                     0x00002203
+#define SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER              0x0001
+#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_MIN_VER     0x0001
+#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_MIN_VER      0x0001
+#define SPM_CORE_TEST_2_INVERT_MIN_VER                     0x0001
+
 /* Use lower 16 bits in return value for error code, upper 16 for line number
  * in test service
  */
diff --git a/test/test_services/tfm_core_test/manifest.yaml b/test/test_services/tfm_core_test/manifest.yaml
index 58abfe1..cbf5be5 100644
--- a/test/test_services/tfm_core_test/manifest.yaml
+++ b/test/test_services/tfm_core_test/manifest.yaml
@@ -11,6 +11,7 @@
   "priority": "NORMAL",
   "id": "0x00000002",
   "entry_point": "core_test_init",
+  "tfm_partition_ipc": true,
   "stack_size": "0x0400",
   "heap_size": "0x0400",
   "mmio_regions": [
@@ -52,5 +53,111 @@
     "object_list": [
       "*tfm_ss_core_test.*"
     ]
-  }
+  },
+  "services": [
+    {
+      "name": "SPM_CORE_TEST_INIT_SUCCESS_SID",
+      "sid": "0x00002100",
+      "signal": "SPM_CORE_TEST_INIT_SUCCESS_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_DIRECT_RECURSION_SID",
+      "sid": "0x00002101",
+      "signal": "SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_MPU_ACCESS_SID",
+      "sid": "0x00002102",
+      "signal": "SPM_CORE_TEST_MPU_ACCESS_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_MEMORY_PERMISSIONS_SID",
+      "sid": "0x00002103",
+      "signal": "SPM_CORE_TEST_MEMORY_PERMISSIONS_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_SHARE_REDIRECTION_SID",
+      "sid": "0x00002104",
+      "signal": "SPM_CORE_TEST_SHARE_REDIRECTION_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_SS_TO_SS_SID",
+      "sid": "0x00002105",
+      "signal": "SPM_CORE_TEST_SS_TO_SS_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_SS_TO_SS_BUFFER_SID",
+      "sid": "0x00002106",
+      "signal": "SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_OUTVEC_WRITE_SID",
+      "sid": "0x00002107",
+      "signal": "SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_PERIPHERAL_ACCESS_SID",
+      "sid": "0x00002108",
+      "signal": "SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SID",
+      "sid": "0x00002109",
+      "signal": "SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_SPM_REQUEST_SID",
+      "sid": "0x0000210A",
+      "signal": "SPM_CORE_TEST_SPM_REQUEST_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_BLOCK_SID",
+      "sid": "0x0000210B",
+      "signal": "SPM_CORE_TEST_BLOCK_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_NS_THREAD_SID",
+      "sid": "0x0000210C",
+      "signal": "SPM_CORE_TEST_NS_THREAD_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    }
+  ]
 }
diff --git a/test/test_services/tfm_core_test/tfm_ss_core_test.c b/test/test_services/tfm_core_test/tfm_ss_core_test.c
index d8cc347..dd6acd5 100644
--- a/test/test_services/tfm_core_test/tfm_ss_core_test.c
+++ b/test/test_services/tfm_core_test/tfm_ss_core_test.c
@@ -14,6 +14,9 @@
 #include "secure_fw/core/tfm_secure_api.h"
 #include "secure_fw/include/tfm_spm_services_api.h"
 #include "spm_partition_defs.h"
+#include "psa_service.h"
+#include "test/test_services/tfm_core_test/tfm_ss_core_test_signal.h"
+#include "test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h"
 
 #include "smm_mps2.h"
 
@@ -34,11 +37,28 @@
 
 static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
 
-psa_status_t core_test_init(void)
+#ifdef TFM_PSA_API
+static psa_status_t psa_test_common(uint32_t sid, uint32_t minor_version,
+                                    const psa_invec *in_vecs, size_t in_len,
+                                    psa_outvec *out_vecs, size_t out_len)
 {
-    partition_init_done = 1;
-    return CORE_TEST_ERRNO_SUCCESS;
+    psa_handle_t handle;
+    psa_status_t status;
+
+    handle = psa_connect(sid, minor_version);
+    if (handle <= 0) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    status = psa_call(handle, in_vecs, in_len, out_vecs, out_len);
+    if (status < 0) {
+        status = CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
+    }
+
+    psa_close(handle);
+    return status;
 }
+#endif /* TFM_PSA_API */
 
 psa_status_t spm_core_test_sfn_init_success(
                                      struct psa_invec *in_vec, size_t in_len,
@@ -96,7 +116,7 @@
 
 #define MPS2_USERLED_MASK   (0x3)
 
-psa_status_t test_mpu_access(
+static psa_status_t test_mpu_access(
     uint32_t *data_r_ptr, uint32_t *code_ptr, uint32_t *data_w_ptr)
 {
     /* If these accesses fail, TFM Core kicks in, there's no returning to sfn */
@@ -137,7 +157,7 @@
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
-psa_status_t test_memory_permissions(
+static psa_status_t test_memory_permissions(
     uint32_t *data_r_ptr, uint32_t *code_ptr, uint32_t *data_w_ptr)
 {
     int32_t len = sizeof(uint32_t);
@@ -180,13 +200,16 @@
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
-psa_status_t test_share_redirection(void)
+static psa_status_t test_share_redirection(void)
 {
     uint32_t tmp;
 
+#ifndef TFM_PSA_API
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
         return CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
     }
+#endif /* TFM_PSA_API */
+
     /* Read from scratch */
     tmp = tfm_scratch_area[0];
     /* Write to scratch */
@@ -195,7 +218,7 @@
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
-psa_status_t test_peripheral_access(void)
+static psa_status_t test_peripheral_access(void)
 {
     struct arm_mps2_fpgaio_t *fpgaio = SEC_MPS2_FPGAIO;
     /* Check read access */
@@ -215,8 +238,8 @@
 
 #define SS_BUFFER_LEN 16
 
-psa_status_t test_ss_to_ss_buffer(uint32_t *in_ptr, uint32_t *out_ptr,
-                                  int32_t len)
+static psa_status_t test_ss_to_ss_buffer(uint32_t *in_ptr, uint32_t *out_ptr,
+                                         int32_t len)
 {
     int32_t i;
     /* Service internal buffer */
@@ -234,6 +257,7 @@
         return CORE_TEST_ERRNO_TEST_FAULT;
     }
 
+#ifndef TFM_PSA_API
     /* Check requires byte-based size */
     if ((tfm_core_memory_permission_check(in_ptr, len << 2,
         TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS) ||
@@ -241,21 +265,31 @@
         TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS)) {
         return CORE_TEST_ERRNO_INVALID_BUFFER;
     }
+#endif /* TFM_PSA_API */
 
     for (i = 0; i < len; i++) {
         ss_buffer[i] = in_ptr[i];
     }
 
+#ifndef TFM_PSA_API
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
         return CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
     }
+#endif /* TFM_PSA_API */
 
     for (i = 0; i < len; i++) {
         slave_buffer[i] = ss_buffer[i];
     }
 
     /* Call internal service with buffer handling */
+
+#ifdef TFM_PSA_API
+    res = psa_test_common(SPM_CORE_TEST_2_INVERT_SID,
+                          SPM_CORE_TEST_2_INVERT_MIN_VER,
+                          in_vec, 1, outvec, 2);
+#else
     res = tfm_spm_core_test_2_sfn_invert_veneer(in_vec, 1, outvec, 2);
+#endif
 
     if (res != CORE_TEST_ERRNO_SUCCESS) {
         return CORE_TEST_ERRNO_SLAVE_SP_CALL_FAILURE;
@@ -268,9 +302,11 @@
         ss_buffer[i] = slave_buffer[i];
     }
 
+#ifndef TFM_PSA_API
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_DEFAULT) != TFM_SUCCESS) {
         return CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
     }
+#endif /* TFM_PSA_API */
 
     for (i = 0; i < len; i++) {
         out_ptr[i] = ss_buffer[i];
@@ -291,9 +327,11 @@
     uint8_t *out_buf_0;
     uint8_t *out_buf_1;
 
+#ifndef TFM_PSA_API
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
         return CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
     }
+#endif /* TFM_PSA_API */
 
     in_buf_0 = scratch_ptr;
     for (i = 0; i < 5; ++i, ++scratch_ptr)
@@ -323,8 +361,14 @@
     out_vec[1].base = out_buf_0;
     out_vec[1].len = scratch_ptr - out_buf_0;
 
+#ifdef TFM_PSA_API
+    err = psa_test_common(SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID,
+                          SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_MIN_VER,
+                          in_vec, 2, out_vec, 2);
+#else
     err = tfm_spm_core_test_2_get_every_second_byte_veneer(in_vec, 2,
                                                            out_vec, 2);
+#endif
 
     if (err != CORE_TEST_ERRNO_SUCCESS) {
         return CORE_TEST_ERRNO_TEST_FAULT;
@@ -345,18 +389,26 @@
         }
     }
 
+#ifndef TFM_PSA_API
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_DEFAULT) != TFM_SUCCESS) {
         return CORE_TEST_ERRNO_UNEXPECTED_CORE_BEHAVIOUR;
     }
+#endif /* TFM_PSA_API */
 
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
-psa_status_t test_ss_to_ss(void)
+static psa_status_t test_ss_to_ss(void)
 {
+    int32_t ret;
     /* Call to a different service, should be successful */
-    int32_t ret = tfm_spm_core_test_2_slave_service_veneer(NULL, 0, NULL, 0);
-
+#ifdef TFM_PSA_API
+    ret = psa_test_common(SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+                          SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER,
+                          NULL, 0, NULL, 0);
+#else /* TFM_PAS_API*/
+    ret = tfm_spm_core_test_2_slave_service_veneer(NULL, 0, NULL, 0);
+#endif /* TFM_PAS_API*/
     if (ret == CORE_TEST_ERRNO_SUCCESS_2) {
         return CORE_TEST_ERRNO_SUCCESS;
     } else {
@@ -537,3 +589,245 @@
         return CORE_TEST_ERRNO_INVALID_TEST_ID;
     }
 }
+
+#ifdef TFM_PSA_API
+
+#define SS_TO_SS_BUFFER_SIZE (16*4)
+
+typedef psa_status_t (*core_test_func_t)(psa_msg_t *msg);
+
+static psa_status_t tfm_core_test_sfn_wrap_init_success(psa_msg_t *msg)
+{
+    return spm_core_test_sfn_init_success(NULL, 0, NULL, 0);
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_direct_recursion(psa_msg_t *msg)
+{
+    return CORE_TEST_ERRNO_TEST_FAULT;
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_mpu_access(psa_msg_t *msg)
+{
+    size_t num;
+    uint32_t *data_r_ptr;
+    uint32_t *code_ptr;
+    uint32_t *data_w_ptr;
+
+    if ((msg->in_size[0] < sizeof(int32_t)) ||
+        (msg->in_size[1] < sizeof(int32_t)) ||
+        (msg->in_size[2] < sizeof(int32_t))) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 0, &data_r_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 1, &code_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 2, &data_w_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    return test_mpu_access(data_r_ptr, code_ptr, data_w_ptr);
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_memory_permissions(psa_msg_t *msg)
+{
+    size_t num;
+    uint32_t *data_r_ptr;
+    uint32_t *code_ptr;
+    uint32_t *data_w_ptr;
+
+    if ((msg->in_size[0] < sizeof(int32_t)) ||
+        (msg->in_size[1] < sizeof(int32_t)) ||
+        (msg->in_size[2] < sizeof(int32_t))) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 0, &data_r_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 1, &code_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 2, &data_w_ptr, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    return test_memory_permissions(data_r_ptr, code_ptr, data_w_ptr);
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_share_redirection(psa_msg_t *msg)
+{
+    return test_share_redirection();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_ss_to_ss(psa_msg_t *msg)
+{
+    return test_ss_to_ss();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_ss_to_ss_buffer(psa_msg_t *msg)
+{
+    size_t num;
+    uint32_t inbuf[SS_TO_SS_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+    uint32_t outbuf[SS_TO_SS_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+    uint32_t len;
+    psa_status_t res;
+
+    if ((msg->in_size[0] > SS_TO_SS_BUFFER_SIZE) ||
+        (msg->in_size[1] != sizeof(int32_t)) ||
+        (msg->out_size[0] > SS_TO_SS_BUFFER_SIZE)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 0, inbuf, msg->in_size[0]);
+    if (num != msg->in_size[0]) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    num = psa_read(msg->handle, 1, &len, sizeof(int32_t));
+    if (num != sizeof(int32_t)) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    if (len > SS_TO_SS_BUFFER_SIZE) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+
+    res = test_ss_to_ss_buffer(inbuf, outbuf, len);
+    if (res < 0) {
+        return res;
+    }
+
+    psa_write(msg->handle, 0, outbuf, len * sizeof(uint32_t));
+
+    return res;
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_outvec_write(psa_msg_t *msg)
+{
+    return test_outvec_write();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_peripheral_access(psa_msg_t *msg)
+{
+    return test_peripheral_access();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_get_caller_client_id(psa_msg_t *msg)
+{
+    return test_get_caller_client_id();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_spm_request(psa_msg_t *msg)
+{
+    return test_spm_request();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_block(psa_msg_t *msg)
+{
+    return test_block();
+}
+
+static psa_status_t tfm_core_test_sfn_wrap_ns_thread(psa_msg_t *msg)
+{
+    return CORE_TEST_ERRNO_SUCCESS;
+}
+
+static void core_test_signal_handle(psa_signal_t signal, core_test_func_t pfn)
+{
+    psa_msg_t msg;
+    psa_status_t status;
+
+    status = psa_get(signal, &msg);
+    if (status) {
+        return;
+    }
+
+    switch (msg.type) {
+    case PSA_IPC_CONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    case PSA_IPC_CALL:
+        status = pfn(&msg);
+        psa_reply(msg.handle, status);
+        break;
+    case PSA_IPC_DISCONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    default:
+        break;
+    }
+}
+#endif
+
+psa_status_t core_test_init(void)
+{
+#ifdef TFM_PSA_API
+    psa_signal_t signals = 0;
+#endif
+
+    partition_init_done = 1;
+
+#ifdef TFM_PSA_API
+    while (1) {
+        signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+        if (signals & SPM_CORE_TEST_INIT_SUCCESS_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_INIT_SUCCESS_SIGNAL,
+                                    tfm_core_test_sfn_wrap_init_success);
+        } else if (signals & SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL,
+                                    tfm_core_test_sfn_wrap_direct_recursion);
+        } else if (signals & SPM_CORE_TEST_MPU_ACCESS_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_MPU_ACCESS_SIGNAL,
+                                    tfm_core_test_sfn_wrap_mpu_access);
+        } else if (signals & SPM_CORE_TEST_MEMORY_PERMISSIONS_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_MEMORY_PERMISSIONS_SIGNAL,
+                                    tfm_core_test_sfn_wrap_memory_permissions);
+        } else if (signals & SPM_CORE_TEST_SHARE_REDIRECTION_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_SHARE_REDIRECTION_SIGNAL,
+                                    tfm_core_test_sfn_wrap_share_redirection);
+        } else if (signals & SPM_CORE_TEST_SS_TO_SS_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_SS_TO_SS_SIGNAL,
+                                    tfm_core_test_sfn_wrap_ss_to_ss);
+        } else if (signals & SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL,
+                                    tfm_core_test_sfn_wrap_ss_to_ss_buffer);
+        } else if (signals & SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL,
+                                    tfm_core_test_sfn_wrap_outvec_write);
+        } else if (signals & SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL,
+                                    tfm_core_test_sfn_wrap_peripheral_access);
+        } else if (signals & SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL,
+                                   tfm_core_test_sfn_wrap_get_caller_client_id);
+        } else if (signals & SPM_CORE_TEST_SPM_REQUEST_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_SPM_REQUEST_SIGNAL,
+                                    tfm_core_test_sfn_wrap_spm_request);
+        } else if (signals & SPM_CORE_TEST_BLOCK_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_BLOCK_SIGNAL,
+                                    tfm_core_test_sfn_wrap_block);
+        } else if (signals & SPM_CORE_TEST_NS_THREAD_SIGNAL) {
+            core_test_signal_handle(SPM_CORE_TEST_NS_THREAD_SIGNAL,
+                                    tfm_core_test_sfn_wrap_ns_thread);
+        } else {
+            ; /* do nothing */
+        }
+    }
+#endif
+
+    return CORE_TEST_ERRNO_SUCCESS;
+}
diff --git a/test/test_services/tfm_core_test/tfm_ss_core_test_signal.h b/test/test_services/tfm_core_test/tfm_ss_core_test_signal.h
new file mode 100644
index 0000000..017c505
--- /dev/null
+++ b/test/test_services/tfm_core_test/tfm_ss_core_test_signal.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CORE_TEST_SIGNAL_H__
+#define __TFM_CORE_TEST_SIGNAL_H__
+
+/* FixMe: hardcode it for the tool cannot support now */
+#ifdef TFM_PSA_API
+
+#define SPM_CORE_TEST_INIT_SUCCESS_SIGNAL          (1 << (0  + 4))
+#define SPM_CORE_TEST_DIRECT_RECURSION_SIGNAL      (1 << (1  + 4))
+#define SPM_CORE_TEST_MPU_ACCESS_SIGNAL            (1 << (2  + 4))
+#define SPM_CORE_TEST_MEMORY_PERMISSIONS_SIGNAL    (1 << (3  + 4))
+#define SPM_CORE_TEST_SHARE_REDIRECTION_SIGNAL     (1 << (4  + 4))
+#define SPM_CORE_TEST_SS_TO_SS_SIGNAL              (1 << (5  + 4))
+#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SIGNAL       (1 << (6  + 4))
+#define SPM_CORE_TEST_OUTVEC_WRITE_SIGNAL          (1 << (7  + 4))
+#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SIGNAL     (1 << (8  + 4))
+#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SIGNAL  (1 << (9  + 4))
+#define SPM_CORE_TEST_SPM_REQUEST_SIGNAL           (1 << (10 + 4))
+#define SPM_CORE_TEST_BLOCK_SIGNAL                 (1 << (11 + 4))
+#define SPM_CORE_TEST_NS_THREAD_SIGNAL             (1 << (12 + 4))
+#endif /* TFM_PSA_API */
+
+#endif /* __TFM_CORE_TEST_SIGNAL_H__ */
diff --git a/test/test_services/tfm_core_test_2/manifest.yaml b/test/test_services/tfm_core_test_2/manifest.yaml
index d95209f..cfde231 100644
--- a/test/test_services/tfm_core_test_2/manifest.yaml
+++ b/test/test_services/tfm_core_test_2/manifest.yaml
@@ -11,6 +11,7 @@
   "priority": "NORMAL",
   "id": "0x00000003",
   "entry_point": "core_test_2_init",
+  "tfm_partition_ipc": true,
   "stack_size": "0x0400",
   "heap_size": "0x0400",
   "secure_functions": [
@@ -54,5 +55,39 @@
     "object_list": [
       "*tfm_ss_core_test_2.*"
     ]
-  }
+  },
+  "services": [
+    {
+      "name": "SPM_CORE_TEST_2_SLAVE_SERVICE_SID",
+      "sid": "0x00002200",
+      "signal": "SPM_CORE_TEST_2_SLAVE_SERVICE_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SID",
+      "sid": "0x00002201",
+      "signal": "SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID",
+      "sid": "0x00002202",
+      "signal": "SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "SPM_CORE_TEST_2_INVERT_SID",
+      "sid": "0x00002203",
+      "signal": "SPM_CORE_TEST_2_INVERT_SIGNAL",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+  ]
 }
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
index 77368f4..a6192a1 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
@@ -11,9 +11,11 @@
 #include "tfm_api.h"
 #include "tfm_secure_api.h"
 #include "spm_partition_defs.h"
-#include "test/test_services/tfm_core_test/core_test_defs.h"
+#include "psa_service.h"
+#include "tfm_ss_core_test_2_signal.h"
 
 #define INVALID_NS_CLIENT_ID  0x49abcdef
+#define INVERT_BUFFER_SIZE    (16*4)
 
 /* Don't initialise caller_partition_id_zi and expect it to be linked in the
  * zero-initialised data area
@@ -27,19 +29,10 @@
 
 static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
 
-/* FIXME: Add a testcase to test that a failed init makes the secure partition
- * closed, and none of its functions can be called.
- * A new test service for this purpose is to be added.
- */
-psa_status_t core_test_2_init(void)
-{
-    return CORE_TEST_ERRNO_SUCCESS;
-}
-
 psa_status_t spm_core_test_2_slave_service(struct psa_invec *in_vec,
-                                      size_t in_len,
-                                      struct psa_outvec *out_vec,
-                                      size_t out_len)
+                                           size_t in_len,
+                                           struct psa_outvec *out_vec,
+                                           size_t out_len)
 {
     /* This function doesn't do any sanity check on the input parameters, nor
      * makes any expectation of them, always returns successfully, with a
@@ -52,9 +45,9 @@
 }
 
 psa_status_t spm_core_test_2_check_caller_client_id(struct psa_invec *in_vec,
-                                    size_t in_len,
-                                    struct psa_outvec *out_vec,
-                                    size_t out_len)
+                                                    size_t in_len,
+                                                    struct psa_outvec *out_vec,
+                                                    size_t out_len)
 {
     size_t i;
     int32_t caller_client_id_stack = INVALID_NS_CLIENT_ID;
@@ -91,35 +84,96 @@
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
+psa_status_t spm_core_test_2_get_every_second_byte_internal(
+                                                           const uint8_t *inbuf,
+                                                           uint8_t *outbuf,
+                                                           size_t in_size,
+                                                           size_t *out_size)
+{
+    int j;
+
+    if (in_size/2 > *out_size) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
+    }
+    for (j = 1; j < in_size; j += 2) {
+        outbuf[j/2] = inbuf[j];
+    }
+    *out_size = in_size/2;
+
+    return CORE_TEST_ERRNO_SUCCESS;
+}
+
 psa_status_t spm_core_test_2_get_every_second_byte(
                                      struct psa_invec *in_vec, size_t in_len,
                                      struct psa_outvec *out_vec, size_t out_len)
 {
-    int i, j;
+    int i;
+    psa_status_t res;
 
     if (in_len != out_len) {
         return CORE_TEST_ERRNO_INVALID_PARAMETER;
     }
     for (i = 0; i < in_len; ++i) {
-        if (in_vec[i].len/2 > out_vec[i].len) {
-            return CORE_TEST_ERRNO_INVALID_PARAMETER;
+        res = spm_core_test_2_get_every_second_byte_internal(
+                              in_vec[i].base, out_vec[i].base,
+                              in_vec[i].len, &out_vec[i].len);
+        if (res < 0) {
+            return res;
         }
-        for (j = 1; j < in_vec[i].len; j += 2) {
-            ((uint8_t *)out_vec[i].base)[j/2] = ((uint8_t *)in_vec[i].base)[j];
-        }
-        out_vec[i].len = in_vec[i].len/2;
     }
     return CORE_TEST_ERRNO_SUCCESS;
 }
 
 /* Invert function */
 #define SFN_INVERT_MAX_LEN 128
-
-psa_status_t spm_core_test_2_sfn_invert(struct psa_invec *in_vec, size_t in_len,
-                                   struct psa_outvec *out_vec, size_t out_len)
+static psa_status_t spm_core_test_2_sfn_invert_internal(uint32_t *in_ptr,
+                                                        uint32_t *out_ptr,
+                                                        int32_t *res_ptr,
+                                                        int32_t len)
 {
     int32_t i;
     static uint32_t invert_buffer[SFN_INVERT_MAX_LEN];
+
+#ifndef TFM_PSA_API
+    if (tfm_core_memory_permission_check(res_ptr, sizeof(int32_t),
+        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS) {
+        return CORE_TEST_ERRNO_INVALID_BUFFER;
+    }
+#endif /* TFM_PSA_API */
+    *res_ptr = -1;
+
+    if (len > SFN_INVERT_MAX_LEN) {
+        return CORE_TEST_ERRNO_INVALID_BUFFER;
+    }
+
+#ifndef TFM_PSA_API
+    /* Check requires byte-based size */
+    if ((tfm_core_memory_permission_check(in_ptr, len << 2,
+        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS) ||
+        (tfm_core_memory_permission_check(out_ptr, len << 2,
+        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS)) {
+        return CORE_TEST_ERRNO_INVALID_BUFFER;
+    }
+#endif /* TFM_PSA_API */
+
+    for (i = 0; i < len; i++) {
+        invert_buffer[i] = in_ptr[i];
+    }
+    for (i = 0; i < len; i++) {
+        invert_buffer[i] = ~invert_buffer[i];
+    }
+    for (i = 0; i < len; i++) {
+        out_ptr[i] = invert_buffer[i];
+    }
+
+    *res_ptr = 0;
+    return CORE_TEST_ERRNO_SUCCESS;
+}
+
+psa_status_t spm_core_test_2_sfn_invert(
+                                     struct psa_invec *in_vec, size_t in_len,
+                                     struct psa_outvec *out_vec, size_t out_len)
+{
     int32_t len;
     uint32_t *in_ptr;
     uint32_t *out_ptr;
@@ -140,35 +194,150 @@
     out_ptr = (uint32_t *)out_vec[0].base;
     res_ptr = (int32_t *)out_vec[1].base;
 
-    if (tfm_core_memory_permission_check(res_ptr, sizeof(int32_t),
-        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS) {
-        return CORE_TEST_ERRNO_INVALID_BUFFER;;
+    return spm_core_test_2_sfn_invert_internal(in_ptr, out_ptr, res_ptr, len);
+}
+
+#ifdef TFM_PSA_API
+
+typedef psa_status_t (*core_test_2_func_t)(psa_msg_t *msg);
+
+static void core_test_2_signal_handle(psa_signal_t signal,
+                                      core_test_2_func_t pfn)
+{
+    psa_msg_t msg;
+    psa_status_t status;
+
+    status = psa_get(signal, &msg);
+    if (status) {
+        return;
     }
 
-    *res_ptr = -1;
+    switch (msg.type) {
+    case PSA_IPC_CONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    case PSA_IPC_CALL:
+        status = pfn(&msg);
+        psa_reply(msg.handle, status);
+        break;
+    case PSA_IPC_DISCONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    default:
+        break;
+    }
+}
 
-    if (len > SFN_INVERT_MAX_LEN) {
-        return CORE_TEST_ERRNO_INVALID_BUFFER;;
+psa_status_t spm_core_test_2_wrap_slave_service(psa_msg_t *msg)
+{
+    return spm_core_test_2_slave_service(NULL, 0, NULL, 0);
+}
+
+psa_status_t spm_core_test_2_wrap_check_caller_client_id(psa_msg_t *msg)
+{
+    return spm_core_test_2_check_caller_client_id(NULL, 0, NULL, 0);
+}
+
+psa_status_t spm_core_test_2_wrap_get_every_second_byte(psa_msg_t *msg)
+{
+    uint32_t inbuf[INVERT_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+    uint32_t outbuf[INVERT_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+
+    int i;
+    size_t num;
+    size_t out_len;
+    psa_status_t res;
+
+    for (i = 0; i < PSA_MAX_IOVEC; ++i) {
+        if (msg->in_size[i] > INVERT_BUFFER_SIZE) {
+            return CORE_TEST_ERRNO_INVALID_PARAMETER;
+        }
+
+        if (msg->in_size[i] == 0) {
+            continue;
+        }
+
+        num = psa_read(msg->handle, i, inbuf, msg->in_size[i]);
+        if (num != msg->in_size[i]) {
+            return CORE_TEST_ERRNO_INVALID_PARAMETER;
+        }
+
+        out_len = msg->out_size[i];
+
+        res = spm_core_test_2_get_every_second_byte_internal((uint8_t *)inbuf,
+                (uint8_t *)outbuf, msg->in_size[i], &out_len);
+        if (res < 0) {
+            return res;
+        }
+
+        psa_write(msg->handle, i, outbuf, out_len);
+    }
+    return CORE_TEST_ERRNO_SUCCESS;
+}
+
+psa_status_t spm_core_test_2_wrap_sfn_invert(psa_msg_t *msg)
+{
+    uint32_t inbuf[INVERT_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+    uint32_t outbuf[INVERT_BUFFER_SIZE/sizeof(uint32_t)] = {0};
+    size_t num;
+    int32_t res_ptr;
+    psa_status_t ret;
+
+    if ((msg->out_size[0] < msg->in_size[0]) ||
+        (msg->in_size[0] > INVERT_BUFFER_SIZE) ||
+        (msg->in_size[0]%4 != 0) ||
+        (msg->out_size[1] < sizeof(int32_t))) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
     }
 
-    /* Check requires byte-based size */
-    if ((tfm_core_memory_permission_check(in_ptr, len << 2,
-        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS) ||
-        (tfm_core_memory_permission_check(out_ptr, len << 2,
-        TFM_MEMORY_ACCESS_RW) != TFM_SUCCESS)) {
-        return CORE_TEST_ERRNO_INVALID_BUFFER;;
+    num = psa_read(msg->handle, 0, inbuf, msg->in_size[0]);
+    if (num != msg->in_size[0]) {
+        return CORE_TEST_ERRNO_INVALID_PARAMETER;
     }
 
-    for (i = 0; i < len; i++) {
-        invert_buffer[i] = in_ptr[i];
-    }
-    for (i = 0; i < len; i++) {
-        invert_buffer[i] = ~invert_buffer[i];
-    }
-    for (i = 0; i < len; i++) {
-        out_ptr[i] = invert_buffer[i];
+    ret = spm_core_test_2_sfn_invert_internal(inbuf, outbuf,
+                                              &res_ptr, msg->in_size[0]);
+    if (ret < 0) {
+        return ret;
     }
 
-    *res_ptr = 0;
+    psa_write(msg->handle, 0, outbuf, msg->in_size[0]);
+    psa_write(msg->handle, 1, &res_ptr, sizeof(int32_t));
+
+    return ret;
+}
+
+#endif
+
+/* FIXME: Add a testcase to test that a failed init makes the secure partition
+ * closed, and none of its functions can be called.
+ * A new test service for this purpose is to be added.
+ */
+psa_status_t core_test_2_init(void)
+{
+#ifdef TFM_PSA_API
+    psa_signal_t signals = 0;
+
+    while (1) {
+        signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+        if (signals & SPM_CORE_TEST_2_SLAVE_SERVICE_SIGNAL) {
+            core_test_2_signal_handle(SPM_CORE_TEST_2_SLAVE_SERVICE_SIGNAL,
+                                      spm_core_test_2_wrap_slave_service);
+        } else if (signals & SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL) {
+            core_test_2_signal_handle(
+                                  SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL,
+                                  spm_core_test_2_wrap_check_caller_client_id);
+        } else if (signals & SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL) {
+            core_test_2_signal_handle(
+                                   SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL,
+                                   spm_core_test_2_wrap_get_every_second_byte);
+        } else if (signals & SPM_CORE_TEST_2_INVERT_SIGNAL) {
+            core_test_2_signal_handle(SPM_CORE_TEST_2_INVERT_SIGNAL,
+                                      spm_core_test_2_wrap_sfn_invert);
+        } else {
+            ; /* do nothing */
+        }
+    }
+#endif
     return CORE_TEST_ERRNO_SUCCESS;
 }
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h
new file mode 100644
index 0000000..ae9c1db
--- /dev/null
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CORE_TEST_2_SIGNAL_H__
+#define __TFM_CORE_TEST_2_SIGNAL_H__
+
+/* FixMe: hardcode it for the tool cannot support now */
+#ifdef TFM_PSA_API
+
+#define SPM_CORE_TEST_2_SLAVE_SERVICE_SIGNAL            (1 << (0  + 4))
+#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL   (1 << (1  + 4))
+#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL    (1 << (2  + 4))
+#define SPM_CORE_TEST_2_INVERT_SIGNAL                   (1 << (3  + 4))
+#endif /* TFM_PSA_API */
+
+#endif /* __TFM_CORE_TEST_2_SIGNAL_H__ */