Platform: Enable CC312 on Musca-S1

Adds support for turning on CC312 with compile switches.
Adds a file with dummy implementations of crypto functions
normally done by utilizing CC312.

Signed-off-by: Balint Matyi <Balint.Matyi@arm.com>
Change-Id: Iaf094f2606ead826e90d8907ec10d77665595539
diff --git a/platform/ext/musca_s1.cmake b/platform/ext/musca_s1.cmake
index bed9c22..7d42196 100644
--- a/platform/ext/musca_s1.cmake
+++ b/platform/ext/musca_s1.cmake
@@ -150,7 +150,7 @@
 elseif(BUILD_TARGET_HARDWARE_KEYS)
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/tfm_initial_attestation_key_material.c")
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/tfm_rotpk.c")
-  list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/crypto_keys.c")
+  list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_s1/dummy_crypto_keys.c")
 endif()
 
 if (NOT DEFINED BUILD_TARGET_NV_COUNTERS)
@@ -189,3 +189,55 @@
     embedded_include_directories(PATH "${PLATFORM_DIR}/target/musca_s1/CMSIS_Driver" ABSOLUTE)
     embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE)
 endif()
+
+if (NOT DEFINED CRYPTO_HW_ACCELERATOR)
+    set (CRYPTO_HW_ACCELERATOR OFF)
+endif()
+
+if (NOT DEFINED CRYPTO_HW_ACCELERATOR_OTP_STATE)
+    set (CRYPTO_HW_ACCELERATOR_OTP_STATE "DISABLED")
+endif()
+
+if (CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "PROVISIONING")
+    set(CRYPTO_HW_ACCELERATOR OFF)
+    set(CRYPTO_HW_ACCELERATOR_CMAKE_BUILD "${PLATFORM_DIR}/common/cc312/BuildCC312.cmake" PARENT_SCOPE)
+    set(CRYPTO_HW_ACCELERATOR_CMAKE_LINK "${PLATFORM_DIR}/common/cc312/LinkCC312Provisioning.cmake" PARENT_SCOPE)
+
+    get_filename_component(CC312_SOURCE_DIR "${PLATFORM_DIR}/../../lib/ext/cryptocell-312-runtime" ABSOLUTE)
+    add_definitions("-DCRYPTO_HW_ACCELERATOR_OTP_PROVISIONING")
+
+    add_definitions("-DCC_IOT")
+    string(APPEND CC312_INC_DIR " ${CC312_SOURCE_DIR}/shared/hw/include/musca_s1")
+    embedded_include_directories(PATH "${CC312_SOURCE_DIR}/shared/hw/include/musca_s1" ABSOLUTE)
+    embedded_include_directories(PATH "${CMAKE_CURRENT_BINARY_DIR}/services/crypto/cryptocell/install/include" ABSOLUTE)
+    embedded_include_directories(PATH "${PLATFORM_DIR}/common/cc312/" ABSOLUTE)
+elseif (CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "ENABLED")
+    set(CRYPTO_HW_ACCELERATOR ON)
+
+    add_definitions("-DCRYPTO_HW_ACCELERATOR_OTP_ENABLED")
+elseif(CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "DISABLED")
+else()
+    message(FATAL_ERROR "CRYPTO_HW_ACCELERATOR_OTP_STATE invalid. expected (DISABLED|PROVISIONING|ENABLED)")
+endif()
+
+#Enable CryptoCell-312 HW accelerator
+if (CRYPTO_HW_ACCELERATOR)
+    set(CRYPTO_HW_ACCELERATOR_CMAKE_BUILD "${PLATFORM_DIR}/common/cc312/BuildCC312.cmake" PARENT_SCOPE)
+    set(CRYPTO_HW_ACCELERATOR_CMAKE_LINK "${PLATFORM_DIR}/common/cc312/LinkCC312.cmake" PARENT_SCOPE)
+
+    get_filename_component(CC312_SOURCE_DIR "${PLATFORM_DIR}/../../lib/ext/cryptocell-312-runtime" ABSOLUTE)
+    add_definitions("-DCRYPTO_HW_ACCELERATOR")
+    add_definitions("-DCRYPTO_HW_ACCELERATOR_CC312")
+
+    add_definitions("-DCC_IOT")
+    #The CC312 uses GNU make as a build system so does not use the cmake flag
+    #system. As such any flags that need to be set for both CC312 and TF-M
+    #require setting multiple times.
+    string(APPEND CC312_INC_DIR " ${CC312_SOURCE_DIR}/shared/hw/include/musca_s1")
+    embedded_include_directories(PATH "${CC312_SOURCE_DIR}/shared/hw/include/musca_s1" ABSOLUTE)
+    embedded_include_directories(PATH "${CMAKE_CURRENT_BINARY_DIR}/services/crypto/cryptocell/install/include" ABSOLUTE)
+    embedded_include_directories(PATH "${PLATFORM_DIR}/common/cc312/" ABSOLUTE)
+
+    #Compiling this file requires to disable warning: -Wunused-local-typedefs
+    set_source_files_properties("${PLATFORM_DIR}/target/musca_s1/dummy_crypto_keys.c" PROPERTIES COMPILE_FLAGS -Wno-unused-local-typedefs)
+endif()
diff --git a/platform/ext/target/musca_s1/dummy_crypto_keys.c b/platform/ext/target/musca_s1/dummy_crypto_keys.c
new file mode 100644
index 0000000..19da4fd
--- /dev/null
+++ b/platform/ext/target/musca_s1/dummy_crypto_keys.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2017-2020 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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
+ * pair and keep the private key is secret.
+ */
+
+#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[];
+extern const uint32_t initial_attestation_private_key_size;
+
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
+#ifndef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
+/**
+ * \brief Copy the key to the destination buffer
+ *
+ * \param[out]  p_dst  Pointer to buffer where to store the key
+ * \param[in]   p_src  Pointer to the key
+ * \param[in]   size   Length of the key
+ */
+static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size)
+{
+    uint32_t i;
+
+    for (i = size; i > 0; i--) {
+        *p_dst = *p_src;
+        p_src++;
+        p_dst++;
+    }
+}
+#endif /* !CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
+
+enum tfm_plat_err_t tfm_plat_get_huk_derived_key(const uint8_t *label,
+                                                 size_t label_size,
+                                                 const uint8_t *context,
+                                                 size_t context_size,
+                                                 uint8_t *key,
+                                                 size_t key_size)
+{
+    (void)label;
+    (void)label_size;
+    (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;
+    }
+
+    copy_key(key, sample_tfm_key, key_size);
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t          *key_buf,
+                                uint32_t          size,
+                                struct ecc_key_t *ecc_key,
+                                psa_ecc_curve_t  *curve_type)
+{
+    uint32_t key_size = initial_attestation_private_key_size;
+    int rc;
+
+    if (size < key_size) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    /* Set the EC curve type which the key belongs to */
+    *curve_type = initial_attestation_curve_type;
+
+    /* Copy the private key to the buffer, it MUST be present */
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
+    rc = crypto_hw_accelerator_get_attestation_private_key(key_buf, &size);
+    key_size = size;
+#else
+    copy_key(key_buf, initial_attestation_private_key, key_size);
+    rc = 0;
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
+
+    if (rc) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    ecc_key->priv_key = key_buf;
+    ecc_key->priv_key_size = key_size;
+
+    ecc_key->pubx_key = NULL;
+    ecc_key->pubx_key_size = 0;
+    ecc_key->puby_key = NULL;
+    ecc_key->puby_key_size = 0;
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+                        uint8_t *rotpk_hash,
+                        uint32_t *rotpk_hash_size)
+{
+    int rc = 0;
+
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_ENABLED
+    rc = crypto_hw_accelerator_get_rotpk_hash(image_id, rotpk_hash,
+                                              rotpk_hash_size);
+#else
+    if (*rotpk_hash_size < ROTPK_HASH_LEN) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    if (image_id >= rotpk_key_cnt) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    *rotpk_hash_size = ROTPK_HASH_LEN;
+
+    copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_ENABLED */
+
+    if (rc) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+#endif /* BL2 */