Test: Create SST test service

This patch adds a new secure service for use by
the SST test suites. The initial implementation
enables testing of the SST access by reference
feature.

Change-Id: I41663255bd65aa72168ba6d32c47b23e65586001
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index f479815..bb56736 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -49,6 +49,7 @@
 set (CORE_TEST_SERVICES OFF)
 set (CORE_TEST_POSITIVE OFF)
 set (CORE_TEST_INTERACTIVE OFF)
+set (SST_TEST_SERVICES OFF)
 
 if (REGRESSION)
 	set(SERVICES_TEST_ENABLED ON)
@@ -88,6 +89,7 @@
 if (SERVICE_TEST_NS)
 	add_definitions(-DSERVICES_TEST_NS)
 	set(TEST_FRAMEWORK_NS ON)
+	set(SST_TEST_SERVICES ON)
 endif()
 
 if(TEST_FRAMEWORK_S)
@@ -102,6 +104,10 @@
 	add_definitions(-DCORE_TEST_SERVICES)
 endif()
 
+if (SST_TEST_SERVICES)
+	add_definitions(-DSST_TEST_SERVICES)
+endif()
+
 if (BL2)
 	add_definitions(-DBL2)
 endif()
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index d32bb39..6e84182 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -137,6 +137,12 @@
 	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DCORE_TEST_SERVICES\"")
 endif()
 
+if (NOT DEFINED SST_TEST_SERVICES)
+	message(FATAL_ERROR "Incomplete build configuration: SST_TEST_SERVICES is undefined. ")
+elseif (SST_TEST_SERVICES)
+	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DSST_TEST_SERVICES\"")
+endif()
+
 #Set BL2 specific settings.
 if (NOT DEFINED BL2)
 	message(FATAL_ERROR "Incomplete build configuration: BL2 is undefined. ")
diff --git a/app/main_ns.c b/app/main_ns.c
index a0d64d5..fb7b10a 100644
--- a/app/main_ns.c
+++ b/app/main_ns.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -19,6 +19,9 @@
 #ifdef CORE_TEST_SERVICES
 #include "test/suites/core/non_secure/svc_core_test_ns.h"
 #endif
+#ifdef SST_TEST_SERVICES
+#include "test/test_services/tfm_sst_test_service/sst_test_service_svc.h"
+#endif
 #ifdef TEST_FRAMEWORK_NS
 #include "test/framework/integ_test.h"
 #endif
@@ -56,6 +59,13 @@
   (void *)svc_tfm_core_test_multiple_calls,
 #endif /* CORE_TEST_SERVICES */
 
+#if defined(SST_TEST_SERVICES)
+  (void *)sst_test_service_svc_setup,
+  (void *)sst_test_service_svc_dummy_encrypt,
+  (void *)sst_test_service_svc_dummy_decrypt,
+  (void *)sst_test_service_svc_clean,
+#endif /* SST_TEST_SERVICES */
+
 //(void *)user_function1,
 // ...
 };
diff --git a/interface/include/tfm_ns_svc.h b/interface/include/tfm_ns_svc.h
index e83b076..75b78ec 100644
--- a/interface/include/tfm_ns_svc.h
+++ b/interface/include/tfm_ns_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -47,6 +47,13 @@
     SVC_TFM_CORE_TEST_MULTIPLE_CALLS,
 #endif /* CORE_TEST_SERVICES */
 
+#if defined(SST_TEST_SERVICES)
+    SVC_SST_TEST_SERVICE_SETUP,
+    SVC_SST_TEST_SERVICE_DUMMY_ENCRYPT,
+    SVC_SST_TEST_SERVICE_DUMMY_DECRYPT,
+    SVC_SST_TEST_SERVICE_CLEAN,
+#endif /* SST_TEST_SERVICES */
+
     /* add all the new entries above this line */
     SVC_TFM_MAX,
 };
diff --git a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
index f22f16d..06c34a5 100644
--- a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
+++ b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
@@ -61,6 +61,12 @@
     }
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+    TFM_SEC_FUNC_SST_TEST_SERVICE +0 ALIGN 32 {
+        *sst_test_service.* (+RO)
+    }
+#endif /* SST_TEST_SERVICES */
+
     ER_TFM_DATA S_DATA_START S_DATA_SIZE {
         .ANY (+RW +ZI)
     }
