Test: Refine attestation test service

- Move IAK read operation from service init step into specific client
  call handling. OTP read may fail on some develop boards at earlier
  init stage.
- Split the secure and non-secure interface APIs.

Signed-off-by: David Hu <david.hu@arm.com>
Change-Id: I8be534398b5e79dda725f0c0f62296466133c9e7
diff --git a/test/test_services/tfm_attest_test_service/CMakeLists.txt b/test/test_services/tfm_attest_test_service/CMakeLists.txt
index 0674e78..851c95c 100644
--- a/test/test_services/tfm_attest_test_service/CMakeLists.txt
+++ b/test/test_services/tfm_attest_test_service/CMakeLists.txt
@@ -78,12 +78,12 @@
 
 target_sources(tfm_api_ns
     PRIVATE
-        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_attest_test_service_api.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_attest_test_service_ns_api.c
 )
 
 # The veneers give warnings about not being properly declared so they get hidden
 # to not overshadow _real_ warnings.
-set_source_files_properties(tfm_attest_test_service_api.c
+set_source_files_properties(tfm_attest_test_service_ns_api.c
     PROPERTIES
         COMPILE_FLAGS -Wno-implicit-function-declaration
 )
@@ -97,12 +97,12 @@
 
 target_sources(tfm_secure_api
     INTERFACE
-        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_attest_test_service_api.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_attest_test_service_secure_api.c
 )
 
 # The veneers give warnings about not being properly declared so they get hidden
 # to not overshadow _real_ warnings.
-set_source_files_properties(tfm_attest_test_service_api.c
+set_source_files_properties(tfm_attest_test_service_secure_api.c
     PROPERTIES
         COMPILE_FLAGS -Wno-implicit-function-declaration
 )
diff --git a/test/test_services/tfm_attest_test_service/tfm_attest_test_service.c b/test/test_services/tfm_attest_test_service/tfm_attest_test_service.c
index b8e1170..691d870 100644
--- a/test/test_services/tfm_attest_test_service/tfm_attest_test_service.c
+++ b/test/test_services/tfm_attest_test_service/tfm_attest_test_service.c
@@ -69,9 +69,10 @@
 static size_t  attestation_public_key_len = 0;
 static psa_ecc_family_t attestation_key_curve;
 
+static bool is_public_key_exported = false;
+
 static psa_status_t attest_export_public_key(void)
 {
-
     enum tfm_plat_err_t plat_res;
     psa_ecc_family_t psa_curve;
     struct ecc_key_t attest_key = {0};
@@ -118,6 +119,18 @@
 #ifdef TFM_PSA_API
 static psa_status_t attest_test_get_public_key(const psa_msg_t *msg)
 {
+    psa_status_t err;
+
+    /* Skip the export operation if the public key has been already exported. */
+    if (!is_public_key_exported) {
+        err = attest_export_public_key();
+        if (err != PSA_SUCCESS) {
+            return err;
+        }
+
+        is_public_key_exported = true;
+    }
+
     if (msg->out_size[0] < attestation_public_key_len) {
         return PSA_ERROR_BUFFER_TOO_SMALL;
     }
@@ -162,12 +175,6 @@
 psa_status_t tfm_attest_test_service_init(void)
 {
     psa_signal_t signals;
-    psa_status_t err;
-
-    err = attest_export_public_key();
-    if (err != PSA_SUCCESS) {
-        psa_panic();
-    }
 
     while (1) {
         signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
@@ -181,8 +188,6 @@
     return PSA_ERROR_SERVICE_FAILURE;
 }
 #else /* TFM_PSA_API */
-static bool is_public_key_exported = false;
-
 psa_status_t tfm_attest_test_get_public_key(const psa_invec *in_vec,
                                             uint32_t num_invec,
                                             psa_outvec *out_vec,
diff --git a/test/test_services/tfm_attest_test_service/tfm_attest_test_service_ns_api.c b/test/test_services/tfm_attest_test_service/tfm_attest_test_service_ns_api.c
new file mode 100644
index 0000000..fc426b6
--- /dev/null
+++ b/test/test_services/tfm_attest_test_service/tfm_attest_test_service_ns_api.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa/crypto.h"
+#include "tfm_attest_test_service_api.h"
+#ifdef TFM_PSA_API
+#include "psa/client.h"
+#include "tfm_api.h"
+#include "psa_manifest/sid.h"
+#else /* TFM_PSA_API */
+#include "tfm_veneers.h"
+#include "tfm_ns_interface.h"
+#endif /* TFM_PSA_API */
+
+psa_status_t tfm_initial_attest_get_public_key(uint8_t *public_key,
+                                               size_t  public_key_buf_size,
+                                               size_t  *public_key_len,
+                                               psa_ecc_family_t *curve_type)
+{
+    psa_status_t status;
+
+    psa_outvec out_vec[] = {
+        {.base = public_key,     .len = public_key_buf_size},
+        {.base = curve_type,     .len = sizeof(*curve_type)},
+        {.base = public_key_len, .len = sizeof(*public_key_len)}
+    };
+
+#ifdef TFM_PSA_API
+    psa_handle_t handle = PSA_NULL_HANDLE;
+
+    handle = psa_connect(TFM_ATTEST_TEST_GET_PUBLIC_KEY_SID,
+                         TFM_ATTEST_TEST_GET_PUBLIC_KEY_VERSION);
+    if (!PSA_HANDLE_IS_VALID(handle)) {
+        return PSA_HANDLE_TO_ERROR(handle);
+    }
+
+    status = psa_call(handle, PSA_IPC_CALL, NULL, 0,
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
+#else
+    status = tfm_ns_interface_dispatch(
+                               (veneer_fn)tfm_attest_test_get_public_key_veneer,
+                               NULL, 0, out_vec, IOVEC_LEN(out_vec));
+#endif
+
+    return status;
+}
diff --git a/test/test_services/tfm_attest_test_service/tfm_attest_test_service_api.c b/test/test_services/tfm_attest_test_service/tfm_attest_test_service_secure_api.c
similarity index 100%
rename from test/test_services/tfm_attest_test_service/tfm_attest_test_service_api.c
rename to test/test_services/tfm_attest_test_service/tfm_attest_test_service_secure_api.c