Attest: Align attestation service to new COSE library

T_COSE library implementation was updated. Update attestation
service and test suite to be aligned with new t_cose library API.

Change-Id: Iccc73f317c6451f692028bc199e04588fb9b9321
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/secure_fw/services/initial_attestation/CMakeLists.inc b/secure_fw/services/initial_attestation/CMakeLists.inc
index 21d8e02..8abfae2 100644
--- a/secure_fw/services/initial_attestation/CMakeLists.inc
+++ b/secure_fw/services/initial_attestation/CMakeLists.inc
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -64,8 +64,8 @@
 embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core/include ABSOLUTE)
 embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/spm ABSOLUTE)
 embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/inc ABSOLUTE)
-embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/inc ABSOLUTE)
-embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/src ABSOLUTE)
+embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/inc ABSOLUTE)
+embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/src ABSOLUTE)
 embedded_include_directories(PATH ${INITIAL_ATTESTATION_DIR} ABSOLUTE)
 
 set(BUILD_CMSIS_CORE Off)
diff --git a/secure_fw/services/initial_attestation/CMakeLists.txt b/secure_fw/services/initial_attestation/CMakeLists.txt
index 36f26b0..fb61f81 100644
--- a/secure_fw/services/initial_attestation/CMakeLists.txt
+++ b/secure_fw/services/initial_attestation/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -34,7 +34,7 @@
 endif()
 
 if (NOT TARGET tfm_t_cose_sign)
-	add_subdirectory(${TFM_ROOT_DIR}/lib/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose)
+	add_subdirectory(${TFM_ROOT_DIR}/lib/ext/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose)
 endif()
 
 #Specify what we build (for the initial attestation service, build as a static library)
diff --git a/secure_fw/services/initial_attestation/attest_token.c b/secure_fw/services/initial_attestation/attest_token.c
index 077a57b..78c0ee0 100644
--- a/secure_fw/services/initial_attestation/attest_token.c
+++ b/secure_fw/services/initial_attestation/attest_token.c
@@ -2,6 +2,7 @@
  * attest_token.c
  *
  * Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ * Copyright (c) 2020, Arm Limited.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -11,6 +12,10 @@
 #include "attest_token.h"
 #include "qcbor.h"
 #include "t_cose_sign1_sign.h"
+#include "t_cose_common.h"
+#include "q_useful_buf.h"
+#include "psa/crypto.h"
+#include "attestation_key.h"
 
 
 /**
@@ -19,7 +24,7 @@
  * \brief Attestation token creation implementation
  *
  * Outline of token creation. Much of this occurs inside
- * t_cose_sign1_init() and t_cose_sign1_finish().
+ * t_cose_sign1_encode_parameters() and t_cose_sign1_encode_signature().
  *
  * - Create encoder context
  * - Open the CBOR array that hold the \c COSE_Sign1
@@ -29,7 +34,7 @@
  *   - Unprotected Headers
  *     - Key ID
  * - Open payload bstr
- *   - Write payload data… lots of it…
+ *   - Write payload data lots of it
  *   - Get bstr that is the encoded payload
  * - Compute signature
  *   - Create a separate encoder context for \c Sig_structure
@@ -64,6 +69,9 @@
     case T_COSE_ERR_UNSUPPORTED_HASH:
         return ATTEST_TOKEN_ERR_HASH_UNAVAILABLE;
 
+    case T_COSE_ERR_TOO_SMALL:
+        return ATTEST_TOKEN_ERR_TOO_SMALL;
+
     default:
         /* A lot of the errors are not mapped because they are
          * primarily internal errors that should never happen. They
@@ -83,40 +91,48 @@
                                            int32_t cose_alg_id,
                                            const struct q_useful_buf *out_buf)
 {
-    /* approximate stack usage on 32-bit machine: 4 bytes */
-    enum t_cose_err_t cose_return_value;
-    enum attest_token_err_t return_value;
+    enum t_cose_err_t cose_ret;
+    enum attest_token_err_t return_value = ATTEST_TOKEN_ERR_SUCCESS;
+    enum psa_attest_err_t   attest_ret;
+    int32_t                 t_cose_options = 0;
+    struct t_cose_key attest_key;
+    psa_key_handle_t private_key;
 
     /* Remember some of the configuration values */
     me->opt_flags  = opt_flags;
     me->key_select = key_select;
 
