Attest: Add CBOR/COSE encoding to IAT

Replace the temporary TLV encoding of the initial
attestation token (IAT) to the final CBOR/COSE encoding.

Change-Id: I4b6c936e501704fd193757e47ccbde657e85ede6
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/interface/include/psa_initial_attestation_api.h b/interface/include/psa_initial_attestation_api.h
index 5d650f0..bb479f4 100644
--- a/interface/include/psa_initial_attestation_api.h
+++ b/interface/include/psa_initial_attestation_api.h
@@ -26,7 +26,7 @@
  * \brief PSA INITIAL ATTESTATION API version
  */
 #define PSA_INITIAL_ATTEST_API_VERSION_MAJOR (0)
-#define PSA_INITIAL_ATTEST_API_VERSION_MINOR (1)
+#define PSA_INITIAL_ATTEST_API_VERSION_MINOR (9)
 
 /**
  * \enum psa_attest_err_t
@@ -181,19 +181,6 @@
  */
 
 /**
- * Calculated based on:
- *  - COSE header
- *    - Algorithm identifier
- *    - Key ID
- *  - Claims in initial attestation token
- *  - COSE Signature
- *
- * This size (in bytes) is a maximum value, actual token size can be smaller.
- */
-/* FixMe: Just initial value it must be updated if claims are fixed */
-#define PSA_INITIAL_ATTEST_TOKEN_SIZE (512u)
-
-/**
  * \brief Get initial attestation token
  *
  * \param[in]     challenge_obj   Pointer to buffer where challenge input is
diff --git a/secure_fw/services/initial_attestation/CMakeLists.inc b/secure_fw/services/initial_attestation/CMakeLists.inc
index 5373dcd..9644905 100644
--- a/secure_fw/services/initial_attestation/CMakeLists.inc
+++ b/secure_fw/services/initial_attestation/CMakeLists.inc
@@ -37,6 +37,7 @@
 		"${INITIAL_ATTESTATION_DIR}/attestation_core.c"
 		"${INITIAL_ATTESTATION_DIR}/attestation_crypto_stub.c"
 		"${INITIAL_ATTESTATION_DIR}/attestation_key.c"
+		"${INITIAL_ATTESTATION_DIR}/attest_token.c"
 		)
 
 	#Setting include directories
@@ -47,6 +48,8 @@
 	embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core 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 ${INITIAL_ATTESTATION_DIR} ABSOLUTE)
 
 	set(BUILD_CMSIS_CORE Off)
diff --git a/secure_fw/services/initial_attestation/attest_eat_defines.h b/secure_fw/services/initial_attestation/attest_eat_defines.h
new file mode 100644
index 0000000..002e2a1
--- /dev/null
+++ b/secure_fw/services/initial_attestation/attest_eat_defines.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __ATTEST_EAT_DEFINES_H__
+#define __ATTEST_EAT_DEFINES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EAT_CBOR_ARM_RANGE_BASE                 (-75000)
+#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION   (EAT_CBOR_ARM_RANGE_BASE - 0)
+#define EAT_CBOR_ARM_LABEL_CLIENT_ID            (EAT_CBOR_ARM_RANGE_BASE - 1)
+#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE   (EAT_CBOR_ARM_RANGE_BASE - 2)
+#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID    (EAT_CBOR_ARM_RANGE_BASE - 3)
+#define EAT_CBOR_ARM_LABEL_BOOT_SEED            (EAT_CBOR_ARM_RANGE_BASE - 4)
+#define EAT_CBOR_ARM_LABEL_HW_VERSION           (EAT_CBOR_ARM_RANGE_BASE - 5)
+#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS        (EAT_CBOR_ARM_RANGE_BASE - 6)
+#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS     (EAT_CBOR_ARM_RANGE_BASE - 7)
+#define EAT_CBOR_ARM_LABEL_CHALLENGE            (EAT_CBOR_ARM_RANGE_BASE - 8)
+#define EAT_CBOR_ARM_LABEL_UEID                 (EAT_CBOR_ARM_RANGE_BASE - 9)
+#define EAT_CBOR_ARM_LABEL_ORIGINATION          (EAT_CBOR_ARM_RANGE_BASE - 10)
+
+#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_TYPE  (1)
+#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_VALUE (2)
+#define EAT_CBOR_SW_COMPONENT_SECURITY_EPOCH    (3)
+#define EAT_CBOR_SW_COMPONENT_VERSION           (4)
+#define EAT_CBOR_SW_COMPONENT_SIGNER_ID         (5)
+#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC  (6)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ATTEST_EAT_DEFINES_H__ */
diff --git a/secure_fw/services/initial_attestation/attestation.h b/secure_fw/services/initial_attestation/attestation.h
index 71a3835..356132d 100644
--- a/secure_fw/services/initial_attestation/attestation.h
+++ b/secure_fw/services/initial_attestation/attestation.h
@@ -15,30 +15,6 @@
 extern "C" {
 #endif
 
-/* Extension of shared data TLVs, defined in bl2/include/tfm_boot_status.h */
-/* #define GENERAL_BOOT_SEED          0x00 */ /* Defined in tfm_boot_status.h */
-#define GENERAL_INSTANCE_ID        0x01
-#define GENERAL_CHALLENGE          0x02
-#define GENERAL_CALLER_ID          0x03
-#define GENERAL_IMPLEMENTATION_ID  0x04
-#define GENERAL_HW_VERSION         0x05
-#define GENERAL_SECURITY_LIFECYCLE 0x06
-
-#define TLV_MINOR_IAS_INSTANCE_ID \
-                            ((SW_GENERAL << 6) | GENERAL_INSTANCE_ID)
-#define TLV_MINOR_IAS_CHALLENGE \
-                            ((SW_GENERAL << 6) | GENERAL_CHALLENGE)
-#define TLV_MINOR_IAS_CALLER_ID \
-                            ((SW_GENERAL << 6) | GENERAL_CALLER_ID)
-#define TLV_MINOR_IAS_IMPLEMENTATION_ID \
-                            ((SW_GENERAL << 6) | GENERAL_IMPLEMENTATION_ID)
-#define TLV_MINOR_IAS_HW_VERSION \
-                            ((SW_GENERAL << 6) | GENERAL_HW_VERSION)
-#define TLV_MINOR_IAS_SECURITY_LIFECYCLE \
-                            ((SW_GENERAL << 6) | GENERAL_SECURITY_LIFECYCLE)
-#define TLV_MINOR_IAS_IAT_VERSION \
-                            ((SW_GENERAL << 6) | GENERAL_IAT_VERSION)
-
 /*!
  * \brief Initialise the initial attestation service during the TF-M boot up
  *        process.
diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c
index c167342..a0c396b 100644
--- a/secure_fw/services/initial_attestation/attestation_core.c
+++ b/secure_fw/services/initial_attestation/attestation_core.c
@@ -8,7 +8,6 @@
 #include <stdint.h>
 #include <string.h>
 #include <stddef.h>
-#include "psa_initial_attestation_api.h"
 #include "attestation.h"
 #include "secure_utilities.h"
 #include "tfm_api.h"
@@ -19,9 +18,16 @@
 #include "platform/include/tfm_plat_device_id.h"
 #include "platform/include/tfm_plat_boot_seed.h"
 #include "tfm_attest_hal.h"
+#include "attest_token.h"
+#include "attest_eat_defines.h"
+#include "t_cose_defines.h"
 
 #define MAX_BOOT_STATUS 512
 
+/* Indicates how to encode SW components' measurements in the CBOR map */
+#define EAT_SW_COMPONENT_NESTED     1  /* Nested map */
+#define EAT_SW_COMPONENT_NOT_NESTED 0  /* Flat structure */
+
 /*!
  * \var boot_status
  *
@@ -53,7 +59,60 @@
 }
 
 /*!
- * \brief Static function to look up all entries in the shared data area
+ * \brief Static function to map return values between \ref attest_token_err_t
+ *        and \ref psa_attest_err_t
+ *
+ * \param[in]  token_err  Token encoding return value
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static inline enum psa_attest_err_t
+error_mapping(enum attest_token_err_t token_err)
+{
+    switch (token_err) {
+    case ATTEST_TOKEN_ERR_SUCCESS:
+        return PSA_ATTEST_ERR_SUCCESS;
+        break;
+    case ATTEST_TOKEN_ERR_TOO_SMALL:
+        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+        break;
+    default:
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+}
+
+/*!
+ * \brief Static function to convert a pointer and size info to unsigned
+ *        integer number. Max 32bits unsigned integers are supported.
+ *
+ * \param[in]  int_ptr  Pointer to the unsigned integer
+ * \param[in]  len      Size of the unsigned integers in bytes
+ * \param[in]  value    Pointer where to store the converted value
+ *
+ * \return Returns 0 on success and -1 on error.
+ */
+static inline int32_t get_uint(const void *int_ptr,
+                               size_t len,
+                               uint32_t *value)
+{
+    switch (len) {
+    case 1:
+        *value = (uint32_t)(*(uint8_t  *)(int_ptr));
+        break;
+    case 2:
+        *value = (uint32_t)(*(uint16_t *)(int_ptr));
+        break;
+    case 4:
+        *value = (uint32_t)(*(uint32_t *)(int_ptr));
+        break;
+    default:
+        return -1;
+    }
+
+    return 0;
+}
+/*!
+ * \brief Static function to look up all entires in the shared data area
  *       (boot status) which belong to a specific module.
  *
  * \param[in]     module  The identifier of SW module to look up based on this
@@ -96,8 +155,8 @@
         tlv_curr  = (*tlv_ptr) + tlv_entry->tlv_len;
     }
 
-    /* Iterates over the TLV section and copy TLVs with requested module
-     * identifier to the provided buffer.
+    /* Iterates over the TLV section and returns the address and size of TLVs
+     * with requested module identifier
      */
     for (; tlv_curr < tlv_end; tlv_curr += tlv_entry->tlv_len) {
         tlv_entry = (struct shared_data_tlv_entry *)tlv_curr;
@@ -113,126 +172,219 @@
 }
 
 /*!
- * \brief Static function to copy a TLV entry from shared data section to the
- *        attestation token.
+ * \brief Static function to add SW component related claims to attestation
+ *        token in CBOR format.
  *
- * \param[in]  tlv_len        The length of TLV entry in bytes
- * \param[in]  tlv_ptr        Pointer from where to copy the TLV entry
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ *  This function translates between TLV  and CBOR encoding.
  *
- * \return Returns 0 on success. Otherwise, 1.
- */
-static uint32_t attest_copy_tlv(uint16_t       tlv_len,
-                                const uint8_t *tlv_ptr,
-                                uint32_t       token_buf_size,
-                                uint8_t       *token_buf)
-{
-    struct shared_data_tlv_header *tlv_header;
-    uint8_t *next_tlv = token_buf;
-
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-    if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
-        return 1;
-    }
-
-    if (tlv_header->tlv_tot_len + tlv_len > token_buf_size) {
-        return 1;
-    }
-
-    next_tlv += tlv_header->tlv_tot_len;
-    tlv_header->tlv_tot_len += tlv_len;
-    tfm_memcpy(next_tlv, tlv_ptr, tlv_len);
-
-    return 0;
-}
-
-/*!
- * \brief Static function to add a TLV entry to the attestation token.
- *
- * \param[in]  minor_type     The identifier of the TLV entry
- * \param[in]  size           Size of the TLV entry in bytes
- * \param[in]  data           Pointer to the buffer which stores the TLV entry
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
- *
- * \return Returns 0 on success. Otherwise, 1.
- */
-static uint32_t attest_add_tlv(uint16_t       minor_type,
-                               uint32_t       size,
-                               const uint8_t *data,
-                               uint32_t       token_buf_size,
-                               uint8_t       *token_buf)
-{
-    struct shared_data_tlv_header *tlv_header;
-    struct shared_data_tlv_entry  *tlv_entry;
-    uint8_t *next_tlv = token_buf;
-
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-    if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
-        return 1;
-    }
-
-    if (tlv_header->tlv_tot_len + SHARED_DATA_ENTRY_SIZE(size) >
-        token_buf_size) {
-        return 1;
-    }
-
-    next_tlv += tlv_header->tlv_tot_len;
-    tlv_header->tlv_tot_len += SHARED_DATA_ENTRY_SIZE(size);
-
-    tlv_entry = (struct shared_data_tlv_entry *)next_tlv;
-    tlv_entry->tlv_type = SET_TLV_TYPE(TLV_MAJOR_IAS, minor_type);
-    tlv_entry->tlv_len = SHARED_DATA_ENTRY_SIZE(size);
-
-    next_tlv += SHARED_DATA_ENTRY_HEADER_SIZE;
-    tfm_memcpy(next_tlv, data, size);
-
-    return 0;
-}
-
-/*!
- * \brief Static function to initalise the token buffer. Add TLV data header to
- *        it.
- *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx    Attestation token encoding context
+ * \param[in]  tlv_id       The ID of claim
+ * \param[in]  claim_value  A structure which carries a pointer and size about
+ *                          the data item to be added to the token
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_init_token(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_sw_component_claim(struct attest_token_ctx *token_ctx,
+                              uint8_t tlv_id,
+                              const struct useful_buf_c *claim_value)
 {
-    struct shared_data_tlv_header *tlv_header;
+    int32_t res;
+    uint32_t value;
 
-    if (SHARED_DATA_HEADER_SIZE > token_buf_size) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+    switch (tlv_id) {
+    case SW_MEASURE_VALUE:
+        attest_token_add_bstr(token_ctx,
+                              EAT_CBOR_SW_COMPONENT_MEASUREMENT_VALUE,
+                              claim_value);
+        break;
+    case SW_MEASURE_TYPE:
+        attest_token_add_tstr(token_ctx,
+                              EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC,
+                              claim_value);
+        break;
+    case SW_VERSION:
+        attest_token_add_tstr(token_ctx,
+                              EAT_CBOR_SW_COMPONENT_VERSION,
+                              claim_value);
+        break;
+    case SW_SIGNER_ID:
+        attest_token_add_bstr(token_ctx,
+                              EAT_CBOR_SW_COMPONENT_SIGNER_ID,
+                              claim_value);
+        break;
+    case SW_EPOCH:
+        res = get_uint(claim_value->ptr, claim_value->len, &value);
+        if (res) {
+            return PSA_ATTEST_ERR_GENERAL;
+        }
+        attest_token_add_integer(token_ctx,
+                                 EAT_CBOR_SW_COMPONENT_SECURITY_EPOCH,
+                                 (int64_t)value);
+        break;
+    case SW_TYPE:
+        attest_token_add_tstr(token_ctx,
+                              EAT_CBOR_SW_COMPONENT_MEASUREMENT_TYPE,
+                              claim_value);
+        break;
+    default:
+        return PSA_ATTEST_ERR_GENERAL;
     }
 
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-    tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
-    tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
-
     return PSA_ATTEST_ERR_SUCCESS;
 }
 
 /*!
- * \brief Static function to add SW modules related claims to attestation token.
+ * \brief Static function to add the measurement data of a single SW components
+ *        to the attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx    Token encoding context
+ * \param[in]  module       SW component identifier
+ * \param[in]  tlv_address  Address of the first TLV entry in the boot status,
+ *                          which belongs to this SW component.
+ * \param[in]  nested_map   Flag to indicate that how to encode the SW component
+ *                          measurement data: nested map or non-nested map.
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_sw_module_claims(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_single_sw_measurment(struct attest_token_ctx *token_ctx,
+                                uint32_t module,
+                                uint8_t *tlv_address,
+                                uint32_t nested_map)
+{
+    struct shared_data_tlv_entry *tlv_entry =
+    (struct shared_data_tlv_entry *) tlv_address;
+    uint16_t tlv_len = tlv_entry->tlv_len;
+    uint8_t  tlv_id  = GET_IAS_CLAIM(tlv_entry->tlv_type);
+    uint8_t *tlv_ptr = tlv_address;
+    int32_t found = 1;
+    struct useful_buf_c claim_value;
+    enum psa_attest_err_t res;
+    QCBOREncodeContext *cbor_encode_ctx;
+
+    cbor_encode_ctx = attest_token_borrow_cbor_cntxt(token_ctx);
+
+    /* Open nested map for SW component measurement claims */
+    if (nested_map) {
+        QCBOREncode_OpenMapInMapN(cbor_encode_ctx,
+                                 EAT_CBOR_SW_COMPONENT_MEASUREMENT_VALUE);
+    }
+
+    /* Look up all measurement TLV entry which belongs to the SW component */
+    while (found) {
+         /* Here only measurement claims are added to the token */
+         if (GET_IAS_MEASUREMENT_CLAIM(tlv_id)) {
+            claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
+            claim_value.len  = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+            res = attest_add_sw_component_claim(token_ctx,
+                                                tlv_id,
+                                                &claim_value);
+            if (res != PSA_ATTEST_ERR_SUCCESS) {
+                return res;
+            }
+        }
+
+        /* Look up next entry it can be non-measurement claim*/
+        found = attest_get_tlv_by_module(module, &tlv_id,
+                                         &tlv_len, &tlv_ptr);
+        if (found == -1) {
+            return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+        }
+    }
+
+    if (nested_map) {
+        QCBOREncode_CloseMap(cbor_encode_ctx);
+    }
+
+    return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add the claims of a single SW components to the
+ *        attestation token.
+ *
+ * \param[in]  token_ctx    Token encoding context
+ * \param[in]  module       SW component identifier
+ * \param[in]  tlv_address  Address of the first TLV entry in the boot status,
+ *                          which belongs to this SW component.
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_single_sw_component(struct attest_token_ctx *token_ctx,
+                               uint32_t module,
+                               uint8_t *tlv_address)
+{
+    struct shared_data_tlv_entry *tlv_entry =
+    (struct shared_data_tlv_entry *) tlv_address;
+    uint16_t tlv_len = tlv_entry->tlv_len;
+    uint8_t  tlv_id  = GET_IAS_CLAIM(tlv_entry->tlv_type);
+    uint8_t *tlv_ptr = tlv_address;
+    int32_t found = 1;
+    uint32_t measurement_claim_cnt = 0;
+    struct useful_buf_c claim_value;
+    QCBOREncodeContext *cbor_encode_ctx;
+
+    /* Open map which stores claims belong to a SW component */
+    cbor_encode_ctx = attest_token_borrow_cbor_cntxt(token_ctx);
+    QCBOREncode_OpenMap(cbor_encode_ctx);
+
+    /*Look up all TLV entry which belongs to the same SW component */
+    while (found) {
+        /* Check whether claim is measurement claim */
+        if (GET_IAS_MEASUREMENT_CLAIM(tlv_id)) {
+            if (measurement_claim_cnt == 0) {
+                /* Call only once when first measurement claim found */
+                measurement_claim_cnt++;
+                attest_add_single_sw_measurment(token_ctx,
+                                                module,
+                                                tlv_ptr,
+                                                EAT_SW_COMPONENT_NOT_NESTED);
+            }
+        } else {
+            /* Adding top level claims */
+            claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
+            claim_value.len  = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+            attest_add_sw_component_claim(token_ctx, tlv_id, &claim_value);
+        }
+
+        /* Look up next entry which belongs to SW component */
+        found = attest_get_tlv_by_module(module, &tlv_id,
+                                         &tlv_len, &tlv_ptr);
+        if (found == -1) {
+            return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+        }
+    }
+
+    /* Close map which stores claims belong to a SW component */
+    QCBOREncode_CloseMap(cbor_encode_ctx);
+
+    return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add the claims of all SW components to the
+ *        attestation token.
+ *
+ * \param[in]  token_ctx  Token encoding context
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_all_sw_components(struct attest_token_ctx *token_ctx)
 {
     uint16_t tlv_len;
     uint8_t *tlv_ptr;
-    uint8_t  claim;
-    uint32_t found;
-    uint32_t res;
-    int module;
+    uint8_t  tlv_id;
+    int32_t found;
+    uint32_t module;
+    QCBOREncodeContext *cbor_encode_ctx;
+
+    /* Open array which stores SW components claims */
+    cbor_encode_ctx = attest_token_borrow_cbor_cntxt(token_ctx);
+    QCBOREncode_OpenArrayInMapN(cbor_encode_ctx,
+                                EAT_CBOR_ARM_LABEL_SW_COMPONENTS);
 
     /* Starting from module 1, because module 0 contains general claims which
      * are not related to SW module(i.e: boot_seed)
@@ -243,59 +395,33 @@
          */
         tlv_ptr = NULL;
 
-        /*Look up all entry which belongs to the same SW module */
-        do {
-            found = attest_get_tlv_by_module(module, &claim,
-                                             &tlv_len, &tlv_ptr);
+        /* Look up the first TLV entry which belongs to the SW module */
+        found = attest_get_tlv_by_module(module, &tlv_id,
+                                         &tlv_len, &tlv_ptr);
+        if (found == -1) {
+            return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+        }
 
-            if (found == -1) {
-                return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
-            }
-
-            if (found == 1) {
-                switch (claim) {
-                /* Intentional fall through
-                 * Claims are handled in the same way with TLV encoding, they
-                 * are just copied to the token buffer.
-                 * But later in case of CBOR encoding they must be
-                 * differentiated in order to apply the corresponding claim
-                 * label.
-                 *
-                 * FixMe: Handle cases individually and apply the proper EAT
-                 *        label
-                 */
-                case SW_MEASURE_VALUE:
-                case SW_MEASURE_TYPE:
-                case SW_VERSION:
-                case SW_SIGNER_ID:
-                case SW_EPOCH:
-                case SW_TYPE:
-                    res = attest_copy_tlv(tlv_len, tlv_ptr,
-                                          token_buf_size, token_buf);
-                    if (res != 0) {
-                        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-                    }
-                    break;
-                default:
-                    return PSA_ATTEST_ERR_GENERAL;
-                }
-            }
-        } while (found == 1);
+        if (found == 1) {
+            attest_add_single_sw_component(token_ctx, module, tlv_ptr);
+        }
     }
 
+    /* Close array which stores SW components claims*/
+    QCBOREncode_CloseArray(cbor_encode_ctx);
+
     return PSA_ATTEST_ERR_SUCCESS;
 }
 
 /*!
  * \brief Static function to add boot seed claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_boot_seed_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_boot_seed_claim(struct attest_token_ctx *token_ctx)
 {
     /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
      *        type is configured in the MPU to be normal, instead of device,
@@ -304,20 +430,18 @@
     __attribute__ ((aligned(4)))
     uint8_t boot_seed[BOOT_SEED_SIZE];
     enum tfm_plat_err_t res;
+    struct useful_buf_c claim_value;
 
     res = tfm_plat_get_boot_seed(sizeof(boot_seed), boot_seed);
     if (res != TFM_PLAT_ERR_SUCCESS) {
         return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
     }
 
-    res = attest_add_tlv(TLV_MINOR_IAS_BOOT_SEED,
-                         BOOT_SEED_SIZE,
-                         boot_seed,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    claim_value.ptr = boot_seed;
+    claim_value.len  = BOOT_SEED_SIZE;
+    attest_token_add_bstr(token_ctx,
+                          EAT_CBOR_ARM_LABEL_BOOT_SEED,
+                          &claim_value);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -330,13 +454,12 @@
 /*!
  * \brief Static function to add instance id claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_instance_id_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_instance_id_claim(struct attest_token_ctx *token_ctx)
 {
     /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
      *        type is configured in the MPU to be normal, instead of device,
@@ -344,23 +467,20 @@
      */
     __attribute__ ((aligned(4)))
     uint8_t instance_id[INSTANCE_ID_MAX_SIZE];
-    uint32_t res;
     enum tfm_plat_err_t res_plat;
     uint32_t size = sizeof(instance_id);
+    struct useful_buf_c claim_value;
 
     res_plat = tfm_plat_get_instance_id(&size, instance_id);
     if (res_plat != TFM_PLAT_ERR_SUCCESS) {
         return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
     }
 
-    res = attest_add_tlv(TLV_MINOR_IAS_INSTANCE_ID,
-                         size,
-                         instance_id,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    claim_value.ptr = instance_id;
+    claim_value.len  = size;
+    attest_token_add_bstr(token_ctx,
+                          EAT_CBOR_ARM_LABEL_UEID,
+                          &claim_value);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -368,13 +488,12 @@
 /*!
  * \brief Static function to add implementation id claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_implementation_id_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_implementation_id_claim(struct attest_token_ctx *token_ctx)
 {
     /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
      *        type is configured in the MPU to be normal, instead of device,
@@ -382,23 +501,20 @@
      */
     __attribute__ ((aligned(4)))
     uint8_t implementation_id[IMPLEMENTATION_ID_MAX_SIZE];
-    uint32_t res;
     enum tfm_plat_err_t res_plat;
     uint32_t size = sizeof(implementation_id);
+    struct useful_buf_c claim_value;
 
     res_plat = tfm_plat_get_implementation_id(&size, implementation_id);
     if (res_plat != TFM_PLAT_ERR_SUCCESS) {
         return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
     }
 
-    res = attest_add_tlv(TLV_MINOR_IAS_IMPLEMENTATION_ID,
-                         size,
-                         implementation_id,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    claim_value.ptr = implementation_id;
+    claim_value.len  = size;
+    attest_token_add_bstr(token_ctx,
+                          EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID,
+                          &claim_value);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -406,13 +522,12 @@
 /*!
  * \brief Static function to add hardware version claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_hw_version_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_hw_version_claim(struct attest_token_ctx *token_ctx)
 {
     /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
      *        type is configured in the MPU to be normal, instead of device,
@@ -420,23 +535,20 @@
      */
     __attribute__ ((aligned(4)))
     uint8_t hw_version[HW_VERSION_MAX_SIZE];
-    uint32_t res;
     enum tfm_plat_err_t res_plat;
     uint32_t size = sizeof(hw_version);
+    struct useful_buf_c claim_value;
 
     res_plat = tfm_plat_get_hw_version(&size, hw_version);
     if (res_plat != TFM_PLAT_ERR_SUCCESS) {
         return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
     }
 
-    res = attest_add_tlv(TLV_MINOR_IAS_HW_VERSION,
-                         size,
-                         hw_version,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    claim_value.ptr = hw_version;
+    claim_value.len  = size;
+    attest_token_add_tstr(token_ctx,
+                          EAT_CBOR_ARM_LABEL_HW_VERSION,
+                          &claim_value);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -445,13 +557,12 @@
 /*!
  * \brief Static function to add caller id claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_caller_id_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_caller_id_claim(struct attest_token_ctx *token_ctx)
 {
     uint32_t res;
     int32_t  caller_id;
@@ -461,14 +572,9 @@
         return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
     }
 
-    res = attest_add_tlv(TLV_MINOR_IAS_CALLER_ID,
-                         sizeof(int32_t),
-                         (uint8_t *)&caller_id,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    attest_token_add_integer(token_ctx,
+                             EAT_CBOR_ARM_LABEL_CLIENT_ID,
+                             (int64_t)caller_id);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -476,27 +582,20 @@
 /*!
  * \brief Static function to add security lifecycle claim to attestation token.
  *
- * \param[in]  token_buf_size Size of token buffer in bytes
- * \param[out] token_buf      Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_security_lifecycle_claim(uint32_t token_buf_size, uint8_t *token_buf)
+attest_add_security_lifecycle_claim(struct attest_token_ctx *token_ctx)
 {
-    uint32_t res;
     enum tfm_security_lifecycle_t security_lifecycle;
 
     security_lifecycle = tfm_attest_hal_get_security_lifecycle();
 
-    res = attest_add_tlv(TLV_MINOR_IAS_SECURITY_LIFECYCLE,
-                         sizeof(enum tfm_security_lifecycle_t),
-                         (uint8_t *)&security_lifecycle,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    attest_token_add_integer(token_ctx,
+                             EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE,
+                             (int64_t)security_lifecycle);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
@@ -504,54 +603,24 @@
 /*!
  * \brief Static function to add challenge claim to attestation token.
  *
- * \param[in]  challenge_buf_size Size of challenge object in bytes
- * \param[in]  challenge_buf      Pointer to buffer which stores the challenge
- *                                object
- * \param[in]  token_buf_size     Size of token buffer in bytes
- * \param[out] token_buf          Pointer to buffer which stores the token
+ * \param[in]  token_ctx  Token encoding context
+ * \param[in]  challenge  Pointer to buffer which stores the challenge
  *
  * \return Returns error code as specified in \ref psa_attest_err_t
  */
 static enum psa_attest_err_t
-attest_add_challenge_claim(uint32_t       challenge_buf_size,
-                           const uint8_t *challenge_buf,
-                           uint32_t       token_buf_size,
-                           uint8_t       *token_buf)
+attest_add_challenge_claim(struct attest_token_ctx   *token_ctx,
+                           const struct useful_buf_c *challenge)
 {
-    uint32_t res;
-
-    res = attest_add_tlv(TLV_MINOR_IAS_CHALLENGE,
-                         challenge_buf_size,
-                         challenge_buf,
-                         token_buf_size,
-                         token_buf);
-    if (res != 0) {
-        return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
-    }
+    attest_token_add_bstr(token_ctx, EAT_CBOR_ARM_LABEL_CHALLENGE, challenge);
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
 
 /*!
- * \brief Static function to retrieve the constructed attestation token's size.
- *
- * \param[in] token_buf Pointer to buffer which stores the token
- *
- * \return Returns the size of token in bytes
- */
-static uint32_t attest_get_token_size(const uint8_t *token_buf)
-{
-    struct shared_data_tlv_header *tlv_header;
-
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-
-    return tlv_header->tlv_tot_len;
-}
-
-/*!
  * \brief Static function to verify the input challenge size
  *
- * Only discrete sizes are accepted.
+ *  Only discrete sizes are accepted.
  *
  * \param[in] challenge_size  Size of challenge object in bytes.
  *
@@ -572,11 +641,129 @@
     return PSA_ATTEST_ERR_INVALID_INPUT;
 }
 
-/* Initial implementation of attestation service:
- *  - data is TLV encoded
- *  - token is not signed yet
- *  - only fixed set of claims are supported
- *  - external claims are not handled, expect challenge object
+/*!
+ * \brief Static function to create the initial attestation token
+ *
+ * \param[in]  challenge        Structure to carry the challenge value:
+ *                              pointer + challeng's length
+ * \param[in]  token            Structure to carry the token info, where to
+ *                              create it: pointer + buffer's length
+ * \param[out] completed_token  Structure to carry the info about the created
+ *                              token: pointer + final token's length
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_create_token(struct useful_buf_c *challenge,
+                    struct useful_buf   *token,
+                    struct useful_buf_c *completed_token)
+{
+    enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
+    enum attest_token_err_t token_err;
+    struct attest_token_ctx attest_token_ctx;
+    int32_t key_select;
+    int32_t alg_select;
+    uint32_t option_flags = 0;
+
+    if (challenge->len == 36) {
+        /* FixMe: Special challenge with option flags appended. This might can
+         *        be removed when the public API can take option_flags.
+         */
+        option_flags = *(uint32_t *)(challenge->ptr + 32);
+        challenge->len = 32;
+    }
+
+    /* Lower three bits are the key select */
+    key_select = option_flags & 0x7;
+
+    /* Map the key select to an algorithm. Maybe someday we'll support something
+     * other than ES256
+     */
+    switch (key_select) {
+    default:
+        alg_select = COSE_ALGORITHM_ES256;
+    }
+
+    /* Get started creating the token. This sets up the CBOR and COSE contexts
+     * 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   */
+                                   token);
+
+    if (token_err != ATTEST_TOKEN_ERR_SUCCESS) {
+        attest_err = error_mapping(token_err);
+        goto error;
+    }
+
+    attest_err = attest_add_challenge_claim(&attest_token_ctx,
+                                            challenge);
+    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+        goto error;
+    }
+
+    if (!(option_flags & TOKEN_OPT_OMIT_CLAIMS)) {
+        attest_err = attest_add_boot_seed_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+
+        /* FixMe: Remove this #if when MPU will be configured properly.
+         *        Currently in case of TFM_LVL == 3 unaligned access triggers
+         *        a usage fault exception.
+         */
+#if !defined(TFM_LVL) || (TFM_LVL == 1)
+        attest_err = attest_add_instance_id_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+
+        attest_err = attest_add_hw_version_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+
+        attest_err = attest_add_implementation_id_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+#endif
+
+        attest_err = attest_add_caller_id_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+
+        attest_err = attest_add_security_lifecycle_claim(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+
+        attest_err = attest_add_all_sw_components(&attest_token_ctx);
+        if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+            goto error;
+        }
+    }
+
+    /* Finish up creating the token. This is where the actual signature
+     * is generated. This finishes up the CBOR encoding too.
+     */
+    token_err = attest_token_finish(&attest_token_ctx, completed_token);
+    if (token_err) {
+        attest_err = error_mapping(token_err);
+        goto error;
+    }
+
+error:
+    return attest_err;
+}
+
+/* Limitations of the current implementation:
+ *  - Token is not signed yet properly, just a fake signature is added to the
+ *    token due to lack of psa_asymmetric_sign() implementation in crypto
+ *    service.
  */
 enum psa_attest_err_t
 initial_attest_get_token(const psa_invec  *in_vec,  uint32_t num_invec,
@@ -584,91 +771,43 @@
 {
     enum tfm_status_e tfm_err;
     enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
+    struct useful_buf_c challenge;
+    struct useful_buf token;
+    struct useful_buf_c completed_token;
 
-    const uint8_t *challenge_buf = (uint8_t *)in_vec[0].base;
-    size_t   challenge_buf_size  = in_vec[0].len;
-    uint8_t *token_buf           = (uint8_t *)out_vec[0].base;
-    size_t  *token_buf_size      = &(out_vec[0].len);
+    challenge.ptr = in_vec[0].base;
+    challenge.len = in_vec[0].len;
+    token.ptr = out_vec[0].base;
+    token.len = out_vec[0].len;
 
-    attest_err = attest_verify_challenge_size(challenge_buf_size);
+    attest_err = attest_verify_challenge_size(challenge.len);
     if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
         goto error;
     }
 
-    tfm_err = tfm_core_memory_permission_check((void *)challenge_buf,
-                                               challenge_buf_size,
+    tfm_err = tfm_core_memory_permission_check((void *)challenge.ptr,
+                                               challenge.len,
                                                TFM_MEMORY_ACCESS_RO);
     if (tfm_err != TFM_SUCCESS) {
         attest_err =  PSA_ATTEST_ERR_INVALID_INPUT;
         goto error;
     }
 
-    tfm_err = tfm_core_memory_permission_check(token_buf,
-                                               *token_buf_size,
+    tfm_err = tfm_core_memory_permission_check(token.ptr,
+                                               token.len,
                                                TFM_MEMORY_ACCESS_RW);
     if (tfm_err != TFM_SUCCESS) {
         attest_err =  PSA_ATTEST_ERR_INVALID_INPUT;
         goto error;
     }
 
-    attest_err = attest_init_token(*token_buf_size, token_buf);
+    attest_err = attest_create_token(&challenge, &token, &completed_token);
     if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
         goto error;
     }
 
-    attest_err = attest_add_sw_module_claims(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    attest_err = attest_add_boot_seed_claim(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    /* FixMe: Remove this #if when MPU will be configured properly. Currently
-     *        in case of TFM_LVL == 3 unaligned access triggers a usage fault
-     *        exception.
-     */
-#if !defined(TFM_LVL) || (TFM_LVL == 1)
-    attest_err = attest_add_instance_id_claim(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    attest_err = attest_add_hw_version_claim(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    attest_err = attest_add_implementation_id_claim(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-#endif
-
-    attest_err = attest_add_challenge_claim(challenge_buf_size,
-                                            challenge_buf,
-                                            *token_buf_size,
-                                            token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    attest_err = attest_add_caller_id_claim(*token_buf_size, token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-    attest_err = attest_add_security_lifecycle_claim(*token_buf_size,
-                                                     token_buf);
-    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
-        goto error;
-    }
-
-     /* FixMe: Token should be signed with attestation key */
-
-    *token_buf_size = attest_get_token_size(token_buf);
+    out_vec[0].base = (void *)completed_token.ptr;
+    out_vec[0].len  = completed_token.len;
 
 error:
     return attest_err;
@@ -682,6 +821,17 @@
     enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
     uint32_t  challenge_size = *(uint32_t *)in_vec[0].base;
     uint32_t *token_buf_size = (uint32_t *)out_vec[0].base;
+    struct useful_buf_c challenge;
+    struct useful_buf token;
+    struct useful_buf_c completed_token;
+
+    /* Only the size of the challenge is needed */
+    challenge.ptr = NULL;
+    challenge.len = challenge_size;
+
+    /* Special value to get the size of the token, but token is not created */
+    token.ptr = NULL;
+    token.len = INT32_MAX;
 
     if (out_vec[0].len < sizeof(uint32_t)) {
         attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
@@ -693,7 +843,12 @@
         goto error;
     }
 
-    *token_buf_size = PSA_INITIAL_ATTEST_TOKEN_SIZE;
+    attest_err = attest_create_token(&challenge, &token, &completed_token);
+    if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+        goto error;
+    }
+
+    *token_buf_size = completed_token.len;
 
 error:
     return attest_err;
diff --git a/secure_fw/services/initial_attestation/manifest.yaml b/secure_fw/services/initial_attestation/manifest.yaml
index 4d607af..1de3305 100644
--- a/secure_fw/services/initial_attestation/manifest.yaml
+++ b/secure_fw/services/initial_attestation/manifest.yaml
@@ -38,6 +38,8 @@
     "attestation_core.c",
     "attestation_crypto_stub.c",
     "attestation_key.c",
+    "attest_token.c",
+
   ],
   "tfm_linker_pattern": [
     "library_list": [
diff --git a/test/suites/attestation/CMakeLists.inc b/test/suites/attestation/CMakeLists.inc
index c503554..45a0613 100644
--- a/test/suites/attestation/CMakeLists.inc
+++ b/test/suites/attestation/CMakeLists.inc
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,8 +29,13 @@
 elseif(ENABLE_ATTESTATION_SERVICE_TESTS)
 	list(APPEND ALL_SRC_C_S  "${ATTESTATION_TEST_DIR}/secure/attestation_s_interface_testsuite.c")
 	list(APPEND ALL_SRC_C_NS "${ATTESTATION_TEST_DIR}/non_secure/attestation_ns_interface_testsuite.c")
+	list(APPEND ALL_SRC_C_NS "${ATTESTATION_TEST_DIR}/token_test.c")
 
 	#Setting include directories
 	embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
 	embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
+	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/t_cose/inc ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/src ABSOLUTE)
 endif()
diff --git a/test/suites/attestation/attestation_tests_common.h b/test/suites/attestation/attestation_tests_common.h
index be85a69..041f0ac 100644
--- a/test/suites/attestation/attestation_tests_common.h
+++ b/test/suites/attestation/attestation_tests_common.h
@@ -8,8 +8,6 @@
 #ifndef __ATTESTATION_TESTS_COMMON_H__
 #define __ATTESTATION_TESTS_COMMON_H__
 
-#include "psa_initial_attestation_api.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -19,7 +17,7 @@
  *
  * \brief Size of token buffer in bytes.
  */
-#define TEST_TOKEN_SIZE PSA_INITIAL_ATTEST_TOKEN_SIZE
+#define TEST_TOKEN_SIZE (0x200)
 
 /*!
  * \def TOO_SMALL_TOKEN_BUFFER
diff --git a/test/suites/attestation/non_secure/attestation_ns_interface_testsuite.c b/test/suites/attestation/non_secure/attestation_ns_interface_testsuite.c
index 7135a56..7c2e28f 100644
--- a/test/suites/attestation/non_secure/attestation_ns_interface_testsuite.c
+++ b/test/suites/attestation/non_secure/attestation_ns_interface_testsuite.c
@@ -16,6 +16,7 @@
 #include "tfm_api.h"
 #include <string.h>
 #include <stdlib.h>
+#include "../token_test.h"
 
 static uint8_t token_buffer[TEST_TOKEN_SIZE];
 static uint8_t challenge_buffer[TEST_CHALLENGE_OBJ_SIZE];
@@ -24,58 +25,21 @@
 /* List of tests */
 static void tfm_attest_test_2001(struct test_result_t *ret);
 static void tfm_attest_test_2002(struct test_result_t *ret);
+static void tfm_attest_test_2003(struct test_result_t *ret);
+static void tfm_attest_test_2004(struct test_result_t *ret);
 
 static struct test_t attestation_interface_tests[] = {
     {&tfm_attest_test_2001, "TFM_ATTEST_TEST_2001",
      "Get attestation token and check claims", {0} },
     {&tfm_attest_test_2002, "TFM_ATTEST_TEST_2002",
      "Negative test cases for initial attestation service", {0} },
+    {&tfm_attest_test_2003, "TFM_ATTEST_TEST_2003",
+     "Minimal token test for CBOR/COSE encoding", {0} },
+    {&tfm_attest_test_2004, "TFM_ATTEST_TEST_2004",
+     "Minimal token size test for CBOR/COSE encoding", {0} },
 };
 
 /*!
- * \brief Static function to iterates over the TLV fields in the attestation
- *        token and look for the location of the specified TLV type.
- *
- * \param[in]  minor_type The identifier of the TLV data entry
- * \param[in]  token_buf  Pointer to the buffer which stores the token
- * \param[out] tlv_ptr    Pointer to the TLV data entry
- *
- * \return Returns 0 on success. Otherwise, 1.
- */
-static uint32_t attest_get_tlv_data(uint16_t  minor_type,
-                                    uint8_t  *token_buf,
-                                    uint8_t **tlv_data_ptr)
-{
-    struct shared_data_tlv_header *tlv_header;
-    struct shared_data_tlv_entry  *tlv_entry;
-    uintptr_t tlv_end;
-    uintptr_t tlv_curr;
-
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-    if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
-        return 1u;
-    }
-
-    /* Get the boundaries of TLV section */
-    tlv_end  = (uintptr_t)token_buf + tlv_header->tlv_tot_len;
-    tlv_curr = (uintptr_t)token_buf + SHARED_DATA_HEADER_SIZE;
-
-    /* Iterates over the TLV section and copy TLVs with requested minor
-     * type to the provided buffer.
-     */
-    for(; tlv_curr < tlv_end; tlv_curr += tlv_entry->tlv_len) {
-        tlv_entry = (struct shared_data_tlv_entry *)tlv_curr;
-        if (GET_MINOR(tlv_entry->tlv_type) == minor_type) {
-            *tlv_data_ptr = (uint8_t *)tlv_entry +
-                            SHARED_DATA_ENTRY_HEADER_SIZE;
-            return 0;
-        }
-    }
-
-    return 1u;
-}
-
-/*!
  * \brief Static function to generate a random byte stream. It is used as a
  *        challenge object to test attestation service.
  *
@@ -120,29 +84,11 @@
  * \brief Positive tests for initial attestation service
  *
  *      - Calling Initial Attestation service to get token
- *      - Check the existence of the fixed set of claims:
- *          - Boot status
- *          - Boot seed
- *          - Instance ID
- *          - Challenge object
- *          - Caller ID
- *          - Implementation ID
- *          - Hardware version
- *          - Security lifecycle
- *      - Comparing value of claims:
- *          - Boot seed: Compare boot seed from subsequent calls
- *          - Device ID: Currently compare with fix value
- *          - Challenge: Compare with input object
- *          - Caller ID: Check whether is it in non-secure range
  */
 static void tfm_attest_test_2001(struct test_result_t *ret)
 {
     enum psa_attest_err_t err;
     uint32_t token_size;
-    uint8_t boot_seed_buffer[BOOT_SEED_SIZE];
-    uint8_t *tlv_data_ptr;
-    int32_t caller_id;
-    uint32_t res;
 
     generate_challenge(TEST_CHALLENGE_OBJ_SIZE, challenge_buffer);
 
@@ -154,8 +100,8 @@
         return;
     }
 
-    if (token_size != PSA_INITIAL_ATTEST_TOKEN_SIZE) {
-        TEST_FAIL("Token size is faulty");
+    if (token_size > TEST_TOKEN_SIZE) {
+        TEST_FAIL("Allocated buffer is smaller than required");
         return;
     }
 
@@ -169,119 +115,6 @@
         return;
     }
 
-    /* Check IMAGE HASH
-     * The image hash cannot be retrieved from image manifest if code runs in
-     * NS context, because the image header resides in S memory area.
-     */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_S_NS_MEASURE_VALUE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_S_NS_SHA256");
-        return;
-    }
-
-    /* FixMe: Remove this #if when MPU will be configured properly. Currently
-     *        in case of TFM_LVL == 3 unaligned access triggers a usage fault
-     *        exception.
-     */
-#if !defined(TFM_LVL) || (TFM_LVL == 1)
-    /* Check INSTANCE_ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_INSTANCE_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_INSTANCE_ID");
-        return;
-    }
-
-    /* Check IMPLEMENTATION_ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_IMPLEMENTATION_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_IMPLEMENTATION_ID");
-        return;
-    }
-
-    /* Check HARDWARE_VERSION, optional claim */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_HW_VERSION, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_HW_VERSION");
-        return;
-    }
-#endif
-
-    /* Check SECURITY LIFECYCLE */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_SECURITY_LIFECYCLE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_SECURITY_LIFECYCLE");
-        return;
-    }
-
-    /* Check CHALLENGE */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_CHALLENGE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_CHALLENGE");
-        return;
-    }
-    if (tfm_memcmp(tlv_data_ptr, challenge_buffer,
-                   TEST_CHALLENGE_OBJ_SIZE) != 0) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_CHALLENGE");
-        return;
-    }
-
-    /* Check CALLER ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_CALLER_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_CALLER_ID");
-        return;
-    }
-
-    caller_id = *((int32_t *)tlv_data_ptr);
-    if (!TFM_CLIENT_ID_IS_NS(caller_id)) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_CALLER_ID");
-        return;
-    }
-
-    /* Check BOOT_SEED */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_BOOT_SEED, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
-    /* Store received boot seed. */
-    tfm_memcpy(boot_seed_buffer, tlv_data_ptr, BOOT_SEED_SIZE);
-
-    /* Call attest API again and compare the value of boot seed on subsequent
-     * calls. They must be equal within the same boot cycle.
-     */
-    err = psa_initial_attest_get_token(challenge_buffer,
-                                       TEST_CHALLENGE_OBJ_SIZE,
-                                       token_buffer,
-                                       &token_size);
-    if (err != PSA_ATTEST_ERR_SUCCESS) {
-        TEST_FAIL("Get token failed");
-        return;
-    }
-
-    /* Get boot seed again */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_BOOT_SEED, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
-    /*Compare the values of boot seed on subsequent calls */
-    if (tfm_memcmp(tlv_data_ptr, boot_seed_buffer, BOOT_SEED_SIZE) != 0) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
     ret->val = TEST_PASSED;
 }
 
