Attest: Support kid parameter in COSE_Mac0 structure header

Add a HAL API tfm_plat_get_symmetric_iak_id() to fetch kid from
platform.
Implement an example of this HAL API.

Add attest_get_symmetric_iak_id() to pass the kid value to token
generation of symmetric key algorithm based Initial Attestation.

Change-Id: I642f7a03f1738c8fe77f11fc2ae91652fc01df29
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/secure_fw/partitions/initial_attestation/attest_symmetric_key.c b/secure_fw/partitions/initial_attestation/attest_symmetric_key.c
index 599a46a..cdc8a3e 100644
--- a/secure_fw/partitions/initial_attestation/attest_symmetric_key.c
+++ b/secure_fw/partitions/initial_attestation/attest_symmetric_key.c
@@ -20,6 +20,9 @@
 /* Hash algorithm for calculating Instance ID */
 #define INSTANCE_ID_HASH_ALG          PSA_ALG_SHA_256
 
+/* Length of kid buffer */
+#define KID_BUF_LEN                   32
+
 /* Symmetric IAK handle */
 static psa_key_handle_t symmetric_iak_handle = 0;
 
@@ -27,6 +30,13 @@
 static uint8_t instance_id_buf[PSA_HASH_SIZE(INSTANCE_ID_HASH_ALG) + 1];
 static size_t instance_id_len = 0;
 
+#ifdef INCLUDE_COSE_KEY_ID
+/* kid buffer */
+static uint8_t kid_buf[KID_BUF_LEN];
+/* Actual kid length */
+static size_t kid_len = 0;
+#endif
+
 static psa_status_t destroy_iak(psa_key_handle_t *iak_handle)
 {
     psa_status_t res;
@@ -206,6 +216,11 @@
     /* Invalidate the Instance ID as well */
     instance_id_len = 0;
 
+#ifdef INCLUDE_COSE_KEY_ID
+    /* Invalidate the corresponding kid as well */
+    kid_len = 0;
+#endif
+
     return PSA_ATTEST_ERR_SUCCESS;
 }
 
@@ -237,3 +252,44 @@
 
     return PSA_ATTEST_ERR_SUCCESS;
 }
+
+#ifdef INCLUDE_COSE_KEY_ID
+enum psa_attest_err_t
+attest_get_initial_attestation_key_id(struct q_useful_buf_c *attest_key_id)
+{
+    enum tfm_plat_err_t plat_res;
+
+    if (!attest_key_id) {
+        return PSA_ATTEST_ERR_GENERAL;
+    }
+
+    /* The kid has not been fetched previously */
+    if (!kid_len) {
+        plat_res = tfm_plat_get_symmetric_iak_id(kid_buf,
+                                                 sizeof(kid_buf),
+                                                 &kid_len);
+        /* In case the buffer size was not checked, although unlikely */
+        if (sizeof(kid_buf) < kid_len) {
+            /*
+             * Something critical following kid_buf may be overwritten.
+             * Directly jump into fatal error handling.
+             *
+             * TODO: Should be replaced by a call to psa_panic() when it
+             * becomes available.
+             */
+            while (1) {
+                ;
+            }
+        }
+
+        if (plat_res != TFM_PLAT_ERR_SUCCESS) {
+            return PSA_ATTEST_ERR_GENERAL;
+        }
+    }
+
+    attest_key_id->ptr = (const void *)&kid_buf;
+    attest_key_id->len = kid_len;
+
+    return PSA_ATTEST_ERR_SUCCESS;
+}
+#endif /* INCLUDE_COSE_KEY_ID */
diff --git a/secure_fw/partitions/initial_attestation/attest_token.c b/secure_fw/partitions/initial_attestation/attest_token.c
index 6e2762e..43547e6 100644
--- a/secure_fw/partitions/initial_attestation/attest_token.c
+++ b/secure_fw/partitions/initial_attestation/attest_token.c
@@ -120,6 +120,14 @@
     attest_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
     attest_key.k.key_handle = (uint64_t)key_handle;
 
+    attest_ret = attest_get_initial_attestation_key_id(&attest_key_id);
+    if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
+        return ATTEST_TOKEN_ERR_GENERAL;
+    } else if (!attest_key_id.ptr || !attest_key_id.len) {
+        /* In case kid value is invalid, set it to NULL */
+        attest_key_id = NULL_Q_USEFUL_BUF_C;
+    }
+
     t_cose_mac0_set_signing_key(&(me->mac_ctx),
                                 attest_key,
                                 attest_key_id);
diff --git a/secure_fw/partitions/initial_attestation/attestation_key.h b/secure_fw/partitions/initial_attestation/attestation_key.h
index ba9e812..c0881fe 100644
--- a/secure_fw/partitions/initial_attestation/attestation_key.h
+++ b/secure_fw/partitions/initial_attestation/attestation_key.h
@@ -85,18 +85,31 @@
                                           size_t *public_key_len,
                                           psa_ecc_curve_t *public_key_curve);
 
+#ifdef INCLUDE_COSE_KEY_ID
 /**
- * \brief Get the attestation key ID. It is the hash (SHA256) of the COSE_Key
- *        encoded attestation public key.
+ * \brief Get the attestation key ID.
+ *        In asymmetric key algorithm based Initial Attestation, it is the hash
+ *        (SHA256) of the COSE_Key encoded attestation public key.
+ *        In symmetric key algorithm based Initial Attestation, the key ID raw
+ *        data is fetched from from device.
  *
  * \param[out] attest_key_id  Pointer and length of the key id.
  *
- * \retval  PSA_ATTEST_ERR_SUCCESS   Key id calculated successfully.
- * \retval  PSA_ATTEST_ERR_GENERAL   Key id calculation failed.
+ * \retval  PSA_ATTEST_ERR_SUCCESS   Got key id successfully.
+ * \retval  PSA_ATTEST_ERR_GENERAL   Failed to get key id.
 
  */
 enum psa_attest_err_t
 attest_get_initial_attestation_key_id(struct q_useful_buf_c *attest_key_id);
+#else /* INCLUDE_COSE_KEY_ID */
+static inline enum psa_attest_err_t
+attest_get_initial_attestation_key_id(struct q_useful_buf_c *attest_key_id)
+{
+    (void)attest_key_id;
+
+    return PSA_ATTEST_ERR_SUCCESS;
+}
+#endif /* INCLUDE_COSE_KEY_ID */
 
 #ifdef __cplusplus
 }