+    if (opt_flags & TOKEN_OPT_SHORT_CIRCUIT_SIGN) {
+        t_cose_options |= T_COSE_OPT_SHORT_CIRCUIT_SIG;
+    }
+    t_cose_sign1_sign_init(&(me->signer_ctx), t_cose_options, cose_alg_id);
+
+    attest_ret =
+        attest_get_initial_attestation_private_key_handle(&private_key);
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return ATTEST_TOKEN_ERR_SIGNING_KEY;
+    }
+    attest_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
+    attest_key.k.key_handle = private_key;
+
+    t_cose_sign1_set_signing_key(&(me->signer_ctx),
+                                 attest_key,
+                                 NULL_Q_USEFUL_BUF_C); /* No kid */
+
     /* Spin up the CBOR encoder */
     QCBOREncode_Init(&(me->cbor_enc_ctx), *out_buf);
 
-
-    /* Initialize COSE signer. This will cause the cose headers to be
-     * encoded and written into out_buf using me->cbor_enc_ctx
+    /* This will cause the cose headers to be encoded and written into
+     *  out_buf using me->cbor_enc_ctx
      */
-    cose_return_value = t_cose_sign1_init(&(me->signer_ctx),
-                                          opt_flags &
-                                            TOKEN_OPT_SHORT_CIRCUIT_SIGN,
-                                          cose_alg_id,
-                                          key_select,
-                                          &(me->cbor_enc_ctx));
-    if(cose_return_value) {
-        return_value = t_cose_err_to_attest_err(cose_return_value);
-        goto Done;
+    cose_ret = t_cose_sign1_encode_parameters(&(me->signer_ctx),
+                                              &(me->cbor_enc_ctx));
+    if (cose_ret) {
+        return_value = t_cose_err_to_attest_err(cose_ret);
     }
 
-    /* Open the payload-wrapping bstr */
-    QCBOREncode_BstrWrap(&(me->cbor_enc_ctx));
-
     QCBOREncode_OpenMap(&(me->cbor_enc_ctx));
 
-    return_value = ATTEST_TOKEN_ERR_SUCCESS;
-
-Done:
     return return_value;
 }
 