@@ -96,6 +102,15 @@
     }
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+    TFM_SEC_FUNC_SST_TEST_SERVICE_DATA +0 ALIGN 32 {
+        sst_test_service.o (+RW +ZI)
+    }
+
+    TFM_SEC_FUNC_SST_TEST_SERVICE_STACK +0 ALIGN 128 EMPTY 0x2000 {
+    }
+#endif /* SST_TEST_SERVICES */
+
 #endif /* TFM_LVL == 1 */
 
 }
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index 46c7ee8..06c34a5 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -1,7 +1,7 @@
 #! armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -xc
 
 /*
- * Copyright (c) 2017 ARM Limited
+ * Copyright (c) 2017-2018 ARM Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -61,6 +61,12 @@
     }
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+    TFM_SEC_FUNC_SST_TEST_SERVICE +0 ALIGN 32 {
+        *sst_test_service.* (+RO)
+    }
+#endif /* SST_TEST_SERVICES */
+
     ER_TFM_DATA S_DATA_START S_DATA_SIZE {
         .ANY (+RW +ZI)
     }
@@ -96,6 +102,15 @@
     }
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+    TFM_SEC_FUNC_SST_TEST_SERVICE_DATA +0 ALIGN 32 {
+        sst_test_service.o (+RW +ZI)
+    }
+
+    TFM_SEC_FUNC_SST_TEST_SERVICE_STACK +0 ALIGN 128 EMPTY 0x2000 {
+    }
+#endif /* SST_TEST_SERVICES */
+
 #endif /* TFM_LVL == 1 */
 
 }
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index ab698c3..daf7fda 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -72,7 +72,14 @@
 
 #Set macro definitions for the project.
 embedded_set_target_compile_defines(TARGET ${PROJECT_NAME} LANGUAGE C DEFINES __thumb2__ __ARM_FEATURE_CMSE=3 TFM_LVL=${TFM_LVL} DAUTH_CHIP_DEFAULT APPEND)
-target_link_libraries(${PROJECT_NAME} tfm_storage tfm_secure_tests)
+
+if (REGRESSION OR CORE_TEST)
+	#The test service veneers may not be referenced in the secure binary so the
+	#veneer objects are explicitly loaded from the secure tests library.
+	target_link_libraries(${PROJECT_NAME} tfm_storage $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
+else()
+	target_link_libraries(${PROJECT_NAME} tfm_storage)
+endif()
 
 set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS " --predefine=\"-DTFM_LVL=${TFM_LVL}\"")
 
@@ -82,6 +89,12 @@
 	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DCORE_TEST_SERVICES\"")
 endif()
 
+if (NOT DEFINED SST_TEST_SERVICES)
+	message(FATAL_ERROR "Incomplete build configuration: SST_TEST_SERVICES is undefined. ")
+elseif (SST_TEST_SERVICES)
+	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DSST_TEST_SERVICES\"")
+endif()
+
 if (NOT DEFINED BL2)
 	message(FATAL_ERROR "Incomplete build configuration: BL2 is undefined. ")
 elseif (BL2)
@@ -122,4 +135,3 @@
 
 #Finally let cmake system apply changes after the whole project is defined.
 embedded_project_end(${PROJECT_NAME})
-
diff --git a/secure_fw/spm/service_defs.h b/secure_fw/spm/service_defs.h
index 9417f4e..7c8e292 100644
--- a/secure_fw/spm/service_defs.h
+++ b/secure_fw/spm/service_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,9 +15,19 @@
 
 /* FixMe: current implementation requires consecutive IDs, no gaps */
 #define TFM_SEC_FUNC_STORAGE_ID (TFM_SEC_FUNC_BASE + 0)
+
 #ifdef CORE_TEST_SERVICES
 #define TFM_SEC_FUNC_CORE_TEST_ID (TFM_SEC_FUNC_BASE + 1)
 #define TFM_SEC_FUNC_CORE_TEST_2_ID (TFM_SEC_FUNC_BASE + 2)
