Platform: Copy crypto keys to eMRAM on Musca-S1

Copies the keys generated in the CC312 provisioning
process from the Musca-S1's volatile "OTP" area to the
on-board, non-volatile eMRAM. Adds a platform-dependent
define of the used flash address based on flash_layout.h.

Signed-off-by: Balint Matyi <Balint.Matyi@arm.com>
Change-Id: I220517c6d3aa4c4339a62825f13060f27246c6dd
diff --git a/platform/ext/common/cc312/cc312_provisioning.c b/platform/ext/common/cc312/cc312_provisioning.c
index ae01e89..4003299 100644
--- a/platform/ext/common/cc312/cc312_provisioning.c
+++ b/platform/ext/common/cc312/cc312_provisioning.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -121,6 +121,126 @@
     return rc;
 }
 
+/*
+ * All Musca-S1 platform-dependent defines (DX_PLAT_MUSCA_S1) are due to the
+ * fact that the S1 board's OTP is just an ordinary register which is volatile.
+ * The MRAM is used instead, and this is what the changes reflect.
+ */
+#ifdef DX_PLAT_MUSCA_S1
+
+#define HAL_WRITE_MRAM_UINT32(val, regOffset)                      \
+        (*((volatile uint32_t *)(DX_MRAM_CC + ((regOffset) *       \
+        sizeof(uint32_t)))) = (val))
+
+static void cc312_otp_copy_to_mram(const uint32_t offs, size_t size_in_words)
+{
+    uint32_t i = 0;
+    uint32_t temp = 0;
+
+    for(i = 0; i < size_in_words; i++) {
+        CC_PROD_OTP_READ(temp, offs + i);
+        HAL_WRITE_MRAM_UINT32(temp, offs + i);
+    }
+}
+
+static void cc312_otp_copy_attestation_to_mram(void)
+{
+    cc312_otp_copy_to_mram(CC_OTP_ATTESTATION_KEY_OFFSET,
+                           CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS);
+
+    cc312_otp_copy_to_mram(CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET, 1);
+}
+
+static int32_t cc312_otp_copy_dm_content_to_mram(CCDmpuData_t *pDmpuData)
+{
+    uint32_t hbkSizeInWords;
+    uint32_t hbkOtpWordOffset;
+    uint32_t swVerOtpWordOffset;
+    uint32_t swVerSizeInWords;
+    uint32_t icvWord;
+
+    if (pDmpuData == NULL) {
+        return -1;
+    }
+
+    CC_PROD_OTP_READ(icvWord, CC_OTP_MANUFACTURE_FLAG_OFFSET);
+
+    switch (pDmpuData->hbkType) {
+    case DMPU_HBK_TYPE_HBK1:
+            if (!IS_HBK0_USED(icvWord)) {
+                return -1;
+            }
+            hbkSizeInWords = CC_OTP_HBK1_SIZE_IN_WORDS;
+            hbkOtpWordOffset = CC_OTP_HBK1_OFFSET;
+            swVerOtpWordOffset = CC_OTP_HBK1_MIN_VERSION_OFFSET;
+            swVerSizeInWords = CC_OTP_HBK1_MIN_VERSION_SIZE_IN_WORDS;
+            break;
+    case DMPU_HBK_TYPE_HBK:
+            if (IS_HBK0_USED(icvWord)) {
+                return -1;
+            }
+            hbkSizeInWords = CC_OTP_HBK_SIZE_IN_WORDS;
+            hbkOtpWordOffset = CC_OTP_HBK_OFFSET;
+            swVerOtpWordOffset = CC_OTP_HBK_MIN_VERSION_OFFSET;
+            swVerSizeInWords = CC_OTP_HBK_MIN_VERSION_SIZE_IN_WORDS;
+            break;
+    default:
+            return -1;
+    }
+
+
+    cc312_otp_copy_to_mram(CC_OTP_OEM_FLAG_OFFSET, 1);
+
+    cc312_otp_copy_to_mram(hbkOtpWordOffset, hbkSizeInWords);
+
+    cc312_otp_copy_to_mram(CC_OTP_DCU_OFFSET, CC_OTP_DCU_SIZE_IN_WORDS);
+
+    cc312_otp_copy_to_mram(swVerOtpWordOffset, swVerSizeInWords);
+
+    if (pDmpuData->kcpDataType != ASSET_NO_KEY) {
+        cc312_otp_copy_to_mram(CC_OTP_KCP_OFFSET, CC_OTP_KCP_SIZE_IN_WORDS);
+    }
+    if (pDmpuData->kceDataType != ASSET_NO_KEY) {
+        cc312_otp_copy_to_mram(CC_OTP_KCE_OFFSET, CC_OTP_KCE_SIZE_IN_WORDS);
+    }
+
+    return 0;
+}
+
+static int32_t cc312_otp_copy_cm_content_to_mram(CCCmpuData_t *pCmpuData)
+{
+    if (pCmpuData == NULL) {
+        return -1;
+    }
+
+    cc312_otp_copy_to_mram(CC_OTP_MANUFACTURE_FLAG_OFFSET, 1);
+
+    cc312_otp_copy_to_mram(CC_OTP_HUK_OFFSET, CC_OTP_HUK_SIZE_IN_WORDS);
+
+    if (pCmpuData->uniqueDataType == CMPU_UNIQUE_IS_HBK0) {
+        cc312_otp_copy_to_mram(CC_OTP_HBK0_OFFSET, CC_OTP_HBK0_SIZE_IN_WORDS);
+
+        cc312_otp_copy_to_mram(CC_OTP_DCU_OFFSET, CC_OTP_DCU_SIZE_IN_WORDS);
+
+        cc312_otp_copy_to_mram(CC_OTP_HBK0_MIN_VERSION_OFFSET,
+        CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS);
+    }
+    if (pCmpuData->kpicvDataType  != ASSET_NO_KEY) {
+        cc312_otp_copy_to_mram(CC_OTP_KPICV_OFFSET,
+                               CC_OTP_KPICV_SIZE_IN_WORDS);
+    }
+    if (pCmpuData->kceicvDataType  != ASSET_NO_KEY) {
+        cc312_otp_copy_to_mram(CC_OTP_KCEICV_OFFSET,
+                               CC_OTP_KCEICV_SIZE_IN_WORDS);
+    }
+    cc312_otp_copy_to_mram(CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET, 1);
+
+    return 0;
+}
+#endif /* DX_PLAT_MUSCA_S1 */
+
+
+
 static int cc312_program_attestation_private_key(
                                     mbedtls_ecp_group_id curve_type)
 {
@@ -159,10 +279,15 @@
     CC_PROD_OTP_WRITE_VERIFY_WORD(CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET,
                                   zero_count,
                                   error);
+
     if (error != CC_OK) {
         return -1;
     }
 
+#ifdef DX_PLAT_MUSCA_S1
+    cc312_otp_copy_attestation_to_mram();
+#endif
+
     return 0;
 }
 
