RSS: Setup S/NS decryption keys in KMU

Change-Id: I887ed7d132297b9db481233fa1101575c35bfe6b
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/platform/ext/target/arm/rss/common/bl1/bl1_1_shared_symbols.txt b/platform/ext/target/arm/rss/common/bl1/bl1_1_shared_symbols.txt
index 97dd2b6..f382ff4 100644
--- a/platform/ext/target/arm/rss/common/bl1/bl1_1_shared_symbols.txt
+++ b/platform/ext/target/arm/rss/common/bl1/bl1_1_shared_symbols.txt
@@ -23,6 +23,8 @@
 kmu_set_key_locked
 kmu_set_slot_invalid
 kmu_random_delay
+kmu_set_key_export_config
+kmu_set_key_export_config_locked
 pq_crypto_verify
 pq_crypto_get_pub_key_hash
 rss_derive_cpak_seed
diff --git a/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1_2.c b/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1_2.c
index 4d27720..2ac55ab 100644
--- a/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1_2.c
+++ b/platform/ext/target/arm/rss/common/bl1/boot_hal_bl1_2.c
@@ -34,6 +34,7 @@
 #include "rss_kmu_slot_ids.h"
 #include "mpu_armv8m_drv.h"
 #include "cmsis.h"
+#include "dpa_hardened_word_copy.h"
 
 struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
 
@@ -233,12 +234,83 @@
     return 0;
 }
 
+static int setup_kmu_slot_from_otp(enum rss_kmu_slot_id_t slot,
+                                   enum tfm_otp_element_id_t otp_id,
+                                   struct kmu_key_export_config_t *export_config)
+{
+    int rc;
+    enum kmu_error_t kmu_err;
+    volatile uint32_t *kmu_ptr;
+    size_t kmu_slot_size;
+    enum tfm_plat_err_t plat_err;
+    uint32_t key[8];
+
+    kmu_err = kmu_get_key_buffer_ptr(&KMU_DEV_S, slot, &kmu_ptr, &kmu_slot_size);
+    if (kmu_err != KMU_ERROR_NONE) {
+        return -1;
+    }
+
+    plat_err = tfm_plat_otp_read(otp_id, sizeof(key), (uint8_t*)key);
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        rc = -1;
+        goto out;
+    }
+
+    dpa_hardened_word_copy(kmu_ptr, key, kmu_slot_size / sizeof(uint32_t));
+
+    kmu_err = kmu_set_key_locked(&KMU_DEV_S, slot);
+    if (kmu_err != KMU_ERROR_NONE) {
+        rc = -1;
+        goto out;
+    }
+
+    kmu_err = kmu_set_key_export_config(&KMU_DEV_S, slot, export_config);
+    if (kmu_err != KMU_ERROR_NONE) {
+        rc = -1;
+        goto out;
+    }
+
+    kmu_err = kmu_set_key_export_config_locked(&KMU_DEV_S, slot);
+    if (kmu_err != KMU_ERROR_NONE) {
+        rc = -1;
+        goto out;
+    }
+
+    rc = 0;
+out:
+    /* TODO replace with side-channel resistant erase */
+    memset(key, 0, sizeof(key));
+
+    return rc;
+}
+
 int boot_platform_post_load(uint32_t image_id)
 {
     int rc = 0;
     uint32_t vhuk_seed[8];
     size_t vhuk_seed_len;
 
+    const struct kmu_key_export_config_t sic_dr0_export_config = {
+        SIC_BASE_S + 0x120, /* CC3XX DR0_KEY_WORD0 register */
+        0, /* No delay */
+        0x01, /* Increment by 4 bytes with each write */
+        KMU_DESTINATION_PORT_WIDTH_32_BITS, /* Write 32 bits with each write */
+        KMU_DESTINATION_PORT_WIDTH_8_WRITES, /* Perform 8 writes (total 256 bits) */
+        false, /* Don't refresh the masking */
+        false, /* Don't disable the masking */
+    };
+
+    const struct kmu_key_export_config_t sic_dr1_export_config = {
+        SIC_BASE_S + 0x220, /* SIC DR1_KEY_WORD0 register */
+        0, /* No delay */
+        0x01, /* Increment by 4 bytes with each write */
+        KMU_DESTINATION_PORT_WIDTH_32_BITS, /* Write 32 bits with each write */
+        KMU_DESTINATION_PORT_WIDTH_8_WRITES, /* Perform 8 writes (total 256 bits) */
+        false, /* Don't refresh the masking */
+        false, /* Don't disable the masking */
+    };
+
+
     rc = rss_derive_vhuk_seed(vhuk_seed, sizeof(vhuk_seed), &vhuk_seed_len);
     if (rc) {
         return rc;
@@ -255,6 +327,20 @@
     }
 
     rc = rss_derive_dak_seed(RSS_KMU_SLOT_DAK_SEED);
+    if (rc) {
+        return rc;
+    }
+
+    rc = setup_kmu_slot_from_otp(RSS_KMU_SLOT_SECURE_ENCRYPTION_KEY,
+                                 PLAT_OTP_ID_KEY_SECURE_ENCRYPTION,
+                                 &sic_dr0_export_config);
+    if (rc) {
+        return rc;
+    }
+
+    rc = setup_kmu_slot_from_otp(RSS_KMU_SLOT_NON_SECURE_ENCRYPTION_KEY,
+                                 PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION,
+                                 &sic_dr1_export_config);
 
     return rc;
 }
diff --git a/platform/ext/target/arm/rss/common/rss_kmu_slot_ids.h b/platform/ext/target/arm/rss/common/rss_kmu_slot_ids.h
index 4e1d4e4..ed05cc7 100644
--- a/platform/ext/target/arm/rss/common/rss_kmu_slot_ids.h
+++ b/platform/ext/target/arm/rss/common/rss_kmu_slot_ids.h
@@ -37,6 +37,8 @@
      */
     RSS_KMU_SLOT_DM_PROVISIONING_KEY,
     _RSS_KMU_AEAD_RESERVED_SLOT_DM_PROVISIONING_KEY,
+    RSS_KMU_SLOT_SECURE_ENCRYPTION_KEY,
+    RSS_KMU_SLOT_NON_SECURE_ENCRYPTION_KEY,
 };
 
 #ifdef __cplusplus