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;
 }