@@ -195,6 +320,14 @@
     rc = CCProd_Cmpu(DX_BASE_CC, &cmpuData, (unsigned long)pWorkspaceBuf,
                      CMPU_WORKSPACE_MINIMUM_SIZE);
 
+#ifdef DX_PLAT_MUSCA_S1
+    if (rc) {
+        return rc;
+    }
+
+    rc = cc312_otp_copy_cm_content_to_mram(&cmpuData);
+#endif
+
     return rc;
 }
 
@@ -225,6 +358,15 @@
 
     rc = CCProd_Dmpu(DX_BASE_CC, &dmpuData, (unsigned long)pWorkspaceBuf,
                      DMPU_WORKSPACE_MINIMUM_SIZE);
+
+#ifdef DX_PLAT_MUSCA_S1
+    if (rc) {
+        return rc;
+    }
+
+    rc = cc312_otp_copy_dm_content_to_mram(&dmpuData);
+#endif
+
     return rc;
 }
 
diff --git a/platform/ext/musca_s1.cmake b/platform/ext/musca_s1.cmake
index 7d42196..c5c476d 100644
--- a/platform/ext/musca_s1.cmake
+++ b/platform/ext/musca_s1.cmake
@@ -190,6 +190,7 @@
     embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE)
 endif()
 
+#The CC312 is disabled by default
 if (NOT DEFINED CRYPTO_HW_ACCELERATOR)
     set (CRYPTO_HW_ACCELERATOR OFF)
 endif()
diff --git a/platform/ext/target/musca_s1/partition/flash_layout.h b/platform/ext/target/musca_s1/partition/flash_layout.h
index 8ef450e..425ebe7 100644
--- a/platform/ext/target/musca_s1/partition/flash_layout.h
+++ b/platform/ext/target/musca_s1/partition/flash_layout.h
@@ -40,7 +40,9 @@
  * 0x0A1E_0000 Secure Storage Area (20 KB)
  * 0x0A1E_5000 Internal Trusted Storage Area (16 KB)
  * 0x0A1E_9000 NV counters area (4 KB)
- * 0x0A1E_A000 TF_M key area (256 bytes)
+ * 0x0A1E_A000 TF_M key area (256 bytes) This area is referred to in
+ *             /lib/ext/cryptocell-312-runtime/shared/hw/include/musca_s1/  \
+ *             dx_reg_base_host.h Do not change one without changing the other.
  * 0x0A1E_A100 Unused
  *
  * Flash layout on Musca-S1 without BL2: