Attest: Add IPC compatibility

1. Add IPC implementation for both secure and non-secure Initial
   Attestation APIs.
2. Update Initial Attestation Service manifest to support IPC model.
3. Add thread like behaviour to receive and handle requests according
   to IPC model.

Change-Id: Ia27a9e9661ed716bc7eb84d6f077252e0319a586
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
Co-authored-by: Moran Peker <moran.peker@arm.com>
diff --git a/docs/user_guides/services/tfm_attestation_integration_guide.rst b/docs/user_guides/services/tfm_attestation_integration_guide.rst
index e4d49a2..2bbd148 100644
--- a/docs/user_guides/services/tfm_attestation_integration_guide.rst
+++ b/docs/user_guides/services/tfm_attestation_integration_guide.rst
@@ -174,6 +174,9 @@
         - ``tfm_attestation_secure_api.c``: Implements the secure API layer to
           allow other services in the secure domain to request functionalities
           from the attestation service using the PSA API interface.
+        - ``tfm_attestation_req_mngr.c``: Includes the initialization entry of
+          attestation service and handles attestation service requests in IPC
+          model.
 
 Service interface definitions
 =============================
diff --git a/interface/include/tfm_attest_defs.h b/interface/include/tfm_attest_defs.h
new file mode 100644
index 0000000..5cbca7a
--- /dev/null
+++ b/interface/include/tfm_attest_defs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_ATTEST_DEFS_H__
+#define __TFM_ATTEST_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef TFM_PSA_API
+/*
+ * Defines for SID and minor version number. These SIDs must align with the
+ * value in service manifest file.
+ */
+#define TFM_ATTEST_GET_TOKEN_SID               (0x00000020)
+#define TFM_ATTEST_GET_TOKEN_MINOR_VER         (0x0001)
+#define TFM_ATTEST_GET_TOKEN_SIZE_SID          (0x00000021)
+#define TFM_ATTEST_GET_TOKEN_SIZE_MINOR_VER    (0x0001)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_ATTEST_DEFS_H__ */
\ No newline at end of file
diff --git a/interface/src/tfm_initial_attestation_api.c b/interface/src/tfm_initial_attestation_api.c
index ae58701..826c667 100644
--- a/interface/src/tfm_initial_attestation_api.c
+++ b/interface/src/tfm_initial_attestation_api.c
@@ -9,6 +9,11 @@
 #include "tfm_veneers.h"
 #include "tfm_ns_lock.h"
 #include "psa_client.h"
