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/secure_fw/partitions/initial_attestation/CMakeLists.inc b/secure_fw/partitions/initial_attestation/CMakeLists.inc
index ae61037..b0c18c1 100644
--- a/secure_fw/partitions/initial_attestation/CMakeLists.inc
+++ b/secure_fw/partitions/initial_attestation/CMakeLists.inc
@@ -41,10 +41,15 @@
"${INITIAL_ATTESTATION_DIR}/tfm_attestation.c"
"${INITIAL_ATTESTATION_DIR}/tfm_attestation_req_mngr.c"
"${INITIAL_ATTESTATION_DIR}/attestation_core.c"
- "${INITIAL_ATTESTATION_DIR}/attestation_key.c"
"${INITIAL_ATTESTATION_DIR}/attest_token.c"
)
+if (SYMMETRIC_INITIAL_ATTESTATION)
+ list(APPEND ATTEST_C_SRC "${INITIAL_ATTESTATION_DIR}/attest_symmetric_key.c")
+else()
+ list(APPEND ATTEST_C_SRC "${INITIAL_ATTESTATION_DIR}/attestation_key.c")
+endif()
+
if (ATTEST_INCLUDE_OPTIONAL_CLAIMS)
set_property(SOURCE ${ATTEST_C_SRC} APPEND PROPERTY COMPILE_DEFINITIONS INCLUDE_OPTIONAL_CLAIMS)
endif()
diff --git a/secure_fw/partitions/initial_attestation/attest_symmetric_key.c b/secure_fw/partitions/initial_attestation/attest_symmetric_key.c
new file mode 100644
index 0000000..39aa112
--- /dev/null
+++ b/secure_fw/partitions/initial_attestation/attest_symmetric_key.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Laurence Lundblade.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "attestation_key.h"
+#include "platform/include/tfm_plat_crypto_keys.h"
+#include "psa/crypto.h"
+
+/* Only support HMAC as MAC algorithm in COSE_Mac0 so far */
+#define SYMMETRIC_IAK_MAX_SIZE PSA_MAC_MAX_SIZE
+
+/* Symmetric IAK handle */
+static psa_key_handle_t symmetric_iak_handle = 0;
+
+static psa_status_t destroy_iak(psa_key_handle_t *iak_handle)
+{
+ psa_status_t res;
+
+ res = psa_destroy_key(*iak_handle);
+
+ *iak_handle = 0;
+ return res;
+}
+
+enum psa_attest_err_t attest_register_initial_attestation_key(void)
+{
+ uint8_t key_buf[SYMMETRIC_IAK_MAX_SIZE];
+ psa_algorithm_t key_alg;
+ psa_key_handle_t key_handle;
+ size_t key_len;
+ enum tfm_plat_err_t plat_res;
+ psa_status_t psa_res;
+ psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ if (symmetric_iak_handle) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ /* Get the symmetric initial attestation key for HMAC operation */
+ plat_res = tfm_plat_get_symmetric_iak(key_buf, sizeof(key_buf),
+ &key_len, &key_alg);
+ /* In case the buffer size was not checked, although unlikely */
+ if (sizeof(key_buf) < key_len) {
+ /*
+ * Something critical following key_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;
+ }
+
+ /*
+ * Verify if HMAC algorithm is valid.
+ * According to COSE (RFC 8152), only SHA-256, SHA-384 and SHA-512 are
+ * supported in HMAC.
+ */
+ if ((key_alg != PSA_ALG_HMAC(PSA_ALG_SHA_256)) &&
+ (key_alg != PSA_ALG_HMAC(PSA_ALG_SHA_384)) &&
+ (key_alg != PSA_ALG_HMAC(PSA_ALG_SHA_512))) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ /* Setup the key attributes */
+ psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN);
+ psa_set_key_algorithm(&key_attributes, key_alg);
+ psa_set_key_type(&key_attributes, PSA_KEY_TYPE_HMAC);
+
+ /* Register the symmetric key to Crypto service */
+ psa_res = psa_import_key(&key_attributes, key_buf, key_len, &key_handle);
+ if (psa_res != PSA_SUCCESS) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ symmetric_iak_handle = key_handle;
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+enum psa_attest_err_t attest_unregister_initial_attestation_key(void)
+{
+ if (!symmetric_iak_handle) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ destroy_iak(&symmetric_iak_handle);
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+enum psa_attest_err_t
+attest_get_signing_key_handle(psa_key_handle_t *key_handle)
+{
+ if (!symmetric_iak_handle) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ *key_handle = symmetric_iak_handle;
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
diff --git a/secure_fw/partitions/initial_attestation/attest_token.c b/secure_fw/partitions/initial_attestation/attest_token.c
index f3f8d70..3060df4 100644
--- a/secure_fw/partitions/initial_attestation/attest_token.c
+++ b/secure_fw/partitions/initial_attestation/attest_token.c
@@ -118,8 +118,7 @@
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);
+ attest_ret = attest_get_signing_key_handle(&private_key);
if (attest_ret != PSA_ATTEST_ERR_SUCCESS) {
return ATTEST_TOKEN_ERR_SIGNING_KEY;
}
diff --git a/secure_fw/partitions/initial_attestation/attestation_core.c b/secure_fw/partitions/initial_attestation/attestation_core.c
index 6b239d3..0399ceb 100644
--- a/secure_fw/partitions/initial_attestation/attestation_core.c
+++ b/secure_fw/partitions/initial_attestation/attestation_core.c
@@ -931,6 +931,19 @@
return error_mapping_to_psa_status_t(attest_err);
}
+#ifdef SYMMETRIC_INITIAL_ATTESTATION
+psa_status_t
+initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec)
+{
+ (void)in_vec;
+ (void)num_invec;
+ (void)out_vec;
+ (void)num_outvec;
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+#else /* SYMMETRIC_INITIAL_ATTESTATION */
psa_status_t
initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec,
psa_outvec *out_vec, uint32_t num_outvec)
@@ -978,3 +991,4 @@
error:
return error_mapping_to_psa_status_t(attest_err);
}
+#endif /* SYMMETRIC_INITIAL_ATTESTATION */
diff --git a/secure_fw/partitions/initial_attestation/attestation_key.c b/secure_fw/partitions/initial_attestation/attestation_key.c
index 58e690f..f0e7e99 100644
--- a/secure_fw/partitions/initial_attestation/attestation_key.c
+++ b/secure_fw/partitions/initial_attestation/attestation_key.c
@@ -128,7 +128,7 @@
}
enum psa_attest_err_t
-attest_get_initial_attestation_private_key_handle(psa_key_handle_t *handle)
+attest_get_signing_key_handle(psa_key_handle_t *handle)
{
if (attestation_key_handle == ATTEST_KEY_HANDLE_NOT_LOADED) {
return PSA_ATTEST_ERR_GENERAL;
diff --git a/secure_fw/partitions/initial_attestation/attestation_key.h b/secure_fw/partitions/initial_attestation/attestation_key.h
index cb35a94..5525479 100644
--- a/secure_fw/partitions/initial_attestation/attestation_key.h
+++ b/secure_fw/partitions/initial_attestation/attestation_key.h
@@ -8,6 +8,7 @@
#ifndef __ATTESTATION_KEY_H__
#define __ATTESTATION_KEY_H__
+#include "attestation.h"
#include "psa/initial_attestation.h"
#include "psa/crypto.h"
#include "q_useful_buf.h"
@@ -40,16 +41,19 @@
attest_unregister_initial_attestation_key();
/**
- * \brief Get a handle to the attestion private key.
+ * \brief Get the handle of the key for signing token
+ * In asymmetric key algorithm based initial attestation, it is the
+ * handle of the initial attestation private key.
+ * In symmetric key algorithm based initial attestation, it is the
+ * handle of symmetric initial attestation key.
*
- * \param[out] key_handle Key handle for private key
+ * \param[out] key_handle The handle of the key for signing token.
*
- * \retval PSA_ATTEST_ERR_SUCCESS Private key was successfully returned.
- * \retval PSA_ATTEST_ERR_GENERAL Private key could not be returned.
+ * \retval PSA_ATTEST_ERR_SUCCESS Key handle was successfully returned.
+ * \retval PSA_ATTEST_ERR_GENERAL Key handle could not be returned.
*/
-
enum psa_attest_err_t
-attest_get_initial_attestation_private_key_handle(psa_key_handle_t *key_handle);
+attest_get_signing_key_handle(psa_key_handle_t *key_handle);
/**
* \brief Get the public key derived from the initial attestation private key.