+
+/* Give SST test service next ID after core test services */
+#ifdef SST_TEST_SERVICES
+#define TFM_SEC_FUNC_SST_TEST_SERVICE_ID (TFM_SEC_FUNC_BASE + 3)
+#endif
+
+#elif defined(SST_TEST_SERVICES) /* CORE_TEST_SERVICES */
+/* Avoid creating a gap if core test services are not enabled */
+#define TFM_SEC_FUNC_SST_TEST_SERVICE_ID (TFM_SEC_FUNC_BASE + 1)
 #endif /* CORE_TEST_SERVICES */
 
 #endif /* __SERVICE_DEFS_H__ */
diff --git a/secure_fw/spm/user_service_defines.inc b/secure_fw/spm/user_service_defines.inc
index 77d2879..e3fbbf5 100644
--- a/secure_fw/spm/user_service_defines.inc
+++ b/secure_fw/spm/user_service_defines.inc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,21 +14,31 @@
 #include "service_defs.h"
 
 SERVICE_DECLARE(TFM_SEC_FUNC_STORAGE)
+
 #ifdef CORE_TEST_SERVICES
 SERVICE_DECLARE(TFM_SEC_FUNC_CORE_TEST)
 SERVICE_DECLARE(TFM_SEC_FUNC_CORE_TEST_2)
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+SERVICE_DECLARE(TFM_SEC_FUNC_SST_TEST_SERVICE)
+#endif /* SST_TEST_SERVICES */
+
 #elif !defined(__SPM_ADD_USER_SERVICES__) /*__SPM_DECLARE_USER_SERVICES__*/
 #define __SPM_ADD_USER_SERVICES__
 
 /* Order must be same as id!!! */
 SERVICE_ADD(TFM_SEC_FUNC_STORAGE)
+
 #ifdef CORE_TEST_SERVICES
 SERVICE_ADD(TFM_SEC_FUNC_CORE_TEST)
 SERVICE_ADD(TFM_SEC_FUNC_CORE_TEST_2)
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+SERVICE_ADD(TFM_SEC_FUNC_SST_TEST_SERVICE)
+#endif /* SST_TEST_SERVICES */
+
 SERVICE_ADD_INIT_FUNC(TFM_SEC_FUNC_STORAGE, sst_am_prepare)
 
 #ifdef CORE_TEST_SERVICES
@@ -39,6 +49,10 @@
 SERVICE_ADD_INIT_FUNC(TFM_SEC_FUNC_CORE_TEST_2, core_test_2_init)
 #endif /* CORE_TEST_SERVICES */
 
+#ifdef SST_TEST_SERVICES
+SERVICE_ADD_INIT_FUNC(TFM_SEC_FUNC_SST_TEST_SERVICE, sst_test_service_init)
+#endif /* SST_TEST_SERVICES */
+
 #else /* __SPM_ADD_USER_SERVICES__ */
 #error "unexpected inclusion of the file"
 #endif /* __SPM_ADD_USER_SERVICES__ */
diff --git a/test/test_services/CMakeLists.inc b/test/test_services/CMakeLists.inc
index d9121b0..c03c96e 100644
--- a/test/test_services/CMakeLists.inc
+++ b/test/test_services/CMakeLists.inc
@@ -42,6 +42,18 @@
 		)
 endif()
 
+if (NOT DEFINED SST_TEST_SERVICES)
+	message(FATAL_ERROR "Incomplete build configuration: SST_TEST_SERVICES is undefined. ")
+elseif (SST_TEST_SERVICES)
+	list(APPEND ALL_SRC_C_S "${CORE_TEST_DIR}/tfm_sst_test_service/sst_test_service.c"
+		"${CORE_TEST_DIR}/tfm_sst_test_service/sst_test_service_veneers.c"
+		)
+
+	list(APPEND ALL_SRC_C_NS "${CORE_TEST_DIR}/tfm_sst_test_service/sst_test_service_api.c"
+		"${CORE_TEST_DIR}/tfm_sst_test_service/sst_test_service_svc.c"
+		)
+endif()
+
 embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
 embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
 
@@ -62,4 +74,3 @@
 else()
 	include(${PLATFORM_CMAKE_FILE})
 endif()