@@ -183,10 +199,7 @@
 attest_token_finish(struct attest_token_ctx *me,
                     struct q_useful_buf_c *completed_token)
 {
-    /* approximate stack usage on 32-bit machine: 4 + 4 + 8 + 8 = 24 */
     enum attest_token_err_t return_value = ATTEST_TOKEN_ERR_SUCCESS;
-    /* The payload with all the claims that is signed */
-    struct q_useful_buf_c   token_payload_ub;
     /* The completed and signed encoded cose_sign1 */
     struct q_useful_buf_c   completed_token_ub;
     QCBORError              qcbor_result;
@@ -194,35 +207,28 @@
 
     QCBOREncode_CloseMap(&(me->cbor_enc_ctx));
 
-    /* Close off the payload-wrapping bstr. This gives us back the
-     * pointer and length of the payload that needs to be hashed as
-     * part of the signature
-     */
-    QCBOREncode_CloseBstrWrap(&(me->cbor_enc_ctx), &token_payload_ub);
-
-    /* Finish off the cose signature. This does all the interesting work of
-     hashing and signing */
-    cose_return_value =
-        t_cose_sign1_finish(&(me->signer_ctx), token_payload_ub);
-    if(cose_return_value) {
+    /* -- Finish up the COSE_Sign1. This is where the signing happens -- */
+    cose_return_value = t_cose_sign1_encode_signature(&(me->signer_ctx),
+                                                      &(me->cbor_enc_ctx));
+    if (cose_return_value) {
         /* Main errors are invoking the hash or signature */
         return_value = t_cose_err_to_attest_err(cose_return_value);
         goto Done;
     }
 
-    /* Close off the CBOR encoding and return the completed token */
-    qcbor_result = QCBOREncode_Finish(&(me->cbor_enc_ctx),
-                                      &completed_token_ub);
-    if(qcbor_result == QCBOR_ERR_BUFFER_TOO_SMALL) {
-        return_value = ATTEST_TOKEN_ERR_TOO_SMALL;
-    } else if (qcbor_result != QCBOR_SUCCESS) {
-        /* likely from array not closed, too many closes, ... */
-        return_value = ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-    } else {
-        *completed_token = completed_token_ub;
-    }
+    /* Finally close off the CBOR formatting and get the pointer and length
+     * of the resulting COSE_Sign1
+     */
+    qcbor_result = QCBOREncode_Finish(&(me->cbor_enc_ctx), &completed_token_ub);
+    if (qcbor_result == QCBOR_ERR_BUFFER_TOO_SMALL) {
+           return_value = ATTEST_TOKEN_ERR_TOO_SMALL;
+       } else if (qcbor_result != QCBOR_SUCCESS) {
+           /* likely from array not closed, too many closes, ... */
+           return_value = ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+       } else {
+           *completed_token = completed_token_ub;
+       }
 
 Done:
-    return return_value;
+        return return_value;
 }
-
diff --git a/secure_fw/services/initial_attestation/attest_token.h b/secure_fw/services/initial_attestation/attest_token.h
index 14c080d..dffee0b 100644
--- a/secure_fw/services/initial_attestation/attest_token.h
+++ b/secure_fw/services/initial_attestation/attest_token.h
@@ -2,6 +2,7 @@
  * attest_token.h
  *
  * Copyright (c) 2018-2019, Laurence Lundblade.
+ * Copyright (c) 2020, Arm Limited.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -78,13 +79,15 @@
     ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY,
     /** Tampering detected in cryptographic function. */
     ATTEST_TOKEN_ERR_TAMPERING_DETECTED,
+    /** Signing key is not found or of wrong type. */
+    ATTEST_TOKEN_ERR_SIGNING_KEY,
     /** Verification key is not found or of wrong type. */
     ATTEST_TOKEN_ERR_VERIFICATION_KEY,
     /** No token was given or validated */
     ATTEST_TOKEN_ERR_NO_VALID_TOKEN,
     /** Data item with label wasn't found. */
     ATTEST_TOKEN_ERR_NOT_FOUND,
-    /** SW Compoments absence not correctly indicated. */
+    /** SW Components absence not correctly indicated. */
     ATTEST_TOKEN_ERR_SW_COMPONENTS_MISSING
 };
 
@@ -122,10 +125,10 @@
  */
 struct attest_token_ctx {
     /* Private data structure */
-    QCBOREncodeContext      cbor_enc_ctx;
-    uint32_t                opt_flags;
-    int32_t                 key_select;
-    struct t_cose_sign1_ctx signer_ctx;
+    QCBOREncodeContext           cbor_enc_ctx;
+    uint32_t                     opt_flags;
+    int32_t                      key_select;
+    struct t_cose_sign1_sign_ctx signer_ctx;
 };
 
 
diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c
index 4f22789..052107c 100644
--- a/secure_fw/services/initial_attestation/attestation_core.c
+++ b/secure_fw/services/initial_attestation/attestation_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -18,7 +18,7 @@
 #include "tfm_attest_hal.h"
 #include "attest_token.h"
 #include "attest_eat_defines.h"
-#include "t_cose_defines.h"
+#include "t_cose_common.h"
 #include "tfm_memory_utils.h"
 #include "platform/include/tfm_plat_crypto_keys.h"
 
@@ -950,9 +950,9 @@
      * which causes the COSE headers to be constructed.
      */
     token_err = attest_token_start(&attest_token_ctx,
-                                   option_flags,         /* option_flags */
-                                   key_select,           /* key_select   */
-                                   COSE_ALGORITHM_ES256, /* alg_select   */
+                                   option_flags,            /* option_flags */
+                                   key_select,              /* key_select   */
+                                   T_COSE_ALGORITHM_ES256,  /* alg_select   */
                                    token);
 
     if (token_err != ATTEST_TOKEN_ERR_SUCCESS) {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 926a1f0..b55f467 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -134,7 +134,7 @@
 endif()
 
 if (NOT TARGET tfm_t_cose_verify AND ENABLE_ATTESTATION_SERVICE_TESTS)
-	add_subdirectory(${TFM_ROOT_DIR}/lib/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose)
+	add_subdirectory(${TFM_ROOT_DIR}/lib/ext/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose)
 endif()
 
 if ((NOT TARGET tfm_qcbor_encode OR NOT TARGET tfm_qcbor_decode) AND (ENABLE_ATTESTATION_SERVICE_TESTS OR ENABLE_QCBOR_TESTS))
diff --git a/test/suites/attestation/CMakeLists.inc b/test/suites/attestation/CMakeLists.inc
index 9b6d828..38c0eb1 100644
--- a/test/suites/attestation/CMakeLists.inc
+++ b/test/suites/attestation/CMakeLists.inc
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -58,7 +58,7 @@
 	embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/services/initial_attestation ABSOLUTE)
 	embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/inc ABSOLUTE)
 	embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/util ABSOLUTE)
-	embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/inc ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/inc ABSOLUTE)
 
 	#Append all our source files to global lists.
 	list(APPEND ALL_SRC_C_S  ${ATTEST_TEST_SRC_S})
diff --git a/test/suites/attestation/attest_token_decode.c b/test/suites/attestation/attest_token_decode.c
index ffb2a6f..3c3fd3e 100644
--- a/test/suites/attestation/attest_token_decode.c
+++ b/test/suites/attestation/attest_token_decode.c
@@ -2,6 +2,7 @@
  * attest_token_decode.c
  *
  * Copyright (c) 2019, Laurence Lundblade.
+ * Copyright (c) 2020, Arm Limited.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,6 +13,8 @@
 #include "t_cose_sign1_verify.h"
 #include "q_useful_buf.h"
 #include "qcbor_util.h"
+#include "psa/crypto.h"
+#include "attest_public_key.h"
 
 
 /**
@@ -155,24 +158,43 @@
 attest_token_decode_validate_token(struct attest_token_decode_context *me,
                                    struct q_useful_buf_c token)
 {
-    enum t_cose_err_t       t_cose_error;
-    enum attest_token_err_t return_value;
-    uint32_t                t_cose_options;
+    enum t_cose_err_t              t_cose_error;
+    enum attest_token_err_t        return_value;
+    enum psa_attest_err_t          attest_ret;
+    int32_t                        t_cose_options = 0;
+    struct t_cose_sign1_verify_ctx verify_ctx;
+    struct t_cose_key              attest_key;
+    psa_key_handle_t               public_key;
 
-    /*
-     * FIXME: check for CWT/EAT CBOR tag if requested
-     * FIXME: deal with the public key per t_cose_crypto.h
-     */
-
-    t_cose_options = 0;
+    /* Run the signature verification */
     if(me->options & TOKEN_OPT_SHORT_CIRCUIT_SIGN) {
         t_cose_options |= T_COSE_OPT_ALLOW_SHORT_CIRCUIT;
     }
-    t_cose_error = t_cose_sign1_verify(t_cose_options, 0, token, &me->payload);
+    t_cose_sign1_verify_init(&verify_ctx, t_cose_options);
+
+    attest_ret = attest_register_initial_attestation_public_key(&public_key);
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return ATTEST_TOKEN_ERR_VERIFICATION_KEY;
+    }
+
+    attest_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
+    attest_key.k.key_handle = public_key;
+
+    t_cose_sign1_set_verification_key(&verify_ctx, attest_key);
+
+    t_cose_error =  t_cose_sign1_verify(&verify_ctx,
+                                        token, /* COSE to verify */
+                                        &me->payload, /* Payload from token */
+                                        NULL); /* Don't return parameters */
 
     return_value = map_t_cose_errors(t_cose_error);
     me->last_error = return_value;
 
+    attest_ret = attest_unregister_initial_attestation_public_key(public_key);
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return ATTEST_TOKEN_ERR_GENERAL;
+    }
+
     return return_value;
 }