From 581182c1916df03860744d8e32941c72b2cc3fda Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 9 May 2022 10:48:53 +0800 Subject: [PATCH] feat(intel): extend attestation service to Agilex family This patch extends the functionality of FPGA Crypto Services (FCS) to support FPGA Attestation feature in Agilex device. Signed-off-by: Boon Khai Ng Signed-off-by: Sieu Mun Tang Change-Id: I3c2e29d2fa04d394e9f65d8143d7f4e57389cd02 --- plat/intel/soc/common/include/socfpga_fcs.h | 13 ++++ .../soc/common/include/socfpga_mailbox.h | 2 + .../soc/common/include/socfpga_sip_svc.h | 2 + plat/intel/soc/common/sip/socfpga_sip_fcs.c | 70 +++++++++++++++++++ plat/intel/soc/common/socfpga_sip_svc.c | 59 +++++++++++----- 5 files changed, 129 insertions(+), 17 deletions(-) diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h index 1df163971..d9b8be4bb 100644 --- a/plat/intel/soc/common/include/socfpga_fcs.h +++ b/plat/intel/soc/common/include/socfpga_fcs.h @@ -40,6 +40,14 @@ #define FCS_BIG_CNTR_VAL_MAX 495U #define FCS_SVN_CNTR_VAL_MAX 64U +/* FCS Attestation Cert Request Parameter */ + +#define FCS_ALIAS_CERT 0x01 +#define FCS_DEV_ID_SELF_SIGN_CERT 0x02 +#define FCS_DEV_ID_ENROLL_CERT 0x04 +#define FCS_ENROLL_SELF_SIGN_CERT 0x08 +#define FCS_PLAT_KEY_CERT 0x10 + /* FCS Payload Structure */ typedef struct fcs_encrypt_payload_t { @@ -100,4 +108,9 @@ int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, uint32_t *mbox_error); +int intel_fcs_create_cert_on_reload(uint32_t cert_request, + uint32_t *mbox_error); +int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, + uint32_t *dst_size, uint32_t *mbox_error); + #endif /* SOCFPGA_FCS_H */ diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index fcf5fc206..21cb1591b 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -80,6 +80,8 @@ #define MBOX_PSG_SIGMA_TEARDOWN 0xD5 /* Attestation Commands */ +#define MBOX_CREATE_CERT_ON_RELOAD 0x180 +#define MBOX_GET_ATTESTATION_CERT 0x181 #define MBOX_ATTESTATION_SUBKEY 0x182 #define MBOX_GET_MEASUREMENT 0x183 diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index e46bee701..53b949d02 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -84,6 +84,8 @@ #define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065 #define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066 #define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067 +#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068 +#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD 0xC2000069 /* ECC DBE */ #define WARM_RESET_WFI_FLAG BIT(31) diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c index 37dc77259..5ba81eebb 100644 --- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c +++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c @@ -351,3 +351,73 @@ int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, return INTEL_SIP_SMC_STATUS_OK; } + +int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, + uint32_t *dst_size, uint32_t *mbox_error) +{ + int status; + uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; + + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (cert_request < FCS_ALIAS_CERT || + cert_request > + (FCS_ALIAS_CERT | + FCS_DEV_ID_SELF_SIGN_CERT | + FCS_DEV_ID_ENROLL_CERT | + FCS_ENROLL_SELF_SIGN_CERT | + FCS_PLAT_KEY_CERT)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (!is_address_in_ddr_range(dst_addr, *dst_size)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, + (uint32_t *) &cert_request, 1U, CMD_CASUAL, + (uint32_t *) dst_addr, &ret_size); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *dst_size = ret_size * MBOX_WORD_BYTE; + flush_dcache_range(dst_addr, *dst_size); + + return INTEL_SIP_SMC_STATUS_OK; +} + +int intel_fcs_create_cert_on_reload(uint32_t cert_request, + uint32_t *mbox_error) +{ + int status; + + if (mbox_error == NULL) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + if (cert_request < FCS_ALIAS_CERT || + cert_request > + (FCS_ALIAS_CERT | + FCS_DEV_ID_SELF_SIGN_CERT | + FCS_DEV_ID_ENROLL_CERT | + FCS_ENROLL_SELF_SIGN_CERT | + FCS_PLAT_KEY_CERT)) { + return INTEL_SIP_SMC_STATUS_REJECTED; + } + + status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, + (uint32_t *) &cert_request, 1U, CMD_CASUAL, + NULL, NULL); + + if (status < 0) { + *mbox_error = -status; + return INTEL_SIP_SMC_STATUS_ERROR; + } + + return INTEL_SIP_SMC_STATUS_OK; +} diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index da75efa01..f0c2ebe49 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -63,8 +63,9 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) args[2] = buffer->size - buffer->size_written; current_buffer++; current_buffer %= FPGA_CONFIG_BUFFER_SIZE; - } else + } else { args[2] = bytes_per_block; + } buffer->size_written += args[2]; mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args, @@ -79,10 +80,12 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) static int intel_fpga_sdm_write_all(void) { - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { if (intel_fpga_sdm_write_buffer( - &fpga_config_buffers[current_buffer])) + &fpga_config_buffers[current_buffer])) { break; + } + } return 0; } @@ -174,10 +177,11 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, intel_fpga_sdm_write_all(); - if (*count > 0) + if (*count > 0) { status = INTEL_SIP_SMC_STATUS_OK; - else if (*count == 0) + } else if (*count == 0) { status = INTEL_SIP_SMC_STATUS_BUSY; + } for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { if (fpga_config_buffers[i].write_requested != 0) { @@ -186,8 +190,9 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr, } } - if (all_completed == 1) + if (all_completed == 1) { return INTEL_SIP_SMC_STATUS_OK; + } return status; } @@ -249,9 +254,11 @@ static int intel_fpga_config_start(uint32_t flag) static bool is_fpga_config_buffer_full(void) { - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) - if (!fpga_config_buffers[i].write_requested) + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + if (!fpga_config_buffers[i].write_requested) { return false; + } + } return true; } @@ -260,12 +267,15 @@ bool is_address_in_ddr_range(uint64_t addr, uint64_t size) if (!addr && !size) { return true; } - if (size > (UINT64_MAX - addr)) + if (size > (UINT64_MAX - addr)) { return false; - if (addr < BL31_LIMIT) + } + if (addr < BL31_LIMIT) { return false; - if (addr + size > DRAM_BASE + DRAM_SIZE) + } + if (addr + size > DRAM_BASE + DRAM_SIZE) { return false; + } return true; } @@ -349,8 +359,9 @@ static int is_out_of_sec_range(uint64_t reg_addr) /* Secure register access */ uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) { - if (is_out_of_sec_range(reg_addr)) + if (is_out_of_sec_range(reg_addr)) { return INTEL_SIP_SMC_STATUS_ERROR; + } *retval = mmio_read_32(reg_addr); @@ -360,8 +371,9 @@ uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val, uint32_t *retval) { - if (is_out_of_sec_range(reg_addr)) + if (is_out_of_sec_range(reg_addr)) { return INTEL_SIP_SMC_STATUS_ERROR; + } mmio_write_32(reg_addr, val); @@ -385,8 +397,9 @@ uint64_t intel_rsu_update_address; static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz) { - if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } return INTEL_SIP_SMC_STATUS_OK; } @@ -399,8 +412,9 @@ static uint32_t intel_rsu_update(uint64_t update_address) static uint32_t intel_rsu_notify(uint32_t execution_stage) { - if (mailbox_hps_stage_notify(execution_stage) < 0) + if (mailbox_hps_stage_notify(execution_stage) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } return INTEL_SIP_SMC_STATUS_OK; } @@ -408,8 +422,9 @@ static uint32_t intel_rsu_notify(uint32_t execution_stage) static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, uint32_t *ret_stat) { - if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) { return INTEL_SIP_SMC_RSU_ERROR; + } *ret_stat = respbuf[8]; return INTEL_SIP_SMC_STATUS_OK; @@ -495,8 +510,9 @@ static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, *len_in_resp = 0; *mbox_status = GENERIC_RESPONSE_ERROR; - if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) + if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) { return INTEL_SIP_SMC_STATUS_REJECTED; + } int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent, response, &resp_len); @@ -810,6 +826,15 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t *) &x4, &mbox_error); SMC_RET4(handle, status, mbox_error, x3, x4); + case INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT: + status = intel_fcs_get_attestation_cert(x1, x2, + (uint32_t *) &x3, &mbox_error); + SMC_RET4(handle, status, mbox_error, x2, x3); + + case INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD: + status = intel_fcs_create_cert_on_reload(x1, &mbox_error); + SMC_RET2(handle, status, mbox_error); + case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384: status = intel_fcs_get_rom_patch_sha384(x1, &retval64, &mbox_error); -- 2.39.5