fix(intel): update encryption and decryption command logic
This change is to re-align HPS cryption logic with
underlying Secure Device Manager's (SDM) mailbox API.
Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Change-Id: I8fc90982d3cddceaf401c1a112ff8e20861bf4c5
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index d3b7141..a3efd80 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -17,17 +17,30 @@
#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U)
-#define FCS_CRYPTION_DATA_0 0x10100
+#define FCS_MODE_DECRYPT 0x0
+#define FCS_MODE_ENCRYPT 0x1
+#define FCS_ENCRYPTION_DATA_0 0x10100
+#define FCS_DECRYPTION_DATA_0 0x10102
+#define FCS_OWNER_ID_OFFSET 0xC
/* FCS Payload Structure */
-typedef struct fcs_crypt_payload_t {
+typedef struct fcs_encrypt_payload_t {
uint32_t first_word;
uint32_t src_addr;
uint32_t src_size;
uint32_t dst_addr;
uint32_t dst_size;
-} fcs_crypt_payload;
+} fcs_encrypt_payload;
+
+typedef struct fcs_decrypt_payload_t {
+ uint32_t first_word;
+ uint32_t owner_id[2];
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_decrypt_payload;
/* Functions Definitions */
@@ -36,9 +49,13 @@
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t *send_id);
uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id);
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size,
+ uint32_t *send_id);
+
+uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size,
+ uint32_t *send_id);
uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error);
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index ca6f1f8..fcd5450 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -71,7 +71,8 @@
/* Mailbox Command */
#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D
-/* SiP Definitions */
+/* FPGA Crypto Services */
+#define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B
/* ECC DBE */
#define WARM_RESET_WFI_FLAG BIT(31)
@@ -103,7 +104,7 @@
};
/* Function Definitions */
-
+bool is_size_4_bytes_aligned(uint32_t size);
bool is_address_in_ddr_range(uint64_t addr, uint64_t size);
/* ECC DBE */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index 85551a4..a174e5f 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -11,7 +11,7 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
-static bool is_size_4_bytes_aligned(uint32_t size)
+bool is_size_4_bytes_aligned(uint32_t size)
{
if ((size % MBOX_WORD_BYTE) != 0U) {
return false;
@@ -95,37 +95,70 @@
return INTEL_SIP_SMC_STATUS_OK;
}
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id)
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
{
int status;
- uint32_t cmd;
+ uint32_t load_size;
- fcs_crypt_payload payload = {
- FCS_CRYPTION_DATA_0,
+ fcs_encrypt_payload payload = {
+ FCS_ENCRYPTION_DATA_0,
src_addr,
src_size,
dst_addr,
dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
if (!is_address_in_ddr_range(src_addr, src_size) ||
!is_address_in_ddr_range(dst_addr, dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
- if (!is_size_4_bytes_aligned(sizeof(fcs_crypt_payload))) {
+ if (!is_size_4_bytes_aligned(src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
- if (mode != 0U) {
- cmd = MBOX_FCS_ENCRYPT_REQ;
- } else {
- cmd = MBOX_FCS_DECRYPT_REQ;
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
+ (uint32_t *) &payload, load_size,
+ CMD_INDIRECT);
+ inv_dcache_range(dst_addr, dst_size);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
+{
+ int status;
+ uint32_t load_size;
+ uintptr_t id_offset;
+
+ id_offset = src_addr + FCS_OWNER_ID_OFFSET;
+ fcs_decrypt_payload payload = {
+ FCS_DECRYPTION_DATA_0,
+ {mmio_read_32(id_offset),
+ mmio_read_32(id_offset + MBOX_WORD_BYTE)},
+ src_addr,
+ src_size,
+ dst_addr,
+ dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
}
- status = mailbox_send_cmd_async(send_id, cmd, (uint32_t *) &payload,
- sizeof(fcs_crypt_payload) / MBOX_WORD_BYTE,
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
+ (uint32_t *) &payload, load_size,
CMD_INDIRECT);
inv_dcache_range(dst_addr, dst_size);
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 79444cf..a80208f 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -711,6 +711,19 @@
status = intel_smc_get_usercode(&retval);
SMC_RET2(handle, status, retval);
+ case INTEL_SIP_SMC_FCS_CRYPTION:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+
+ if (x1 == FCS_MODE_DECRYPT) {
+ status = intel_fcs_decryption(x2, x3, x4, x5, &send_id);
+ } else if (x1 == FCS_MODE_ENCRYPT) {
+ status = intel_fcs_encryption(x2, x3, x4, x5, &send_id);
+ } else {
+ status = INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ SMC_RET3(handle, status, x4, x5);
+
case INTEL_SIP_SMC_HPS_SET_BRIDGES:
status = intel_hps_set_bridges(x1, x2);
SMC_RET1(handle, status);