Attest: Implement API to get attestation public key

Implement non-secure interface function for IPC and library models and
secure interface function to get the public part of the attestation
key pair.
Add public key getter secure function / service to Initial Attestation
partition manifest.

Change-Id: Idae5f5d5d645afa6d3c7e62e9169387e57932137
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/interface/include/psa/initial_attestation.h b/interface/include/psa/initial_attestation.h
index 6a7b8d8..4dd247b 100644
--- a/interface/include/psa/initial_attestation.h
+++ b/interface/include/psa/initial_attestation.h
@@ -45,7 +45,9 @@
     PSA_ATTEST_ERR_INIT_FAILED,
     /** Token buffer is too small to store the created token there */
     PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW,
-    /** Some of the mandatory claims are unavailable*/
+    /** Attestation key buffer is too small to store the obtained key there */
+    PSA_ATTEST_ERR_KEY_BUFFER_OVERFLOW,
+    /** Some of the mandatory claims are unavailable */
     PSA_ATTEST_ERR_CLAIM_UNAVAILABLE,
     /** Some parameter or combination of parameters are recognised as invalid:
      * - challenge size is not allowed
diff --git a/interface/include/psa_manifest/sid.h b/interface/include/psa_manifest/sid.h
index baa02c2..a6a96e7 100644
--- a/interface/include/psa_manifest/sid.h
+++ b/interface/include/psa_manifest/sid.h
@@ -45,6 +45,8 @@
 #define TFM_ATTEST_GET_TOKEN_VERSION                               (1U)
 #define TFM_ATTEST_GET_TOKEN_SIZE_SID                              (0x00000021U)
 #define TFM_ATTEST_GET_TOKEN_SIZE_VERSION                          (1U)
+#define TFM_ATTEST_GET_PUBLIC_KEY_SID                              (0x00000022U)
+#define TFM_ATTEST_GET_PUBLIC_KEY_VERSION                          (1U)
 
 /******** TFM_SP_CORE_TEST ********/
 #define SPM_CORE_TEST_INIT_SUCCESS_SID                             (0x0000F020U)
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index b0b4867..0bcef49 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -94,6 +94,7 @@
 /******** TFM_SP_INITIAL_ATTESTATION ********/
 psa_status_t tfm_initial_attest_get_token_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_initial_attest_get_token_size_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_initial_attest_get_public_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
diff --git a/interface/src/tfm_initial_attestation_func_api.c b/interface/src/tfm_initial_attestation_func_api.c
index c391f61..7292df5 100644
--- a/interface/src/tfm_initial_attestation_func_api.c
+++ b/interface/src/tfm_initial_attestation_func_api.c
@@ -9,6 +9,7 @@
 #include "tfm_veneers.h"
 #include "tfm_ns_interface.h"
 #include "psa/client.h"
+#include "psa/crypto_types.h"
 
 #define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
 
@@ -56,3 +57,25 @@
                             (uint32_t)in_vec,  IOVEC_LEN(in_vec),
                             (uint32_t)out_vec, IOVEC_LEN(out_vec));
 }
+
+enum psa_attest_err_t
+tfm_initial_attest_get_public_key(uint8_t         *public_key,
+                                  size_t           public_key_buf_size,
+                                  size_t          *public_key_len,
+                                  psa_ecc_curve_t *elliptic_curve_type)
+{
+    int32_t res;
+
+    psa_outvec out_vec[] = {
+        {.base = public_key,          .len = public_key_buf_size},
+        {.base = elliptic_curve_type, .len = sizeof(*elliptic_curve_type)},
+        {.base = public_key_len,      .len = sizeof(*public_key_len)}
+    };
+
+    res = tfm_ns_interface_dispatch(
+                        (veneer_fn)tfm_initial_attest_get_public_key_veneer,
+                        (uint32_t)NULL,  0,
+                        (uint32_t)out_vec, IOVEC_LEN(out_vec));
+
+    return (enum psa_attest_err_t)res;
+}
diff --git a/interface/src/tfm_initial_attestation_ipc_api.c b/interface/src/tfm_initial_attestation_ipc_api.c
index 10b3a59..ed9264f 100644
--- a/interface/src/tfm_initial_attestation_ipc_api.c
+++ b/interface/src/tfm_initial_attestation_ipc_api.c
@@ -9,6 +9,7 @@
 #include "tfm_veneers.h"
 #include "tfm_ns_interface.h"
 #include "psa/client.h"
+#include "psa/crypto_types.h"
 #include "psa_manifest/sid.h"
 
 #define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
@@ -81,3 +82,32 @@
 
     return (enum psa_attest_err_t)status;
 }
+
+enum psa_attest_err_t
+tfm_initial_attest_get_public_key(uint8_t         *public_key,
+                                  size_t           public_key_buf_size,
+                                  size_t          *public_key_len,
+                                  psa_ecc_curve_t *elliptic_curve_type)
+{
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    psa_status_t status;
+
+    psa_outvec out_vec[] = {
+        {.base = public_key,          .len = public_key_buf_size},
+        {.base = elliptic_curve_type, .len = sizeof(*elliptic_curve_type)},
+        {.base = public_key_len,      .len = sizeof(*public_key_len)}
+    };
+
+    handle = psa_connect(TFM_ATTEST_GET_PUBLIC_KEY_SID,
+                         TFM_ATTEST_GET_PUBLIC_KEY_VERSION);
+    if (!PSA_HANDLE_IS_VALID(handle)) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    status = psa_call(handle, PSA_IPC_CALL,
+                      NULL, 0,
+                      out_vec, IOVEC_LEN(out_vec));
+    psa_close(handle);
+
+    return (enum psa_attest_err_t)status;
+}