+#ifdef TFM_PSA_API
+#include "tfm_attest_defs.h"
+#endif
+
+#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
 
 enum psa_attest_err_t
 psa_initial_attest_get_token(const uint8_t *challenge_obj,
@@ -16,40 +21,89 @@
                              uint8_t       *token,
                              uint32_t      *token_size)
 {
-    psa_invec  in_vec[1];
-    psa_outvec out_vec[1];
+#ifdef TFM_PSA_API
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    psa_status_t status;
+#else
     uint32_t res;
+#endif
+    psa_invec in_vec[] = {
+        {challenge_obj, challenge_size}
+    };
+    psa_outvec out_vec[] = {
+        {token, *token_size}
+    };
 
-    in_vec[0].base = challenge_obj;
-    in_vec[0].len  = challenge_size;
+#ifdef TFM_PSA_API
+    handle = psa_connect(TFM_ATTEST_GET_TOKEN_SID,
+                         TFM_ATTEST_GET_TOKEN_MINOR_VER);
+    if (handle <= 0) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
 
-    out_vec[0].base = token;
-    out_vec[0].len  = *token_size;
+    status = psa_call(handle,
+                      in_vec, IOVEC_LEN(in_vec),
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
 
+    if (status < PSA_SUCCESS) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    if (status == PSA_SUCCESS) {
+        *token_size = out_vec[0].len;
+    }
+
+    return (enum psa_attest_err_t)status;
+#else
     res = tfm_ns_lock_dispatch((veneer_fn)tfm_initial_attest_get_token_veneer,
-                                (uint32_t)in_vec,  1,
-                                (uint32_t)out_vec, 1);
+                               (uint32_t)in_vec,  IOVEC_LEN(in_vec),
+                               (uint32_t)out_vec, IOVEC_LEN(out_vec));
 
-    *token_size = out_vec[0].len;
+    if (res == PSA_ATTEST_ERR_SUCCESS) {
+        *token_size = out_vec[0].len;
+    }
 
-    return res;
+    return (enum psa_attest_err_t)res;
+#endif
 }
 
 enum psa_attest_err_t
 psa_initial_attest_get_token_size(uint32_t  challenge_size,
                                   uint32_t *token_size)
 {
-    psa_invec  in_vec[1];
-    psa_outvec out_vec[1];
+#ifdef TFM_PSA_API
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    psa_status_t status;
+#endif
+    psa_invec in_vec[] = {
+        {&challenge_size, sizeof(challenge_size)}
+    };
+    psa_outvec out_vec[] = {
+        {token_size, sizeof(uint32_t)}
+    };
 
-    in_vec[0].base = &challenge_size;
-    in_vec[0].len  = sizeof(uint32_t);
+#ifdef TFM_PSA_API
+    handle = psa_connect(TFM_ATTEST_GET_TOKEN_SIZE_SID,
+                         TFM_ATTEST_GET_TOKEN_SIZE_MINOR_VER);
+    if (handle <= 0) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
 
-    out_vec[0].base = token_size;
-    out_vec[0].len  = sizeof(uint32_t);
+    status = psa_call(handle,
+                      in_vec, IOVEC_LEN(in_vec),
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
 
-    return tfm_ns_lock_dispatch((veneer_fn) \
-                                tfm_initial_attest_get_token_size_veneer,
-                                (uint32_t)in_vec,  1,
-                                (uint32_t)out_vec, 1);
+    if (status < PSA_SUCCESS) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    return (enum psa_attest_err_t)status;
+#else
+    return (enum psa_attest_err_t)tfm_ns_lock_dispatch(
+                            (veneer_fn)tfm_initial_attest_get_token_size_veneer,
+                            (uint32_t)in_vec,  IOVEC_LEN(in_vec),
+                            (uint32_t)out_vec, IOVEC_LEN(out_vec));
+#endif
 }
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 1402bd0..67bb195 100644
--- a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
+++ b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
@@ -11,7 +11,8 @@
 #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 "secure_fw/services/crypto/tfm_crypto_signal.h"
-#include "secure_fw/services/secure_storage/tfm_sst_signal.h"
 #include "test/test_services/tfm_secure_client_service/tfm_sec_client_ser_sig.h"
+#include "secure_fw/services/secure_storage/tfm_sst_signal.h"
+#include "secure_fw/services/initial_attestation/tfm_attest_signal.h"
 
 #endif /* __TFM_SPM_SIGNAL_DEFS_H__ */
diff --git a/secure_fw/services/initial_attestation/CMakeLists.inc b/secure_fw/services/initial_attestation/CMakeLists.inc
index 831c910..bdfdcd5 100644
--- a/secure_fw/services/initial_attestation/CMakeLists.inc
+++ b/secure_fw/services/initial_attestation/CMakeLists.inc
@@ -35,6 +35,7 @@
 	list(APPEND ALL_SRC_C
 		"${INITIAL_ATTESTATION_DIR}/tfm_attestation_secure_api.c"
 		"${INITIAL_ATTESTATION_DIR}/tfm_attestation.c"
+		"${INITIAL_ATTESTATION_DIR}/tfm_attestation_req_mngr.c"
 		"${INITIAL_ATTESTATION_DIR}/attestation_core.c"
 		"${INITIAL_ATTESTATION_DIR}/attestation_crypto_stub.c"
 		"${INITIAL_ATTESTATION_DIR}/attestation_key.c"
diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c
index 2bb79c6..fa11e61 100644
--- a/secure_fw/services/initial_attestation/attestation_core.c
+++ b/secure_fw/services/initial_attestation/attestation_core.c
@@ -663,7 +663,7 @@
 attest_add_caller_id_claim(struct attest_token_ctx *token_ctx)
 {
     enum psa_attest_err_t res;
-    int32_t  caller_id;
+    int32_t caller_id;
 
     res = attest_get_caller_client_id(&caller_id);
     if (res != PSA_ATTEST_ERR_SUCCESS) {
diff --git a/secure_fw/services/initial_attestation/manifest.yaml b/secure_fw/services/initial_attestation/manifest.yaml
index 24dbf33..2559640 100644
--- a/secure_fw/services/initial_attestation/manifest.yaml
+++ b/secure_fw/services/initial_attestation/manifest.yaml
@@ -10,10 +10,10 @@
   "type": "PSA-ROT",
   "priority": "NORMAL",
   "id": "0x00000103",
-  "entry_point": "attest_init",
+  "entry_point": "attest_partition_init",
   "stack_size": "0x0A00",
   "heap_size": "0x0400",
-  "tfm_init_symbol": "attest_init",
+  "tfm_partition_ipc": true,
   "secure_functions": [
     {
       "sfid": "TFM_ATTEST_GET_TOKEN_SFID",
@@ -38,10 +38,29 @@
     "attestation_key.c",
     "attest_token.c",
     "tfm_attestation.c",
+    "tfm_attestation_req_mngr.c",
   ],
   "tfm_linker_pattern": {
     "library_list": [
       "*tfm_attest*"
     ]
-  }
+  },
+  "services": [
+    {
+      "name": "TFM_ATTEST_GET_TOKEN_SID",
+      "sid": "0x00000020",
+      "signal": "PSA_ATTEST_GET_TOKEN_SIG",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    },
+    {
+      "name": "TFM_ATTEST_GET_TOKEN_SIZE_SID",
+      "sid": "0x00000021",
+      "signal": "PSA_ATTEST_GET_TOKEN_SIZE_SIG",
+      "non_secure_clients": "true",
+      "minor_version": 1,
+      "minor_policy": "STRICT"
+    }
+  ]
 }
diff --git a/secure_fw/services/initial_attestation/tfm_attest_signal.h b/secure_fw/services/initial_attestation/tfm_attest_signal.h
new file mode 100644
index 0000000..2acd0fd
--- /dev/null
+++ b/secure_fw/services/initial_attestation/tfm_attest_signal.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_ATTEST_SIGNAL_H__
+#define __TFM_ATTEST_SIGNAL_H__
+
+/* FixMe: hardcode it since the tool cannot support now */
+#define PSA_ATTEST_GET_TOKEN_SIG         (1 << (0 + 4))
+#define PSA_ATTEST_GET_TOKEN_SIZE_SIG    (1 << (1 + 4))
+
+#endif /* __TFM_ATTEST_SIGNAL_H__ */
\ No newline at end of file
diff --git a/secure_fw/services/initial_attestation/tfm_attestation.c b/secure_fw/services/initial_attestation/tfm_attestation.c
index 4dca76a..94b6caa 100644
--- a/secure_fw/services/initial_attestation/tfm_attestation.c
+++ b/secure_fw/services/initial_attestation/tfm_attestation.c
@@ -11,18 +11,24 @@
 #include "psa_initial_attestation_api.h"
 #include "bl2/include/tfm_boot_status.h"
 
+#ifdef TFM_PSA_API
+extern int32_t g_attest_caller_id;
+#endif
+
 enum psa_attest_err_t
 attest_check_memory_access(void *addr,
                            uint32_t size,
                            enum attest_memory_access_t access)
 {
-    enum tfm_status_e tfm_res;
     enum psa_attest_err_t attest_res = PSA_ATTEST_ERR_SUCCESS;
+#ifndef TFM_PSA_API
+    enum tfm_status_e tfm_res;
 
     tfm_res = tfm_core_memory_permission_check(addr, size, access);
     if (tfm_res) {
         attest_res =  PSA_ATTEST_ERR_INVALID_INPUT;
      }
+#endif
 
      return attest_res;
 }
@@ -30,13 +36,17 @@
 enum psa_attest_err_t
 attest_get_caller_client_id(int32_t *caller_id)
 {
-    enum tfm_status_e tfm_res;
     enum psa_attest_err_t attest_res = PSA_ATTEST_ERR_SUCCESS;
+#ifndef TFM_PSA_API
+    enum tfm_status_e tfm_res;
 
     tfm_res =  tfm_core_get_caller_client_id(caller_id);
     if (tfm_res) {
         attest_res =  PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
      }
+#else
+    *caller_id = g_attest_caller_id;
+#endif
 
     return attest_res;
 }
diff --git a/secure_fw/services/initial_attestation/tfm_attestation_req_mngr.c b/secure_fw/services/initial_attestation/tfm_attestation_req_mngr.c
new file mode 100644
index 0000000..d899bc6
--- /dev/null
+++ b/secure_fw/services/initial_attestation/tfm_attestation_req_mngr.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+#include "psa_initial_attestation_api.h"
+#include "attestation.h"
+
+#ifdef TFM_PSA_API
+#include "tfm_attest_signal.h"
+#include "tfm_client.h"
+#include "psa_service.h"
+#include "region_defs.h"
+
+#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
+
+typedef enum psa_attest_err_t (*attest_func_t)(const psa_msg_t *msg);
+
+int32_t g_attest_caller_id;
+
+static enum psa_attest_err_t psa_attest_get_token(const psa_msg_t *msg)
+{
+    enum psa_attest_err_t status = PSA_ATTEST_ERR_SUCCESS;
+    uint8_t challenge_buff[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
+    uint8_t token_buff[PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE];
+    uint32_t bytes_read = 0;
+    size_t challenge_size = msg->in_size[0];
+    size_t token_size = msg->out_size[0];
+    psa_invec in_vec[] = {
+        {challenge_buff, challenge_size}
+    };
+    psa_outvec out_vec[] = {
+        {token_buff, token_size}
+    };
+
+    if (challenge_size > PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64) {
+        return PSA_ATTEST_ERR_INVALID_INPUT;
+    }
+
+    /* store the client ID here for later use in service */
+    g_attest_caller_id = msg->client_id;
+
+    bytes_read = psa_read(msg->handle, 0,
+                          challenge_buff, challenge_size);
+    if (bytes_read != challenge_size) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    token_size = (token_size < PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE) ?
+                  token_size : PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE;
+
+    status = initial_attest_get_token(in_vec, IOVEC_LEN(in_vec),
+                                      out_vec, IOVEC_LEN(out_vec));
+    if (status == PSA_ATTEST_ERR_SUCCESS) {
+        psa_write(msg->handle, 0, out_vec[0].base, out_vec[0].len);
+    }
+
+    return status;
+}
+
+static enum psa_attest_err_t psa_attest_get_token_size(const psa_msg_t *msg)
+{
+    enum psa_attest_err_t status = PSA_ATTEST_ERR_SUCCESS;
+    uint32_t challenge_size;
+    uint32_t token_size;
+    uint32_t bytes_read = 0;
+    psa_invec in_vec[] = {
+        {&challenge_size, msg->in_size[0]}
+    };
+    psa_outvec out_vec[] = {
+        {&token_size, msg->out_size[0]}
+    };
+
+    if (msg->in_size[0] != sizeof(challenge_size)
+        || msg->out_size[0] != sizeof(token_size)) {
+        return PSA_ATTEST_ERR_INVALID_INPUT;
+    }
+
+    /* store the client ID here for later use in service */
+    g_attest_caller_id = msg->client_id;
+
+    bytes_read = psa_read(msg->handle, 0,
+                          &challenge_size, msg->in_size[0]);
+    if (bytes_read != msg->in_size[0]) {
+        return PSA_ATTEST_ERR_INVALID_INPUT;
+    }
+
+    status = initial_attest_get_token_size(in_vec, IOVEC_LEN(in_vec),
+                                           out_vec, IOVEC_LEN(out_vec));
+    if (status == PSA_ATTEST_ERR_SUCCESS) {
+        psa_write(msg->handle, 0, out_vec[0].base, out_vec[0].len);
+    }
+
+    return status;
+}
+
+/*
+ * Fixme: Temporarily implement abort as infinite loop,
+ * will replace it later.
+ */
+static void tfm_abort(void)
+{
+    while (1)
+        ;
+}
+
+static void attest_signal_handle(psa_signal_t signal, attest_func_t pfn)
+{
+    psa_msg_t msg;
+    psa_status_t status;
+
+    status = psa_get(signal, &msg);
+    switch (msg.type) {
+    case PSA_IPC_CONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    case PSA_IPC_CALL:
+        status = (psa_status_t)pfn(&msg);
+        psa_reply(msg.handle, status);
+        break;
+    case PSA_IPC_DISCONNECT:
+        psa_reply(msg.handle, PSA_SUCCESS);
+        break;
+    default:
+        tfm_abort();
+    }
+}
+#endif
+
+enum psa_attest_err_t attest_partition_init(void)
+{
+    enum psa_attest_err_t err = PSA_ATTEST_ERR_SUCCESS;
+#ifdef TFM_PSA_API
+    psa_signal_t signals;
+#endif
+
+    err = attest_init();
+#ifdef TFM_PSA_API
+    if (err != PSA_ATTEST_ERR_SUCCESS) {
+        tfm_abort();
+    }
+
+    while (1) {
+        signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+        if (signals & PSA_ATTEST_GET_TOKEN_SIG) {
+            attest_signal_handle(PSA_ATTEST_GET_TOKEN_SIG,
+                                 psa_attest_get_token);
+        } else if (signals & PSA_ATTEST_GET_TOKEN_SIZE_SIG) {
+            attest_signal_handle(PSA_ATTEST_GET_TOKEN_SIZE_SIG,
+                                 psa_attest_get_token_size);
+        } else {
+            tfm_abort();
+        }
+    }
+#endif
+    return err;
+}
diff --git a/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c b/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c
index acd9878..8819a81 100644
--- a/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c
+++ b/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c
@@ -10,12 +10,19 @@
 #include "tfm_memory_utils.h"
 #include "tfm_client.h"
 #include "tfm_secure_api.h"
+#ifdef TFM_PSA_API
+#include "tfm_attest_defs.h"
+#endif
 #include <string.h>
 
+#ifndef TFM_PSA_API
 /* FIXME: If iovec will be supported by SPM then remove the usage of
  * scratch area.
  */
 extern uint8_t *tfm_scratch_area;
+#else
+#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
+#endif
 
 __attribute__((section("SFN")))
 enum psa_attest_err_t
@@ -24,12 +31,42 @@
                              uint8_t       *token,
                              uint32_t      *token_size)
 {
-    enum psa_attest_err_t err;
+    psa_status_t status;
+#ifdef TFM_PSA_API
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    psa_invec in_vec[] = {
+        {challenge_obj, challenge_size}
+    };
+    psa_outvec out_vec[] = {
+        {token, *token_size}
+    };
+#else
     psa_invec *in_vec;
     psa_outvec *out_vec;
     uint8_t *challenge_buff;
     uint8_t *token_buff;
+#endif
 
+#ifdef TFM_PSA_API
+    handle = psa_connect(TFM_ATTEST_GET_TOKEN_SID,
+                         TFM_ATTEST_GET_TOKEN_MINOR_VER);
+    if (handle <= 0) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    status = psa_call(handle,
+                      in_vec, IOVEC_LEN(in_vec),
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
+
+    if (status < PSA_SUCCESS) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    if (status == PSA_SUCCESS) {
+        *token_size = out_vec[0].len;
+    }
+#else
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
         return PSA_ATTEST_ERR_GENERAL;
     }
@@ -50,38 +87,61 @@
     /* Copy challenge object to scratch area */
     tfm_memcpy(challenge_buff, challenge_obj, challenge_size);
 
-
     in_vec[0].base = challenge_buff;
     in_vec[0].len  = challenge_size;
 
     out_vec[0].base = token_buff;
     out_vec[0].len  = *token_size;
 
-    err = tfm_initial_attest_get_token_veneer(in_vec, 1, out_vec, 1);
-    if (err != PSA_ATTEST_ERR_SUCCESS) {
-        return err;
+    status = tfm_initial_attest_get_token_veneer(in_vec, 1, out_vec, 1);
+    if (status == PSA_ATTEST_ERR_SUCCESS) {
+        tfm_memcpy(token, out_vec[0].base, out_vec[0].len);
+        *token_size = out_vec[0].len;
     }
+#endif
 
-    /* Copy output token to local buffer */
-    tfm_memcpy(token, out_vec[0].base, out_vec[0].len);
-    *token_size = out_vec[0].len;
-
-    return err;
+    return (enum psa_attest_err_t)status;
 }
 
 __attribute__((section("SFN")))
 enum psa_attest_err_t
-psa_initial_attest_get_token_size(uint32_t  challenge_size,
+psa_initial_attest_get_token_size(uint32_t challenge_size,
                                   uint32_t *token_size)
 {
-    enum psa_attest_err_t err;
+    psa_status_t status;
+#ifdef TFM_PSA_API
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    psa_invec in_vec[] = {
+        {&challenge_size, sizeof(challenge_size) }
+    };
+    psa_outvec out_vec[] = {
+        {token_size, sizeof(uint32_t)}
+    };
+#else
     struct paramters_t {
         psa_invec in_vec;
         uint32_t challenge_size;
         psa_outvec out_vec;
         uint32_t token_size;
     };
+#endif
 
+#ifdef TFM_PSA_API
+    handle = psa_connect(TFM_ATTEST_GET_TOKEN_SIZE_SID,
+                         TFM_ATTEST_GET_TOKEN_SIZE_MINOR_VER);
+    if (handle <= 0) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    status = psa_call(handle,
+                      in_vec, IOVEC_LEN(in_vec),
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
+
+    if (status < PSA_SUCCESS) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+#else
     if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
         return PSA_ATTEST_ERR_GENERAL;
     }
@@ -99,12 +159,12 @@
     param->out_vec.base = &param->token_size;
     param->out_vec.len  = sizeof(uint32_t);
 
-    err = tfm_initial_attest_get_token_size_veneer(&param->in_vec,  1,
-                                                   &param->out_vec, 1);
-    if (err != PSA_ATTEST_ERR_SUCCESS) {
-        return err;
+    status = tfm_initial_attest_get_token_size_veneer(&param->in_vec,  1,
+                                                      &param->out_vec, 1);
+    if (status == PSA_ATTEST_ERR_SUCCESS) {
+        *token_size = param->token_size;
     }
-    *token_size = param->token_size;
+#endif
 
-    return err;
+    return (enum psa_attest_err_t)status;
 }
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index bd57977..f5edad6 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -37,8 +37,9 @@
 
 /******** TFM_SP_INITIAL_ATTESTATION ********/
 PARTITION_DECLARE(TFM_SP_INITIAL_ATTESTATION, 0
+    | SPM_PART_FLAG_IPC
     , "PSA-ROT", 0x00000103, NORMAL);
-PARTITION_ADD_INIT_FUNC(TFM_SP_INITIAL_ATTESTATION, attest_init);
+PARTITION_ADD_INIT_FUNC(TFM_SP_INITIAL_ATTESTATION, attest_partition_init);
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index a7c1e6a..3bc40c7 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -70,6 +70,25 @@
 },
 
 
+/******** TFM_SP_INITIAL_ATTESTATION ********/
+{
+        "TFM_ATTEST_GET_TOKEN_SID",
+        TFM_SP_INITIAL_ATTESTATION_ID,
+        PSA_ATTEST_GET_TOKEN_SIG,
+        0x00000020,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
+{
+        "TFM_ATTEST_GET_TOKEN_SIZE_SID",
+        TFM_SP_INITIAL_ATTESTATION_ID,
+        PSA_ATTEST_GET_TOKEN_SIZE_SIG,
+        0x00000021,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
diff --git a/test/framework/non_secure_suites.c b/test/framework/non_secure_suites.c
index bc8a731..ba37848 100644
--- a/test/framework/non_secure_suites.c
+++ b/test/framework/non_secure_suites.c
@@ -44,6 +44,12 @@
     /* Non-secure Crypto test cases */
     {&register_testsuite_ns_crypto_interface, 0, 0, 0},
 
+    /* Non-secure initial attestation service test cases */
+    {&register_testsuite_ns_attestation_interface, 0, 0, 0},
+
+    /* Non-secure QCBOR library test cases */
+    {&register_testsuite_ns_qcbor, 0, 0, 0},
+
 #ifndef TFM_PSA_API
     /*
      * FixMe: skip below test cases temporary since target service is not
@@ -52,11 +58,6 @@
     /* Non-secure Audit Logging test cases */
     {&register_testsuite_ns_audit_interface, 0, 0, 0},
 
-    /* Non-secure initial attestation service test cases */
-    {&register_testsuite_ns_attestation_interface, 0, 0, 0},
-
-    /* Non-secure QCBOR library test cases */
-    {&register_testsuite_ns_qcbor, 0, 0, 0},
 #endif
 
 #ifdef TFM_PARTITION_TEST_CORE
diff --git a/test/framework/secure_suites.c b/test/framework/secure_suites.c
index 80f7ee8..3c86fa2 100644
--- a/test/framework/secure_suites.c
+++ b/test/framework/secure_suites.c
@@ -38,6 +38,9 @@
     /* Crypto test cases */
     {&register_testsuite_s_crypto_interface, 0, 0, 0},
 
+    /* Secure initial attestation service test cases */
+    {&register_testsuite_s_attestation_interface, 0, 0, 0},
+
 #ifndef TFM_PSA_API
     /*
      * FixMe: since the following partitions haven't implement the IPC model,
@@ -46,8 +49,6 @@
     /* Secure Audit Logging test cases */
     {&register_testsuite_s_audit_interface, 0, 0, 0},
 
-    /* Secure initial attestation service test cases */
-    {&register_testsuite_s_attestation_interface, 0, 0, 0},
 #endif
 
 #ifdef TFM_PARTITION_TEST_CORE