Platform: Use CryptoCell HUK to derive a key as SST key
HUK is unique per chip, this guarantees that SST key is also unique
per chip. HUK is generated by TRNG and stored in OTP. It is hidden
to the host CPU when chip is in secure enabled state.
Change-Id: I9ee7aeec2c6c3c69cb01328ec04067622ebba3ef
Signed-off-by: Xu Yong <yong.xu@arm.com>
diff --git a/platform/ext/common/cc312/cc312.c b/platform/ext/common/cc312/cc312.c
index a5c417d..c4f9065 100644
--- a/platform/ext/common/cc312/cc312.c
+++ b/platform/ext/common/cc312/cc312.c
@@ -15,6 +15,10 @@
#include "mbedtls/entropy.h"
#include "mbedtls_cc_mng_int.h"
#include "arm_cmse.h"
+#include "mbedtls_cc_util_key_derivation.h"
+#include "tfm_attest_hal.h"
+
+#define CC312_NULL_CONTEXT "NO SALT!"
CCRndContext_t* CC312_pRndCtx = NULL;
CCRndWorkBuff_t* CC312_pRndWorkBuff = NULL;
@@ -102,3 +106,26 @@
{
return mbedtls_mng_lcsGet(lcs);
}
+
+int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
+ size_t label_size,
+ const uint8_t *context,
+ size_t context_size,
+ uint8_t *key,
+ size_t key_size)
+{
+
+ if (context == NULL || context_size == 0) {
+ /* The CC312 requires the context to not be null, so a default
+ * is given.
+ */
+ context = (const uint8_t *)CC312_NULL_CONTEXT;
+ context_size = sizeof(CC312_NULL_CONTEXT);
+ }
+
+ return mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY, NULL,
+ label, label_size,
+ context, context_size,
+ key, key_size);
+
+}
diff --git a/platform/ext/common/cc312/crypto_hw.h b/platform/ext/common/cc312/crypto_hw.h
index 2d577cd..5951e29 100644
--- a/platform/ext/common/cc312/crypto_hw.h
+++ b/platform/ext/common/cc312/crypto_hw.h
@@ -9,6 +9,7 @@
#define __CRYPTO_HW_H__
#include <stdint.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
@@ -35,6 +36,26 @@
*/
int crypto_hw_accelerator_finish(void);
+/*
+ * \brief This function performs key derivation
+ *
+ * \param[in] label Label for KDF
+ * \param[in] label_size Size of the label
+ * \param[in] context Context for KDF
+ * \param[in] context_size Size of the context
+ * \param[out] key Buffer to output the derived key material
+ * \param[in] key_size Requested size of the derived key material and
+ * minimum size of the key buffer
+ *
+ * \return 0 on success, non-zero otherwise
+ */
+int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
+ size_t label_size,
+ const uint8_t *context,
+ size_t context_size,
+ uint8_t *key,
+ size_t key_size);
+
/**
* \brief Write the crypto keys to One-Time-Programmable memory
*
diff --git a/platform/ext/target/musca_b1/dummy_crypto_keys.c b/platform/ext/target/musca_b1/dummy_crypto_keys.c
index 4281b38..0cc431f 100644
--- a/platform/ext/target/musca_b1/dummy_crypto_keys.c
+++ b/platform/ext/target/musca_b1/dummy_crypto_keys.c
@@ -15,9 +15,15 @@
*/
#include "platform/include/tfm_plat_crypto_keys.h"
+#include "platform/include/tfm_attest_hal.h"
#include <stddef.h>
#include "psa/crypto_types.h"
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
+#include "crypto_hw.h"
+#include "mbedtls_cc_mng_int.h"
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
+
/* FIXME: Functions in this file should be implemented by platform vendor. For
* the security of the storage system, it is critical to use a hardware unique
* key. For the security of the attestation, it is critical to use a unique key
@@ -26,9 +32,11 @@
#define TFM_KEY_LEN_BYTES 16
+#ifndef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
static const uint8_t sample_tfm_key[TFM_KEY_LEN_BYTES] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+#endif /* !CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
extern const psa_ecc_curve_t initial_attestation_curve_type;
extern const uint8_t initial_attestation_private_key[];
@@ -67,12 +75,31 @@
(void)context;
(void)context_size;
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
+ int rc;
+ uint32_t lcs;
+
+ rc = crypto_hw_accelerator_get_lcs(&lcs);
+ if (rc) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (lcs != CC_MNG_LCS_SEC_ENABLED) {
+ return TFM_PLAT_ERR_UNSUPPORTED;
+ }
+
+ rc = crypto_hw_accelerator_huk_derive_key(label, label_size, context,
+ context_size, key, key_size);
+ if (rc) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+#else
if (key_size > TFM_KEY_LEN_BYTES) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}
- /* FIXME: Do key derivation */
copy_key(key, sample_tfm_key, key_size);
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
return TFM_PLAT_ERR_SUCCESS;
}
diff --git a/secure_fw/services/crypto/crypto_generator.c b/secure_fw/services/crypto/crypto_generator.c
index af9b014..850469d 100644
--- a/secure_fw/services/crypto/crypto_generator.c
+++ b/secure_fw/services/crypto/crypto_generator.c
@@ -24,6 +24,10 @@
#include "platform/include/tfm_plat_crypto_keys.h"
+#ifdef TFM_PARTITION_TEST_SST
+#include "psa_manifest/pid.h"
+#endif /* TFM_PARTITION_TEST_SST */
+
/**
* \brief Perform a key derivation operation from the hardware unique key (HUK).
*
@@ -74,6 +78,16 @@
if (status != PSA_SUCCESS) {
return status;
}
+
+#ifdef TFM_PARTITION_TEST_SST
+ /* The SST tests run some operations under the wrong partition ID - this
+ * causes the key derivation to change.
+ */
+ if (partition_id == TFM_SP_SST_TEST) {
+ partition_id = TFM_SP_STORAGE;
+ }
+#endif /* TFM_PARTITION_TEST_SST */
+
partition_label = mbedtls_calloc(1, sizeof(partition_id) + label_length);
if (partition_label == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;