COSE: Split t_cose to two part: sign and verify

Increase granularity to link only those files to secure
code which are used for signing the attestation token.
Other files are linked to non-secure code which are used
during attestation test suite for signature verification.

Change-Id: I6dc030563f56b047253c7a1f3494f59a12fe61c7
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/lib/t_cose/CMakeLists.txt b/lib/t_cose/CMakeLists.txt
index e1f1985..065271b 100644
--- a/lib/t_cose/CMakeLists.txt
+++ b/lib/t_cose/CMakeLists.txt
@@ -15,26 +15,39 @@
 
 #Start an embedded project.
 embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../../ConfigDefault.cmake")
-project(tfm_t_cose LANGUAGES C)
+project(tfm_t_cose_sign   LANGUAGES C)
+project(tfm_t_cose_verify LANGUAGES C)
 embedded_project_fixup()
 
 #Some project global settings
 set(T_COSE_DIR "${CMAKE_CURRENT_LIST_DIR}")
 
 #Append all our source files to global lists.
-list(APPEND ALL_SRC_C
+list(APPEND ALL_SRC_C_SIGN
 	"${T_COSE_DIR}/src/t_cose_sign1_sign.c"
 	"${T_COSE_DIR}/src/t_cose_util.c"
-	"${T_COSE_DIR}/src/t_cose_psa_crypto.c"
+	"${T_COSE_DIR}/src/t_cose_psa_crypto_hash.c"
+	"${T_COSE_DIR}/src/t_cose_psa_crypto_sign.c"
+	)
+
+list(APPEND ALL_SRC_C_VERIFY
+	"${T_COSE_DIR}/src/t_cose_util.c"
+	"${T_COSE_DIR}/src/t_cose_psa_crypto_hash.c"
+	"${T_COSE_DIR}/src/t_cose_psa_crypto_verify.c"
 	)
 
 #Setting include directories
 embedded_include_directories(PATH ${T_COSE_DIR}/inc ABSOLUTE)
+embedded_target_include_directories(TARGET tfm_t_cose_verify PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/util ABSOLUTE APPEND)
+embedded_target_include_directories(TARGET tfm_t_cose_sign   PATH ${TFM_ROOT_DIR}/platform/include ABSOLUTE APPEND)
 
-#Specify what we build (for the t_cose, build as an object library)
-add_library(${PROJECT_NAME} OBJECT ${ALL_SRC_C})
+#Specify what we build (t_cose_sign and t_cose_verify build as an object library)
+add_library(tfm_t_cose_sign   OBJECT ${ALL_SRC_C_SIGN})
+add_library(tfm_t_cose_verify OBJECT ${ALL_SRC_C_VERIFY})
 
 #Set common compiler flags
-config_setting_shared_compiler_flags(${PROJECT_NAME})
+config_setting_shared_compiler_flags(tfm_t_cose_sign)
+config_setting_shared_compiler_flags(tfm_t_cose_verify)
 
-embedded_project_end(${PROJECT_NAME})
+embedded_project_end(tfm_t_cose_sign)
+embedded_project_end(tfm_t_cose_verify)
diff --git a/lib/t_cose/src/t_cose_psa_crypto.c b/lib/t_cose/src/t_cose_psa_crypto.c
deleted file mode 100644
index 56a3b8e..0000000
--- a/lib/t_cose/src/t_cose_psa_crypto.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * t_cose_psa_crypto.c
- *
- * Copyright 2019, Laurence Lundblade
- *
- * Copyright (c) 2019, Arm Limited.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * See BSD-3-Clause license in README.md
- */
-
-#include "t_cose_crypto.h"
-#include "attestation_key.h"
-#include "tfm_plat_defs.h"
-#include "tfm_plat_crypto_keys.h"
-#include "tfm_memory_utils.h"
-#include "psa_crypto.h"
-
-/**
- * \brief Context for PSA hash adaptation.
- *
- * Hash context for PSA hash implementation. This is fit into and cast
- * to/from struct \ref t_cose_crypto_hash.
- */
-struct t_cose_psa_crypto_hash {
-    psa_status_t         status;
-    psa_hash_operation_t operation;
-};
-
-enum t_cose_err_t
-t_cose_crypto_pub_key_sign(int32_t cose_alg_id,
-                           int32_t key_select,
-                           struct q_useful_buf_c hash_to_sign,
-                           struct q_useful_buf signature_buffer,
-                           struct q_useful_buf_c *signature)
-{
-    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
-    enum psa_attest_err_t attest_ret;
-    psa_status_t psa_ret;
-    const size_t sig_size = t_cose_signature_size(cose_alg_id);
-
-    /* Avoid compiler warning due to unused argument */
-    (void)key_select;
-
-    if (sig_size > signature_buffer.len) {
-        return T_COSE_ERR_SIG_BUFFER_SIZE;
-    }
-
-    /* FixMe: Registration of key(s) should not be error by attestation service.
-     *        Later crypto service is going to get the attestation key from
-     *        platform layer.
-     */
-    attest_ret = attest_register_initial_attestation_key();
-    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
-        cose_ret = T_COSE_ERR_FAIL;
-        goto error;
-    }
-
-    psa_ret = psa_asymmetric_sign(ATTEST_PRIVATE_KEY_SLOT,
-                                  0, /* FixMe: algorithm ID */
-                                  hash_to_sign.ptr,
-                                  hash_to_sign.len,
-                                  signature_buffer.ptr, /* Sig buf */
-                                  signature_buffer.len, /* Sig buf size */
-                                  &(signature->len));   /* Sig length */
-
-    if (psa_ret != PSA_SUCCESS) {
-        cose_ret = T_COSE_ERR_FAIL;
-        goto error;
-    } else {
-        signature->ptr = signature_buffer.ptr;
-    }
-
-    attest_ret = attest_unregister_initial_attestation_key();
-    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
-        cose_ret = T_COSE_ERR_FAIL;
-        goto error;
-    }
-
-error:
-    return cose_ret;
-}
-
-enum t_cose_err_t
-t_cose_crypto_get_ec_pub_key(int32_t key_select,
-                             struct q_useful_buf_c kid,
-                             int32_t *cose_curve_id,
-                             struct q_useful_buf buf_to_hold_x_coord,
-                             struct q_useful_buf buf_to_hold_y_coord,
-                             struct q_useful_buf_c *x_coord,
-                             struct q_useful_buf_c *y_coord)
-{
-    enum tfm_plat_err_t plat_res;
-    enum ecc_curve_t cose_curve;
-    struct ecc_key_t attest_key = {0};
-    uint8_t  key_buf[ECC_P_256_KEY_SIZE];
-
-    /* Avoid compiler warning due to unused argument */
-    (void)key_select;
-
-    /* Get the initial attestation key */
-    plat_res = tfm_plat_get_initial_attest_key(key_buf, sizeof(key_buf),
-                                               &attest_key, &cose_curve);
-
-    /* Check the availability of the private key */
-    if (plat_res != TFM_PLAT_ERR_SUCCESS ||
-        attest_key.pubx_key == NULL ||
-        attest_key.puby_key == NULL) {
-        return T_COSE_ERR_KEY_BUFFER_SIZE;
-    }
-
-    *cose_curve_id = (int32_t)cose_curve;
-
-    /* Check buffer size to avoid overflow */
-    if (buf_to_hold_x_coord.len < attest_key.pubx_key_size) {
-        return T_COSE_ERR_KEY_BUFFER_SIZE;
-    }
-
-    /* Copy the X coordinate of the public key to the buffer */
-    tfm_memcpy(buf_to_hold_x_coord.ptr,
-               (const void *)attest_key.pubx_key,
-               attest_key.pubx_key_size);
-
-    /* Update size */
-    buf_to_hold_x_coord.len = attest_key.pubx_key_size;
-
-    /* Check buffer size to avoid overflow */
-    if (buf_to_hold_y_coord.len < attest_key.puby_key_size) {
-        return T_COSE_ERR_KEY_BUFFER_SIZE;
-    }
-
-    /* Copy the Y coordinate of the public key to the buffer */
-    tfm_memcpy(buf_to_hold_y_coord.ptr,
-               (const void *)attest_key.puby_key,
-               attest_key.puby_key_size);
-
-    /* Update size */
-    buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
-    x_coord->ptr = buf_to_hold_x_coord.ptr;
-    x_coord->len = buf_to_hold_x_coord.len;
-    y_coord->ptr = buf_to_hold_y_coord.ptr;
-    y_coord->len = buf_to_hold_y_coord.len;
-
-    return T_COSE_SUCCESS;
-}
-
-/**
- * \brief Check some of the sizes for hash implementation.
- *
- * \return  Value from \ref t_cose_err_t error if sizes are not correct.
- *
- * It makes sure the constants in the header file match the local
- * implementation.  This gets evaluated at compile time and will
- * optimize out to nothing when all checks pass.
- */
-static inline enum t_cose_err_t check_hash_sizes()
-{
-    if (T_COSE_CRYPTO_SHA256_SIZE != PSA_HASH_SIZE(PSA_ALG_SHA_256)) {
-        return T_COSE_ERR_HASH_GENERAL_FAIL;
-    }
-
-    return T_COSE_SUCCESS;
-}
-
-/**
- * \brief Convert COSE algorithm ID to a PSA algorithm ID
- *
- * \param[in] cose_hash_alg_id   The COSE-based ID for the
- *
- * \return PSA-based hash algorithm ID, or MD4 in the case of error.
- *
- */
-static inline psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
-{
-    psa_algorithm_t return_value;
-
-    switch (cose_hash_alg_id) {
-    case COSE_ALG_SHA256_PROPRIETARY:
-        return_value = PSA_ALG_SHA_256;
-        break;
-    default:
-        return_value = PSA_ALG_MD4;
-        break;
-    }
-
-    return return_value;
-}
-
-enum t_cose_err_t
-t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx,
-                         int32_t cose_hash_alg_id)
-{
-    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
-    psa_status_t psa_ret;
-    struct t_cose_psa_crypto_hash *psa_hash_ctx;
-
-    /* These next 3 lines optimize to nothing except when there is
-     * failure.
-     */
-    cose_ret = check_hash_sizes();
-    if (cose_ret) {
-        goto error;
-    }
-
-    /* This mostly turns into a compile-time check. If it succeeds,
-     * then it optimizes out to nothing. If it fails it will
-     * short-circuit this function to always create an error.
-     */
-    if (sizeof(struct t_cose_crypto_hash) <
-       sizeof(struct t_cose_psa_crypto_hash)) {
-        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
-        goto error;
-    }
-    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
-
-    psa_ret = psa_hash_setup(&psa_hash_ctx->operation,
-                             cose_hash_alg_id_to_psa(cose_hash_alg_id));
-
-    if (psa_ret == PSA_SUCCESS) {
-        psa_hash_ctx->status = PSA_SUCCESS;
-        cose_ret = T_COSE_SUCCESS;
-    } else if (psa_ret == PSA_ERROR_NOT_SUPPORTED) {
-        cose_ret = T_COSE_ERR_UNSUPPORTED_HASH;
-    } else {
-        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
-    }
-
-error:
-    return cose_ret;
-}
-
-void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
-                               struct q_useful_buf_c data_to_hash)
-{
-    struct t_cose_psa_crypto_hash *psa_hash_ctx;
-
-    /* This mostly turns into a compile-time check. If it succeeds,
-     * then it optimizes out to nothing. If it fails it will
-     * short-circuit this function to always create an error.
-     */
-    if (sizeof(struct t_cose_crypto_hash) <
-       sizeof(struct t_cose_psa_crypto_hash)) {
-        return;
-    }
-    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
-
-    if (psa_hash_ctx->status == PSA_SUCCESS) {
-        if (data_to_hash.ptr != NULL) {
-            psa_hash_ctx->status = psa_hash_update(&psa_hash_ctx->operation,
-                                                   data_to_hash.ptr,
-                                                   data_to_hash.len);
-        } else {
-            /* Intentionally do nothing, just computing the size of the token */
-        }
-    }
-}
-
-enum t_cose_err_t
-t_cose_crypto_hash_finish(struct t_cose_crypto_hash *hash_ctx,
-                          struct q_useful_buf buffer_to_hold_result,
-                          struct q_useful_buf_c *hash_result)
-{
-    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
-    psa_status_t psa_ret;
-    struct t_cose_psa_crypto_hash *psa_hash_ctx;
-
-    /* This mostly turns into a compile-time check. If it succeeds,
-     * then it optimizes out to nothing. If it fails it will
-     * short-circuit this function to always create an error.
-     */
-    if (sizeof(struct t_cose_crypto_hash) <
-       sizeof(struct t_cose_psa_crypto_hash)) {
-        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
-        goto error;
-    }
-    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
-
-    if (psa_hash_ctx->status == PSA_SUCCESS) {
-        psa_ret = psa_hash_finish(&psa_hash_ctx->operation,
-                                  buffer_to_hold_result.ptr,
-                                  buffer_to_hold_result.len,
-                                  &(hash_result->len));
-
-        if (psa_ret == PSA_SUCCESS) {
-            hash_result->ptr = buffer_to_hold_result.ptr;
-            cose_ret = T_COSE_SUCCESS;
-        } else if (psa_ret == PSA_ERROR_BUFFER_TOO_SMALL) {
-            cose_ret = T_COSE_ERR_HASH_BUFFER_SIZE;
-        } else {
-            cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
-        }
-    } else {
-        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
-    }
-
-error:
-    return cose_ret;
-}
diff --git a/lib/t_cose/src/t_cose_psa_crypto_hash.c b/lib/t_cose/src/t_cose_psa_crypto_hash.c
new file mode 100644
index 0000000..0ca3ba3
--- /dev/null
+++ b/lib/t_cose/src/t_cose_psa_crypto_hash.c
@@ -0,0 +1,180 @@
+/*
+ * t_cose_psa_crypto_hash.c
+ *
+ * Copyright 2019, Laurence Lundblade
+ *
+ * Copyright (c) 2019, Arm Limited.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * See BSD-3-Clause license in README.md
+ */
+
+#include "t_cose_crypto.h"
+#include "psa_crypto.h"
+
+/**
+ * \brief Context for PSA hash adaptation.
+ *
+ * Hash context for PSA hash implementation. This is fit into and cast
+ * to/from struct \ref t_cose_crypto_hash.
+ */
+struct t_cose_psa_crypto_hash {
+    psa_status_t         status;
+    psa_hash_operation_t operation;
+};
+
+/**
+ * \brief Check some of the sizes for hash implementation.
+ *
+ * \return  Value from \ref t_cose_err_t error if sizes are not correct.
+ *
+ * It makes sure the constants in the header file match the local
+ * implementation.  This gets evaluated at compile time and will
+ * optimize out to nothing when all checks pass.
+ */
+static inline enum t_cose_err_t check_hash_sizes(void)
+{
+    if (T_COSE_CRYPTO_SHA256_SIZE != PSA_HASH_SIZE(PSA_ALG_SHA_256)) {
+        return T_COSE_ERR_HASH_GENERAL_FAIL;
+    }
+
+    return T_COSE_SUCCESS;
+}
+
+/**
+ * \brief Convert COSE algorithm ID to a PSA algorithm ID
+ *
+ * \param[in] cose_hash_alg_id   The COSE-based ID for the
+ *
+ * \return PSA-based hash algorithm ID, or MD4 in the case of error.
+ *
+ */
+static inline psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
+{
+    psa_algorithm_t return_value;
+
+    switch (cose_hash_alg_id) {
+    case COSE_ALG_SHA256_PROPRIETARY:
+        return_value = PSA_ALG_SHA_256;
+        break;
+    default:
+        return_value = PSA_ALG_MD4;
+        break;
+    }
+
+    return return_value;
+}
+
+enum t_cose_err_t
+t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx,
+                         int32_t cose_hash_alg_id)
+{
+    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
+    psa_status_t psa_ret;
+    struct t_cose_psa_crypto_hash *psa_hash_ctx;
+
+    /* These next 3 lines optimize to nothing except when there is
+     * failure.
+     */
+    cose_ret = check_hash_sizes();
+    if (cose_ret) {
+        return cose_ret;
+    }
+
+    /* This mostly turns into a compile-time check. If it succeeds,
+     * then it optimizes out to nothing. If it fails it will
+     * short-circuit this function to always create an error.
+     */
+    if (sizeof(struct t_cose_crypto_hash) <
+       sizeof(struct t_cose_psa_crypto_hash)) {
+        return T_COSE_ERR_HASH_GENERAL_FAIL;
+    }
+    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
+
+    psa_ret = psa_hash_setup(&psa_hash_ctx->operation,
+                             cose_hash_alg_id_to_psa(cose_hash_alg_id));
+
+    if (psa_ret == PSA_SUCCESS) {
+        psa_hash_ctx->status = PSA_SUCCESS;
+        cose_ret = T_COSE_SUCCESS;
+    } else if (psa_ret == PSA_ERROR_NOT_SUPPORTED) {
+        cose_ret = T_COSE_ERR_UNSUPPORTED_HASH;
+    } else {
+        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
+    }
+
+    return cose_ret;
+}
+
+void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
+                               struct q_useful_buf_c data_to_hash)
+{
+    struct t_cose_psa_crypto_hash *psa_hash_ctx;
+
+    /* This mostly turns into a compile-time check. If it succeeds,
+     * then it optimizes out to nothing. If it fails it will
+     * short-circuit this function to always create an error.
+     */
+    if (sizeof(struct t_cose_crypto_hash) <
+       sizeof(struct t_cose_psa_crypto_hash)) {
+        return;
+    }
+    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
+
+    if (psa_hash_ctx->status == PSA_SUCCESS) {
+        if (data_to_hash.ptr != NULL) {
+            psa_hash_ctx->status = psa_hash_update(&psa_hash_ctx->operation,
+                                                   data_to_hash.ptr,
+                                                   data_to_hash.len);
+        } else {
+            /* No data was passed in to be hashed indicating the mode of use is
+             * the computation of the size of hash. This mode is hashing is used
+             * by t_cose when it is requested to compute the size of the signed
+             * data it might compute, which is in turn used to compute the
+             * size of a would be token. When computing the size, the size
+             * like this, there is nothing to do in update()
+             */
+        }
+    }
+}
+
+enum t_cose_err_t
+t_cose_crypto_hash_finish(struct t_cose_crypto_hash *hash_ctx,
+                          struct q_useful_buf buffer_to_hold_result,
+                          struct q_useful_buf_c *hash_result)
+{
+    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
+    psa_status_t psa_ret;
+    struct t_cose_psa_crypto_hash *psa_hash_ctx;
+
+    /* This mostly turns into a compile-time check. If it succeeds,
+     * then it optimizes out to nothing. If it fails it will
+     * short-circuit this function to always create an error.
+     */
+    if (sizeof(struct t_cose_crypto_hash) <
+       sizeof(struct t_cose_psa_crypto_hash)) {
+        return T_COSE_ERR_HASH_GENERAL_FAIL;
+    }
+    psa_hash_ctx = (struct t_cose_psa_crypto_hash *)hash_ctx;
+
+    if (psa_hash_ctx->status == PSA_SUCCESS) {
+        psa_ret = psa_hash_finish(&psa_hash_ctx->operation,
+                                  buffer_to_hold_result.ptr,
+                                  buffer_to_hold_result.len,
+                                  &(hash_result->len));
+
+        if (psa_ret == PSA_SUCCESS) {
+            hash_result->ptr = buffer_to_hold_result.ptr;
+            cose_ret = T_COSE_SUCCESS;
+        } else if (psa_ret == PSA_ERROR_BUFFER_TOO_SMALL) {
+            cose_ret = T_COSE_ERR_HASH_BUFFER_SIZE;
+        } else {
+            cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
+        }
+    } else {
+        cose_ret = T_COSE_ERR_HASH_GENERAL_FAIL;
+    }
+
+    return cose_ret;
+}
diff --git a/lib/t_cose/src/t_cose_psa_crypto_sign.c b/lib/t_cose/src/t_cose_psa_crypto_sign.c
new file mode 100644
index 0000000..465343f
--- /dev/null
+++ b/lib/t_cose/src/t_cose_psa_crypto_sign.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "t_cose_crypto.h"
+#include "attestation_key.h"
+#include "tfm_plat_defs.h"
+#include "tfm_plat_crypto_keys.h"
+#include "tfm_memory_utils.h"
+#include "psa_crypto.h"
+
+/* Avoid compiler warning due to unused argument */
+#define ARG_UNUSED(arg) (void)(arg)
+
+enum t_cose_err_t
+t_cose_crypto_pub_key_sign(int32_t cose_alg_id,
+                           int32_t key_select,
+                           struct q_useful_buf_c hash_to_sign,
+                           struct q_useful_buf signature_buffer,
+                           struct q_useful_buf_c *signature)
+{
+    enum t_cose_err_t cose_ret = T_COSE_SUCCESS;
+    enum psa_attest_err_t attest_ret;
+    psa_status_t psa_ret;
+    const size_t sig_size = t_cose_signature_size(cose_alg_id);
+
+    ARG_UNUSED(key_select);
+
+    if (sig_size > signature_buffer.len) {
+        return T_COSE_ERR_SIG_BUFFER_SIZE;
+    }
+
+    /* FixMe: Registration of key(s) should not be error by attestation service.
+     *        Later crypto service is going to get the attestation key from
+     *        platform layer.
+     */
+    attest_ret = attest_register_initial_attestation_key();
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return T_COSE_ERR_FAIL;
+    }
+
+    psa_ret = psa_asymmetric_sign(ATTEST_PRIVATE_KEY_SLOT,
+                                  0, /* FixMe: algorithm ID */
+                                  hash_to_sign.ptr,
+                                  hash_to_sign.len,
+                                  signature_buffer.ptr, /* Sig buf */
+                                  signature_buffer.len, /* Sig buf size */
+                                  &(signature->len));   /* Sig length */
+
+    if (psa_ret != PSA_SUCCESS) {
+        return T_COSE_ERR_FAIL;
+    } else {
+        signature->ptr = signature_buffer.ptr;
+    }
+
+    attest_ret = attest_unregister_initial_attestation_key();
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return T_COSE_ERR_FAIL;
+    }
+
+    return cose_ret;
+}
+
+enum t_cose_err_t
+t_cose_crypto_get_ec_pub_key(int32_t key_select,
+                             struct q_useful_buf_c kid,
+                             int32_t *cose_curve_id,
+                             struct q_useful_buf buf_to_hold_x_coord,
+                             struct q_useful_buf buf_to_hold_y_coord,
+                             struct q_useful_buf_c *x_coord,
+                             struct q_useful_buf_c *y_coord)
+{
+    enum tfm_plat_err_t plat_res;
+    enum ecc_curve_t cose_curve;
+    struct ecc_key_t attest_key = {0};
+    uint8_t  key_buf[ECC_P_256_KEY_SIZE];
+
+    ARG_UNUSED(key_select);
+
+    /* Get the initial attestation key */
+    plat_res = tfm_plat_get_initial_attest_key(key_buf, sizeof(key_buf),
+                                               &attest_key, &cose_curve);
+
+    /* Check the availability of the private key */
+    if (plat_res != TFM_PLAT_ERR_SUCCESS ||
+        attest_key.pubx_key == NULL ||
+        attest_key.puby_key == NULL) {
+        return T_COSE_ERR_KEY_BUFFER_SIZE;
+    }
+
+    *cose_curve_id = (int32_t)cose_curve;
+
+    *x_coord = q_useful_buf_copy_ptr(buf_to_hold_x_coord,
+                                     attest_key.pubx_key,
+                                     attest_key.pubx_key_size);
+
+    *y_coord = q_useful_buf_copy_ptr(buf_to_hold_y_coord,
+                                     attest_key.puby_key,
+                                     attest_key.puby_key_size);
+
+    if(q_useful_buf_c_is_null(*x_coord) || q_useful_buf_c_is_null(*y_coord)) {
+        return T_COSE_ERR_KEY_BUFFER_SIZE;
+    }
+
+    return T_COSE_SUCCESS;
+}
diff --git a/lib/t_cose/src/t_cose_psa_crypto_verify.c b/lib/t_cose/src/t_cose_psa_crypto_verify.c
new file mode 100644
index 0000000..01c7cf7
--- /dev/null
+++ b/lib/t_cose/src/t_cose_psa_crypto_verify.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "t_cose_crypto.h"
+#include "psa_crypto.h"
+
+/* Avoid compiler warning due to unused argument */
+#define ARG_UNUSED(arg) (void)(arg)
+
+enum t_cose_err_t
+t_cose_crypto_pub_key_verify(int32_t cose_alg_id,
+                             int32_t key_select,
+                             struct q_useful_buf_c key_id,
+                             struct q_useful_buf_c hash_to_verify,
+                             struct q_useful_buf_c signature)
+{
+    /* FIXME: Implement this function to call psa_asymmetric_verify() when
+     *        it will be supported by Crypto service in TF-M.
+     */
+    ARG_UNUSED(cose_alg_id);
+    ARG_UNUSED(key_select);
+    ARG_UNUSED(key_id);
+    ARG_UNUSED(hash_to_verify);
+    ARG_UNUSED(signature);
+
+    return T_COSE_SUCCESS;
+}