Attest: Fetch symmetric Initial Attestation Key
Implement attest_register_initial_attest_key() to fetch and register a
symmetric Initial Attestation Key (IAK).
Add tfm_plat_get_symmetric_iak() to receive the key raw data from
platform.
Add attest_get_signing_key_handle() to get the key handle of the
initial attestation key for signing IAT.
Replace attest_get_initial_attestation_private_key_handle() with
attest_get_signing_key_handle().
Also add a binary symmetric IAK file for token verification in
other tools.
Change-Id: Id2e3647cc85abd0eacbf2a0e53b6d2cd927acaaf
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/platform/ext/common/template/crypto_keys.c b/platform/ext/common/template/crypto_keys.c
index c5564e5..e005205 100644
--- a/platform/ext/common/template/crypto_keys.c
+++ b/platform/ext/common/template/crypto_keys.c
@@ -30,9 +30,15 @@
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+#ifdef SYMMETRIC_INITIAL_ATTESTATION
+extern const psa_algorithm_t tfm_attest_hmac_sign_alg;
+extern const uint8_t initial_attestation_hmac_sha256_key[];
+extern const size_t initial_attestation_hmac_sha256_key_size;
+#else /* SYMMETRIC_INITIAL_ATTESTATION */
extern const psa_ecc_curve_t initial_attestation_curve_type;
extern const uint8_t initial_attestation_private_key[];
extern const uint32_t initial_attestation_private_key_size;
+#endif /* SYMMETRIC_INITIAL_ATTESTATION */
extern const struct tfm_plat_rotpk_t device_rotpk[];
extern const uint32_t rotpk_key_cnt;
@@ -77,6 +83,33 @@
return TFM_PLAT_ERR_SUCCESS;
}
+#ifdef SYMMETRIC_INITIAL_ATTESTATION
+enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf,
+ size_t buf_len,
+ size_t *key_len,
+ psa_algorithm_t *key_alg)
+{
+ if (!key_buf || !key_len || !key_alg) {
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+ if (buf_len < initial_attestation_hmac_sha256_key_size) {
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+ /*
+ * Actual implementation may derive a key with other input, other than
+ * directly providing provisioned symmetric initial attestation key.
+ */
+ copy_key(key_buf, initial_attestation_hmac_sha256_key,
+ initial_attestation_hmac_sha256_key_size);
+
+ *key_alg = tfm_attest_hmac_sign_alg;
+ *key_len = initial_attestation_hmac_sha256_key_size;
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#else /* SYMMETRIC_INITIAL_ATTESTATION */
enum tfm_plat_err_t
tfm_plat_get_initial_attest_key(uint8_t *key_buf,
uint32_t size,
@@ -110,6 +143,7 @@
return TFM_PLAT_ERR_SUCCESS;
}
+#endif /* SYMMETRIC_INITIAL_ATTESTATION */
#ifdef BL2
enum tfm_plat_err_t
diff --git a/platform/ext/common/template/tfm_initial_attestation_key_material.c b/platform/ext/common/template/tfm_initial_attestation_key_material.c
index 65e91c0..25dec5c 100644
--- a/platform/ext/common/template/tfm_initial_attestation_key_material.c
+++ b/platform/ext/common/template/tfm_initial_attestation_key_material.c
@@ -11,6 +11,38 @@
#include "psa/crypto_types.h"
#include "psa/crypto_values.h"
+#ifdef SYMMETRIC_INITIAL_ATTESTATION
+/*
+ * This file contains the hard coded version of the secret key for HMAC.
+ *
+ * A HMAC-SHA256 key is 32 bytes long.
+ *
+ * This key is used to sign the initial attestation token in COSE_Mac0.
+ * The secret key is stored in raw format, without any encoding(ASN.1, COSE).
+ *
+ * ####### DO NOT USE THIS KEY IN PRODUCTION #######
+ */
+
+/* HMAC-SHA256 by default */
+const psa_algorithm_t tfm_attest_hmac_sign_alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
+
+/* Symmetric initial attestation key in raw format, without any encoding.
+ * It is used in HMAC-SHA256.
+ * It MUST be present on the device.
+ */
+TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint8_t initial_attestation_hmac_sha256_key[] =
+{
+ 0xA9, 0xB4, 0x54, 0xB2, 0x6D, 0x6F, 0x90, 0xA4,
+ 0xEA, 0x31, 0x19, 0x35, 0x64, 0xCB, 0xA9, 0x1F,
+ 0xEC, 0x6F, 0x9A, 0x00, 0x2A, 0x7D, 0xC0, 0x50,
+ 0x4B, 0x92, 0xA1, 0x93, 0x71, 0x34, 0x58, 0x5F
+};
+
+TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const size_t initial_attestation_hmac_sha256_key_size =
+ sizeof(initial_attestation_hmac_sha256_key);
+#else /* SYMMETRIC_INITIAL_ATTESTATION */
/*
* This file contains the hard coded version of the ECDSA P-256 secret key in:
* platform/ext/common/template/tfm_initial_attestation_key.pem
@@ -43,3 +75,4 @@
TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
const uint32_t initial_attestation_private_key_size =
sizeof(initial_attestation_private_key);
+#endif /* SYMMETRIC_INITIAL_ATTESTATION */
diff --git a/platform/ext/common/template/tfm_symmetric_iak.key b/platform/ext/common/template/tfm_symmetric_iak.key
new file mode 100644
index 0000000..06f8bce
--- /dev/null
+++ b/platform/ext/common/template/tfm_symmetric_iak.key
Binary files differ
diff --git a/platform/include/tfm_plat_crypto_keys.h b/platform/include/tfm_plat_crypto_keys.h
index 7ee9570..f9934cd 100644
--- a/platform/include/tfm_plat_crypto_keys.h
+++ b/platform/include/tfm_plat_crypto_keys.h
@@ -82,6 +82,29 @@
uint8_t *key,
size_t key_size);
+#ifdef SYMMETRIC_INITIAL_ATTESTATION
+/**
+ * \brief Get the symmetric Initial Attestation Key (IAK)
+ *
+ * The device MUST contain a symmetric IAK, which is used to sign the token.
+ * So far only HMAC is supported in symmetric key algorithm based Initial
+ * Attestation.
+ * Keys must be provided in raw format, just binary data without any encoding
+ * (DER, COSE). Caller provides a buffer to copy all the raw data.
+ *
+ * \param[out] key_buf Buffer to store the initial attestation key.
+ * \param[in] buf_len The length of buffer.
+ * \param[out] key_len Buffer to carry the length of the initial
+ * attestation key.
+ * \param[out] key_alg The key algorithm. Only HMAC is supported so far.
+ *
+ * \return Returns error code specified in \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf,
+ size_t buf_len,
+ size_t *key_len,
+ psa_algorithm_t *key_alg);
+#else /* SYMMETRIC_INITIAL_ATTESTATION */
/**
* \brief Get the initial attestation key
*
@@ -115,6 +138,7 @@
uint32_t size,
struct ecc_key_t *ecc_key,
psa_ecc_curve_t *curve_type);
+#endif /* SYMMETRIC_INITIAL_ATTESTATION */
/**
* \brief Get the hash of the corresponding Root of Trust Public Key for