-
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service.c b/test/test_services/tfm_sst_test_service/sst_test_service.c
new file mode 100644
index 0000000..50d8834
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_test_service.h"
+
+#include "secure_fw/core/tfm_secure_api.h"
+#include "secure_fw/services/secure_storage/assets/sst_asset_defs.h"
+#include "secure_fw/services/secure_storage/sst_utils.h"
+#include "tfm_sst_veneers.h"
+
+#define SST_TEST_SERVICE_KEY { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, \
+                               0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, }
+#define SST_TEST_SERVICE_KEY_SIZE SST_ASSET_MAX_SIZE_AES_KEY_128
+
+/**
+ * \brief Service initialisation function. No special initialisation is
+ *        required.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_init(void)
+{
+    return TFM_SST_ERR_SUCCESS;
+}
+
+enum tfm_sst_err_t sst_test_service_sfn_setup(void)
+{
+    enum tfm_sst_err_t err;
+    uint32_t app_id = S_APP_ID;
+    uint32_t key_handle;
+    uint16_t key_uuid = SST_ASSET_ID_AES_KEY_128;
+    uint8_t key_data[SST_TEST_SERVICE_KEY_SIZE] = SST_TEST_SERVICE_KEY;
+    struct tfm_sst_buf_t key_buf = { key_data, SST_TEST_SERVICE_KEY_SIZE, 0 };
+
+    /* Create the key asset using our secure app ID */
+    err = tfm_sst_veneer_create(app_id, key_uuid);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return err;
+    }
+
+    /* Get the handle of the key asset using our secure app ID */
+    err = tfm_sst_veneer_get_handle(app_id, key_uuid, &key_handle);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return err;
+    }
+
+    /* Write the key to the asset using our secure app ID */
+    err = tfm_sst_veneer_write(app_id, key_handle, &key_buf);
+
+    return err;
+}
+
+enum tfm_sst_err_t sst_test_service_sfn_dummy_encrypt(uint32_t app_id,
+                                                      uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size)
+{
+    enum tfm_sst_err_t err;
+    uint32_t i;
+    uint32_t key_handle;
+    uint8_t key_data[SST_TEST_SERVICE_KEY_SIZE];
+    struct tfm_sst_buf_t key_buf = { key_data, SST_TEST_SERVICE_KEY_SIZE, 0 };
+
+    /* Get the handle of the key asset using the non-secure caller's app ID */
+    err = tfm_sst_veneer_get_handle(app_id, key_uuid, &key_handle);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return err;
+    }
+
+    /* Read the key from the asset using the non-secure caller's app ID */
+    err = tfm_sst_veneer_read(app_id, key_handle, &key_buf);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return err;
+    }
+
+    /* Check the buffer is valid memory for the application that supplied it */
+    err = sst_utils_memory_bound_check(buf, buf_size, app_id,
+                                       TFM_MEMORY_ACCESS_RW);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return TFM_SST_ERR_PARAM_ERROR;
+    }
+
+    /* Encrypt the data (very badly) using the key from secure storage */
+    for (i = 0; i < buf_size; i++) {
+        buf[i] ^= key_data[i % SST_TEST_SERVICE_KEY_SIZE];
+    }
+
+    return TFM_SST_ERR_SUCCESS;
+}
+
+enum tfm_sst_err_t sst_test_service_sfn_dummy_decrypt(uint32_t app_id,
+                                                      uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size)
+{
+    /* In the current implementation encrypt and decrypt are the same operation
+     */
+    return sst_test_service_sfn_dummy_encrypt(app_id, key_uuid, buf, buf_size);
+}
+
+enum tfm_sst_err_t sst_test_service_sfn_clean(void)
+{
+    enum tfm_sst_err_t err;
+    uint32_t app_id = S_APP_ID;
+    uint32_t key_handle;
+    uint16_t key_uuid = SST_ASSET_ID_AES_KEY_128;
+
+    /* Get the handle of the key asset using our secure app ID */
+    err = tfm_sst_veneer_get_handle(app_id, key_uuid, &key_handle);
+    if (err != TFM_SST_ERR_SUCCESS) {
+        return err;
+    }
+
+    /* Delete the key asset using our secure app ID */
+    err = tfm_sst_veneer_delete(app_id, key_handle);
+
+    return err;
+}
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service.h b/test/test_services/tfm_sst_test_service/sst_test_service.h
new file mode 100644
index 0000000..1d5ca2c
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SST_TEST_SERVICE_H__
+#define __SST_TEST_SERVICE_H__
+
+#include <stdint.h>
+#include "tfm_sst_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Sets-up the SST test service so that it is ready for test functions to
+ *        be called.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_sfn_setup(void);
+
+/**
+ * \brief Performs a dummy encryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     app_id    Application ID
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Plaintext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_sfn_dummy_encrypt(uint32_t app_id,
+                                                      uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size);
+
+/**
+ * \brief Performs a dummy decryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     app_id    Application ID
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Ciphertext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_sfn_dummy_decrypt(uint32_t app_id,
+                                                      uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size);
+
+/**
+ * \brief Cleans the secure storage used by the SST test service.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_sfn_clean(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SST_TEST_SERVICE_H__ */
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_api.c b/test/test_services/tfm_sst_test_service/sst_test_service_api.c
new file mode 100644
index 0000000..ebfa44f
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_api.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_test_service_api.h"
+
+#include "tfm_ns_svc.h"
+
+__attribute__ ((naked))
+enum tfm_sst_err_t sst_test_service_setup(void)
+{
+    SVC(SVC_SST_TEST_SERVICE_SETUP);
+    __ASM("BX LR");
+}
+
+__attribute__ ((naked))
+enum tfm_sst_err_t sst_test_service_dummy_encrypt(uint16_t key_uuid,
+                                                  uint8_t *buf,
+                                                  uint32_t buf_size)
+{
+    SVC(SVC_SST_TEST_SERVICE_DUMMY_ENCRYPT);
+    __ASM("BX LR");
+}
+
+__attribute__ ((naked))
+enum tfm_sst_err_t sst_test_service_dummy_decrypt(uint16_t key_uuid,
+                                                  uint8_t *buf,
+                                                  uint32_t buf_size)
+{
+    SVC(SVC_SST_TEST_SERVICE_DUMMY_DECRYPT);
+    __ASM("BX LR");
+}
+
+__attribute__ ((naked))
+enum tfm_sst_err_t sst_test_service_clean(void)
+{
+    SVC(SVC_SST_TEST_SERVICE_CLEAN);
+    __ASM("BX LR");
+}
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_api.h b/test/test_services/tfm_sst_test_service/sst_test_service_api.h
new file mode 100644
index 0000000..3b5e2f6
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_api.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SST_TEST_SERVICE_API_H__
+#define __SST_TEST_SERVICE_API_H__
+
+#include <stdint.h>
+#include "tfm_sst_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Sets-up the SST test service so that it is ready for test functions to
+ *        be called.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_setup(void);
+
+/**
+ * \brief Performs a dummy encryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Plaintext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_dummy_encrypt(uint16_t key_uuid,
+                                                  uint8_t *buf,
+                                                  uint32_t buf_size);
+
+/**
+ * \brief Performs a dummy decryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Ciphertext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_dummy_decrypt(uint16_t key_uuid,
+                                                  uint8_t *buf,
+                                                  uint32_t buf_size);
+
+/**
+ * \brief Cleans the secure storage used by the SST test service.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_clean(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SST_TEST_SERVICE_API_H__ */
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_svc.c b/test/test_services/tfm_sst_test_service/sst_test_service_svc.c
new file mode 100644
index 0000000..467cd05
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_svc.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_test_service_svc.h"
+
+#include "sst_test_service_veneers.h"
+#include "tfm_id_mngr.h"
+
+enum tfm_sst_err_t sst_test_service_svc_setup(void)
+{
+    return sst_test_service_veneer_setup();
+}
+
+enum tfm_sst_err_t sst_test_service_svc_dummy_encrypt(uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return sst_test_service_veneer_dummy_encrypt(app_id, key_uuid, buf,
+                                                 buf_size);
+}
+
+enum tfm_sst_err_t sst_test_service_svc_dummy_decrypt(uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return sst_test_service_veneer_dummy_decrypt(app_id, key_uuid, buf,
+                                                 buf_size);
+}
+
+enum tfm_sst_err_t sst_test_service_svc_clean(void)
+{
+    return sst_test_service_veneer_clean();
+}
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_svc.h b/test/test_services/tfm_sst_test_service/sst_test_service_svc.h
new file mode 100644
index 0000000..1b04745
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_svc.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SST_TEST_SERVICE_SVC_H__
+#define __SST_TEST_SERVICE_SVC_H__
+
+#include <stdint.h>
+#include "tfm_sst_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Sets-up the SST test service so that it is ready for test functions to
+ *        be called.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_svc_setup(void);
+
+/**
+ * \brief Performs a dummy encryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Plaintext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_svc_dummy_encrypt(uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size);
+
+/**
+ * \brief Performs a dummy decryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Ciphertext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_svc_dummy_decrypt(uint16_t key_uuid,
+                                                      uint8_t *buf,
+                                                      uint32_t buf_size);
+
+/**
+ * \brief Cleans the secure storage used by the SST test service.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_svc_clean(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SST_TEST_SERVICE_SVC_H__ */
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_veneers.c b/test/test_services/tfm_sst_test_service/sst_test_service_veneers.c
new file mode 100644
index 0000000..802ba59
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_veneers.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_test_service_veneers.h"
+
+#include "sst_test_service.h"
+#include "secure_fw/core/tfm_secure_api.h"
+#include "secure_fw/spm/service_defs.h"
+
+enum tfm_sst_err_t sst_test_service_veneer_setup(void)
+{
+    TFM_CORE_SERVICE_REQUEST(TFM_SEC_FUNC_SST_TEST_SERVICE_ID,
+                             sst_test_service_sfn_setup,
+                             0, 0, 0, 0);
+}
+
+enum tfm_sst_err_t sst_test_service_veneer_dummy_encrypt(uint32_t app_id,
+                                                         uint16_t key_uuid,
+                                                         uint8_t *buf,
+                                                         uint32_t buf_size)
+{
+    TFM_CORE_SERVICE_REQUEST(TFM_SEC_FUNC_SST_TEST_SERVICE_ID,
+                             sst_test_service_sfn_dummy_encrypt,
+                             app_id, key_uuid, buf, buf_size);
+}
+
+enum tfm_sst_err_t sst_test_service_veneer_dummy_decrypt(uint32_t app_id,
+                                                         uint16_t key_uuid,
+                                                         uint8_t *buf,
+                                                         uint32_t buf_size)
+{
+    TFM_CORE_SERVICE_REQUEST(TFM_SEC_FUNC_SST_TEST_SERVICE_ID,
+                             sst_test_service_sfn_dummy_decrypt,
+                             app_id, key_uuid, buf, buf_size);
+}
+
+enum tfm_sst_err_t sst_test_service_veneer_clean(void)
+{
+    TFM_CORE_SERVICE_REQUEST(TFM_SEC_FUNC_SST_TEST_SERVICE_ID,
+                             sst_test_service_sfn_clean,
+                             0, 0, 0, 0);
+}
diff --git a/test/test_services/tfm_sst_test_service/sst_test_service_veneers.h b/test/test_services/tfm_sst_test_service/sst_test_service_veneers.h
new file mode 100644
index 0000000..4171d28
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/sst_test_service_veneers.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SST_TEST_SERVICE_VENEERS_H__
+#define __SST_TEST_SERVICE_VENEERS_H__
+
+#include <stdint.h>
+#include "tfm_sst_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __cmse_secure_gateway \
+__attribute__((cmse_nonsecure_entry, noinline, section("SFN")))
+
+/**
+ * \brief Sets-up the SST test service so that it is ready for test functions to
+ *        be called.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_veneer_setup(void)
+__cmse_secure_gateway;
+
+/**
+ * \brief Performs a dummy encryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     app_id    Application ID
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Plaintext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_veneer_dummy_encrypt(uint32_t app_id,
+                                                         uint16_t key_uuid,
+                                                         uint8_t *buf,
+                                                         uint32_t buf_size)
+__cmse_secure_gateway;
+
+/**
+ * \brief Performs a dummy decryption on the supplied buffer, using the key
+ *        stored in the asset with the given UUID.
+ *
+ * \param[in]     app_id    Application ID
+ * \param[in]     key_uuid  UUID of asset containing key
+ * \param[in,out] buf       Ciphertext buffer
+ * \param[in]     buf_size  Size of buf
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_veneer_dummy_decrypt(uint32_t app_id,
+                                                         uint16_t key_uuid,
+                                                         uint8_t *buf,
+                                                         uint32_t buf_size)
+__cmse_secure_gateway;
+
+/**
+ * \brief Cleans the secure storage used by the SST test service.
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t sst_test_service_veneer_clean(void)
+__cmse_secure_gateway;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SST_TEST_SERVICE_VENEERS_H__ */