@@ -316,10 +149,48 @@
                                        token_buffer,
                                        &token_size);
 
-    if (err == PSA_ATTEST_ERR_SUCCESS) {
+    if (err != PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW) {
         TEST_FAIL("Attestation should fail with too small token buffer");
         return;
     }
 
     ret->val = TEST_PASSED;
 }
+
+/*!
+ * \brief Get minimal token, only include a hard coded challenge, but omit the
+ *        rest of the claims
+ *
+ * Calling the minimal_test, which just retrieves a specific token:
+ *  - only hard coded challenge is included
+ *  - token signature is the hash of the token concatenated twice
+ */
+static void tfm_attest_test_2003(struct test_result_t *ret)
+{
+    enum psa_attest_err_t err;
+
+    err = minimal_test();
+    if (err != PSA_ATTEST_ERR_SUCCESS) {
+        TEST_FAIL("CBOR/COSE minimal_test has failed");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/*!
+ * \brief Get the size of the minimal token, only include a hard coded
+ *        challenge, but omit the rest of the claims
+ */
+static void tfm_attest_test_2004(struct test_result_t *ret)
+{
+    enum psa_attest_err_t err;
+
+    err = minimal_get_size_test();
+    if (err != PSA_ATTEST_ERR_SUCCESS) {
+        TEST_FAIL("CBOR/COSE minimal_get_size_test has failed");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
diff --git a/test/suites/attestation/secure/attestation_s_interface_testsuite.c b/test/suites/attestation/secure/attestation_s_interface_testsuite.c
index 91852bd..951e0ed 100644
--- a/test/suites/attestation/secure/attestation_s_interface_testsuite.c
+++ b/test/suites/attestation/secure/attestation_s_interface_testsuite.c
@@ -9,13 +9,9 @@
 #include "psa_initial_attestation_api.h"
 #include "secure_fw/services/initial_attestation/attestation.h"
 #include "../attestation_tests_common.h"
-#include "bl2/include/tfm_boot_status.h"
-#include "bl2/ext/mcuboot/bootutil/include/bootutil/image.h"
 #include "secure_utilities.h"
 #include "platform/include/tfm_plat_device_id.h"
 #include "platform/include/tfm_plat_boot_seed.h"
-#include "flash_layout.h"
-#include "spm_partition_defs.h"
 #include <string.h>
 #include <stdlib.h>
 
@@ -35,108 +31,6 @@
      "Negative test cases for initial attestation service", {0} },
 };
 
-/*!
- * \brief Static function to iterates over the TLV fields in the attestation
- *        token and look for the location of the specified TLV type.
- *
- * \param[in]  minor_type The identifier of the TLV data entry
- * \param[in]  token_buf  Pointer to the buffer which stores the token
- * \param[out] tlv_ptr    Pointer to the TLV data entry
- *
- * \return Returns 0 on success. Otherwise, 1.
- */
-static uint32_t attest_get_tlv_data(uint16_t  minor_type,
-                                    uint8_t  *token_buf,
-                                    uint8_t **tlv_data_ptr)
-{
-    struct shared_data_tlv_header *tlv_header;
-    struct shared_data_tlv_entry  *tlv_entry;
-    uintptr_t tlv_end;
-    uintptr_t tlv_curr;
-
-    tlv_header = (struct shared_data_tlv_header *)token_buf;
-    if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
-        return 1u;
-    }
-
-    /* Get the boundaries of TLV section */
-    tlv_end  = (uintptr_t)token_buf + tlv_header->tlv_tot_len;
-    tlv_curr = (uintptr_t)token_buf + SHARED_DATA_HEADER_SIZE;
-
-    /* Iterates over the TLV section and copy TLVs with requested minor
-     * type to the provided buffer.
-     */
-    for(; tlv_curr < tlv_end; tlv_curr += tlv_entry->tlv_len) {
-        tlv_entry = (struct shared_data_tlv_entry *)tlv_curr;
-        if (GET_MINOR(tlv_entry->tlv_type) == minor_type) {
-            *tlv_data_ptr = (uint8_t *)tlv_entry +
-                            SHARED_DATA_ENTRY_HEADER_SIZE;
-            return 0;
-        }
-    }
-
-    return 1u;
-}
-
-/*!
- * \brief Get image hash from the image manifest.
- *
- * This function iterates over the image manifest section to look for
- * the image's hash value. This manifest section is also TLV encoded.
- * This function can be called if TFM_LVL == 1, to avoid MemMange fault, which
- * is triggered by enabled MPU at level 3 isolation.
- *
- * Note 1: The access of manifest section must be done with NS alias to avoid
- *         MPC fault, because manifest section is configured to be NS memory.
- *
- * Note 2: This function assumes that active image resides in slot 0 or in RAM
- *         pointing by LOAD_ADDRESS macro. But these assumptions might not be
- *         valid if MCUBOOT_NO_SWAP mode is used.
- *
- * \param[out] Pointer to the location of image hash value in the image
- *             manifest section.
- *
- * \return Returns 0 on success. Otherwise, 1.
- */
-#if !defined(TFM_LVL) || (TFM_LVL == 1)
-/* FixMe: This offset should be calculated per device */
-#define USUAL_S_NS_ALIAS_OFFSET 0x10000000u
-static uint32_t attest_get_s_ns_sha256(uint8_t **hash)
-{
-    struct image_header *image_header;
-    struct image_tlv_info *tlv_info;
-    struct image_tlv *tlv_entry;
-    uint32_t image_header_address;
-    uint8_t *off;
-    uint8_t *end;
-
-#ifdef LOAD_ADDRESS
-    image_header_address = LOAD_ADDRESS;
-#else
-    image_header_address = (FLASH_BASE_ADDRESS + FLASH_AREA_IMAGE_0_OFFSET);
-#endif
-    image_header = (struct image_header *)image_header_address;
-    /* Calculates NS memory alias of manifest section */
-    tlv_info     = (struct image_tlv_info *)(image_header_address +
-                                             image_header->ih_hdr_size +
-                                             image_header->ih_img_size -
-                                             USUAL_S_NS_ALIAS_OFFSET);
-
-    end = (uint8_t *)tlv_info + tlv_info->it_tlv_tot;
-    off = (uint8_t *)tlv_info + sizeof(struct image_tlv_info);
-
-    for (; off < end; off += sizeof(struct image_tlv) + tlv_entry->it_len) {
-        tlv_entry = (struct image_tlv *)(off);
-        if (tlv_entry->it_type == IMAGE_TLV_SHA256) {
-                *hash = (uint8_t *)tlv_entry + sizeof(struct image_tlv);
-                return 0;
-        }
-    }
-
-    return 1u;
-}
-#endif
-
 void
 register_testsuite_s_attestation_interface(struct test_suite_t *p_test_suite)
 {
@@ -154,31 +48,11 @@
  * \brief Positive tests for initial attestation service
  *
  *      - Calling Initial Attestation service to get token
- *      - Check the existence of the fixed set of claims:
- *          - Boot status
- *          - Boot seed
- *          - Instance ID
- *          - Challenge object
- *          - Caller ID
- *          - Implementation ID
- *          - Hardware version
- *          - Security lifecycle
- *      - Comparing value of claims:
- *          - Boot status: Get boot status from token and from image manifest
- *                         and compare them
- *          - Boot seed: Compare boot seed from subsequent calls
- *          - Device ID: Currently compare with fix value
- *          - Challenge: Compare with input object
- *          - Caller ID: Check whether is it in non-secure range
  */
 static void tfm_attest_test_1001(struct test_result_t *ret)
 {
     enum psa_attest_err_t err;
     uint32_t token_size;
-    uint8_t boot_seed_buffer[BOOT_SEED_SIZE];
-    uint8_t *tlv_data_ptr;
-    int32_t caller_id;
-    uint32_t res;
 
     /* Get attestation token size */
     err = psa_initial_attest_get_token_size(TEST_CHALLENGE_OBJ_SIZE,
@@ -188,8 +62,8 @@
         return;
     }
 
-    if (token_size != PSA_INITIAL_ATTEST_TOKEN_SIZE) {
-        TEST_FAIL("Token size is faulty");
+    if (token_size > TEST_TOKEN_SIZE) {
+        TEST_FAIL("Allocated buffer is smaller than required");
         return;
     }
 
@@ -206,135 +80,14 @@
         return;
     }
 
-    /* Check IMAGE HASH */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_S_NS_MEASURE_VALUE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_S_NS_SHA256");
-        return;
-    }
-    /* Extract image hash from manifest data and compare with claim.
-     * This can be done only from secure side if S_MPU is not enabled.
-     */
-#if !defined(TFM_LVL) || (TFM_LVL == 1)
-    uint8_t *hash_from_image;
-    res = attest_get_s_ns_sha256(&hash_from_image);
-    if (res == 0) {
-        if (tfm_memcmp(tlv_data_ptr, hash_from_image, 32) != 0) {
-            TEST_FAIL("Faulty claim: TLV_MINOR_IAS_S_NS_SHA256");
-            return;
-        }
-    }
-#endif
-
-    /* FixMe: Remove this #if when MPU will be configured properly. Currently
-     *        in case of TFM_LVL == 3 unaligned access triggers a usage fault
-     *        exception.
-     */
-#if !defined(TFM_LVL) || (TFM_LVL == 1)
-    /* Check INSTANCE_ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_INSTANCE_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_INSTANCE_ID");
-        return;
-    }
-
-    /* Check IMPLEMENTATION_ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_IMPLEMENTATION_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_IMPLEMENTATION_ID");
-        return;
-    }
-
-    /* Check HARDWARE_VERSION, optional claim */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_HW_VERSION, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_HW_VERSION");
-        return;
-    }
-#endif
-
-    /* Check SECURITY LIFECYCLE */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_SECURITY_LIFECYCLE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_SECURITY_LIFECYCLE");
-        return;
-    }
-
-    /* Check CHALLENGE */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_CHALLENGE, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_CHALLENGE");
-        return;
-    }
-    if (tfm_memcmp(tlv_data_ptr, challenge_buffer,
-                   TEST_CHALLENGE_OBJ_SIZE) != 0) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_CHALLENGE");
-        return;
-    }
-
-    /* Check CALLER ID */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_CALLER_ID, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_CALLER_ID");
-        return;
-    }
-
-    caller_id = *((int32_t *)tlv_data_ptr);
-    if (caller_id < TFM_SP_BASE) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_CALLER_ID");
-        return;
-    }
-
-    /* Check BOOT_SEED */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_BOOT_SEED, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
-    /* Store received boot seed. */
-    tfm_memcpy(boot_seed_buffer, tlv_data_ptr, BOOT_SEED_SIZE);
-
-    /* Call attest API again and compare the value of boot seed on subsequent
-     * calls. They must be equal within the same boot cycle.
-     */
-    err = psa_initial_attest_get_token(challenge_buffer,
-                                       TEST_CHALLENGE_OBJ_SIZE,
-                                       token_buffer,
-                                       &token_size);
-    if (err != PSA_ATTEST_ERR_SUCCESS) {
-        TEST_FAIL("Get token failed");
-        return;
-    }
-
-    /* Get boot seed again */
-    res = attest_get_tlv_data(TLV_MINOR_IAS_BOOT_SEED, token_buffer,
-                              &tlv_data_ptr);
-    if (res != 0) {
-        TEST_FAIL("Missing claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
-    /*Compare the values of boot seed on subsequent calls */
-    if (tfm_memcmp(tlv_data_ptr, boot_seed_buffer, BOOT_SEED_SIZE) != 0) {
-        TEST_FAIL("Faulty claim: TLV_MINOR_IAS_BOOT_SEED");
-        return;
-    }
-
     ret->val = TEST_PASSED;
 }
 
 /*!
  * \brief Negative tests for initial attestation service
  *
+ *    - Calling initial attestation service with bigger challenge object than
+ *      allowed.
  *    - Calling initial attestation service with smaller buffer size than the
  *      expected size of the token.
  */
@@ -343,6 +96,17 @@
     enum psa_attest_err_t err;
     uint32_t token_size = TEST_TOKEN_SIZE;
 
+    /* Call with with bigger challenge object than allowed */
+    err = psa_initial_attest_get_token(challenge_buffer,
+                                       INVALID_CHALLENGE_OBJECT_SIZE,
+                                       token_buffer,
+                                       &token_size);
+
+    if (err != PSA_ATTEST_ERR_INVALID_INPUT) {
+        TEST_FAIL("Attestation should fail with too big challenge object");
+        return;
+    }
+
     /* Call with smaller buffer size than size of test token */
     token_size = TOO_SMALL_TOKEN_BUFFER;
     err = psa_initial_attest_get_token(challenge_buffer,
@@ -351,7 +115,7 @@
                                        &token_size);
 
     if (err != PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW) {
-        TEST_FAIL("Attestation should fail with small buffer");
+        TEST_FAIL("Attestation should fail with too small token buffer");
         return;
     }