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/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__ */