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
  *