firmware: stratix10-svc: add new FCS commands
Extending the fpga svc driver to support 6 new FPGA Crypto Service(FCS) commands. We are adding FCS SDOS data encryption and decryption, random number generator, image validation request, reading the data provision and certificate validation. Signed-off-by: Ang Tien Sung <tien.sung.ang@intel.com> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org> Link: https://lore.kernel.org/r/20220711223140.2307945-3-dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
79b936254a
Коммит
4a4709d470
|
@ -99,8 +99,10 @@ struct stratix10_svc_data_mem {
|
|||
/**
|
||||
* struct stratix10_svc_data - service data structure
|
||||
* @chan: service channel
|
||||
* @paddr: playload physical address
|
||||
* @size: playload size
|
||||
* @paddr: physical address of to be processed payload
|
||||
* @size: to be processed playload size
|
||||
* @paddr_output: physical address of processed payload
|
||||
* @size_output: processed payload size
|
||||
* @command: service command requested by client
|
||||
* @flag: configuration type (full or partial)
|
||||
* @arg: args to be passed via registers and not physically mapped buffers
|
||||
|
@ -111,6 +113,8 @@ struct stratix10_svc_data {
|
|||
struct stratix10_svc_chan *chan;
|
||||
phys_addr_t paddr;
|
||||
size_t size;
|
||||
phys_addr_t paddr_output;
|
||||
size_t size_output;
|
||||
u32 command;
|
||||
u32 flag;
|
||||
u64 arg[3];
|
||||
|
@ -320,7 +324,10 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data,
|
|||
case COMMAND_RECONFIG:
|
||||
case COMMAND_RSU_UPDATE:
|
||||
case COMMAND_RSU_NOTIFY:
|
||||
case COMMAND_POLL_SERVICE_STATUS:
|
||||
case COMMAND_FCS_REQUEST_SERVICE:
|
||||
case COMMAND_FCS_SEND_CERTIFICATE:
|
||||
case COMMAND_FCS_DATA_ENCRYPTION:
|
||||
case COMMAND_FCS_DATA_DECRYPTION:
|
||||
cb_data->status = BIT(SVC_STATUS_OK);
|
||||
break;
|
||||
case COMMAND_RECONFIG_DATA_SUBMIT:
|
||||
|
@ -340,6 +347,14 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data,
|
|||
cb_data->kaddr1 = &res.a1;
|
||||
cb_data->kaddr2 = &res.a2;
|
||||
break;
|
||||
case COMMAND_FCS_RANDOM_NUMBER_GEN:
|
||||
case COMMAND_FCS_GET_PROVISION_DATA:
|
||||
case COMMAND_POLL_SERVICE_STATUS:
|
||||
cb_data->status = BIT(SVC_STATUS_OK);
|
||||
cb_data->kaddr1 = &res.a1;
|
||||
cb_data->kaddr2 = svc_pa_to_va(res.a2);
|
||||
cb_data->kaddr3 = &res.a3;
|
||||
break;
|
||||
default:
|
||||
pr_warn("it shouldn't happen\n");
|
||||
break;
|
||||
|
@ -366,7 +381,7 @@ static int svc_normal_to_secure_thread(void *data)
|
|||
struct stratix10_svc_data *pdata;
|
||||
struct stratix10_svc_cb_data *cbdata;
|
||||
struct arm_smccc_res res;
|
||||
unsigned long a0, a1, a2;
|
||||
unsigned long a0, a1, a2, a3, a4, a5, a6, a7;
|
||||
int ret_fifo = 0;
|
||||
|
||||
pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
|
||||
|
@ -383,6 +398,11 @@ static int svc_normal_to_secure_thread(void *data)
|
|||
a0 = INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK;
|
||||
a1 = 0;
|
||||
a2 = 0;
|
||||
a3 = 0;
|
||||
a4 = 0;
|
||||
a5 = 0;
|
||||
a6 = 0;
|
||||
a7 = 0;
|
||||
|
||||
pr_debug("smc_hvc_shm_thread is running\n");
|
||||
|
||||
|
@ -453,12 +473,50 @@ static int svc_normal_to_secure_thread(void *data)
|
|||
a1 = 0;
|
||||
a2 = 0;
|
||||
break;
|
||||
|
||||
/* for FCS */
|
||||
case COMMAND_FCS_DATA_ENCRYPTION:
|
||||
a0 = INTEL_SIP_SMC_FCS_CRYPTION;
|
||||
a1 = 1;
|
||||
a2 = (unsigned long)pdata->paddr;
|
||||
a3 = (unsigned long)pdata->size;
|
||||
a4 = (unsigned long)pdata->paddr_output;
|
||||
a5 = (unsigned long)pdata->size_output;
|
||||
break;
|
||||
case COMMAND_FCS_DATA_DECRYPTION:
|
||||
a0 = INTEL_SIP_SMC_FCS_CRYPTION;
|
||||
a1 = 0;
|
||||
a2 = (unsigned long)pdata->paddr;
|
||||
a3 = (unsigned long)pdata->size;
|
||||
a4 = (unsigned long)pdata->paddr_output;
|
||||
a5 = (unsigned long)pdata->size_output;
|
||||
break;
|
||||
case COMMAND_FCS_RANDOM_NUMBER_GEN:
|
||||
a0 = INTEL_SIP_SMC_FCS_RANDOM_NUMBER;
|
||||
a1 = (unsigned long)pdata->paddr;
|
||||
a2 = 0;
|
||||
break;
|
||||
case COMMAND_FCS_REQUEST_SERVICE:
|
||||
a0 = INTEL_SIP_SMC_FCS_SERVICE_REQUEST;
|
||||
a1 = (unsigned long)pdata->paddr;
|
||||
a2 = (unsigned long)pdata->size;
|
||||
break;
|
||||
case COMMAND_FCS_SEND_CERTIFICATE:
|
||||
a0 = INTEL_SIP_SMC_FCS_SEND_CERTIFICATE;
|
||||
a1 = (unsigned long)pdata->paddr;
|
||||
a2 = (unsigned long)pdata->size;
|
||||
break;
|
||||
case COMMAND_FCS_GET_PROVISION_DATA:
|
||||
a0 = INTEL_SIP_SMC_FCS_GET_PROVISION_DATA;
|
||||
a1 = (unsigned long)pdata->paddr;
|
||||
a2 = 0;
|
||||
break;
|
||||
|
||||
/* for polling */
|
||||
case COMMAND_POLL_SERVICE_STATUS:
|
||||
a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
|
||||
a1 = (unsigned long)pdata->paddr;
|
||||
a2 = (unsigned long)pdata->size;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -466,10 +524,14 @@ static int svc_normal_to_secure_thread(void *data)
|
|||
break;
|
||||
}
|
||||
pr_debug("%s: before SMC call -- a0=0x%016x a1=0x%016x",
|
||||
__func__, (unsigned int)a0, (unsigned int)a1);
|
||||
__func__,
|
||||
(unsigned int)a0,
|
||||
(unsigned int)a1);
|
||||
pr_debug(" a2=0x%016x\n", (unsigned int)a2);
|
||||
|
||||
ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
|
||||
pr_debug(" a3=0x%016x\n", (unsigned int)a3);
|
||||
pr_debug(" a4=0x%016x\n", (unsigned int)a4);
|
||||
pr_debug(" a5=0x%016x\n", (unsigned int)a5);
|
||||
ctrl->invoke_fn(a0, a1, a2, a3, a4, a5, a6, a7, &res);
|
||||
|
||||
pr_debug("%s: after SMC call -- res.a0=0x%016x",
|
||||
__func__, (unsigned int)res.a0);
|
||||
|
@ -512,6 +574,22 @@ static int svc_normal_to_secure_thread(void *data)
|
|||
break;
|
||||
case INTEL_SIP_SMC_STATUS_REJECTED:
|
||||
pr_debug("%s: STATUS_REJECTED\n", __func__);
|
||||
/* for FCS */
|
||||
switch (pdata->command) {
|
||||
case COMMAND_FCS_REQUEST_SERVICE:
|
||||
case COMMAND_FCS_SEND_CERTIFICATE:
|
||||
case COMMAND_FCS_GET_PROVISION_DATA:
|
||||
case COMMAND_FCS_DATA_ENCRYPTION:
|
||||
case COMMAND_FCS_DATA_DECRYPTION:
|
||||
case COMMAND_FCS_RANDOM_NUMBER_GEN:
|
||||
cbdata->status = BIT(SVC_STATUS_INVALID_PARAM);
|
||||
cbdata->kaddr1 = NULL;
|
||||
cbdata->kaddr2 = NULL;
|
||||
cbdata->kaddr3 = NULL;
|
||||
pdata->chan->scl->receive_cb(pdata->chan->scl,
|
||||
cbdata);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INTEL_SIP_SMC_STATUS_ERROR:
|
||||
case INTEL_SIP_SMC_RSU_ERROR:
|
||||
|
@ -886,8 +964,19 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg)
|
|||
list_for_each_entry(p_mem, &svc_data_mem, node)
|
||||
if (p_mem->vaddr == p_msg->payload) {
|
||||
p_data->paddr = p_mem->paddr;
|
||||
p_data->size = p_msg->payload_length;
|
||||
break;
|
||||
}
|
||||
if (p_msg->payload_output) {
|
||||
list_for_each_entry(p_mem, &svc_data_mem, node)
|
||||
if (p_mem->vaddr == p_msg->payload_output) {
|
||||
p_data->paddr_output =
|
||||
p_mem->paddr;
|
||||
p_data->size_output =
|
||||
p_msg->payload_length_output;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_data->command = p_msg->command;
|
||||
|
|
|
@ -445,4 +445,115 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
|
|||
#define INTEL_SIP_SMC_FIRMWARE_VERSION \
|
||||
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FIRMWARE_VERSION)
|
||||
|
||||
/**
|
||||
* SMC call protocol for FPGA Crypto Service (FCS)
|
||||
* FUNCID starts from 90
|
||||
*/
|
||||
|
||||
/**
|
||||
* Request INTEL_SIP_SMC_FCS_RANDOM_NUMBER
|
||||
*
|
||||
* Sync call used to query the random number generated by the firmware
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 INTEL_SIP_SMC_FCS_RANDOM_NUMBER
|
||||
* a1 the physical address for firmware to write generated random data
|
||||
* a2-a7 not used
|
||||
*
|
||||
* Return status:
|
||||
* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or
|
||||
* INTEL_SIP_SMC_FCS_REJECTED
|
||||
* a1 mailbox error
|
||||
* a2 the physical address of generated random number
|
||||
* a3 size
|
||||
*/
|
||||
#define INTEL_SIP_SMC_FUNCID_FCS_RANDOM_NUMBER 90
|
||||
#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER \
|
||||
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_RANDOM_NUMBER)
|
||||
|
||||
/**
|
||||
* Request INTEL_SIP_SMC_FCS_CRYPTION
|
||||
* Async call for data encryption and HMAC signature generation, or for
|
||||
* data decryption and HMAC verification.
|
||||
*
|
||||
* Call INTEL_SIP_SMC_SERVICE_COMPLETED to get the output encrypted or
|
||||
* decrypted data
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 INTEL_SIP_SMC_FCS_CRYPTION
|
||||
* a1 cryption mode (1 for encryption and 0 for decryption)
|
||||
* a2 physical address which stores to be encrypted or decrypted data
|
||||
* a3 input data size
|
||||
* a4 physical address which will hold the encrypted or decrypted output data
|
||||
* a5 output data size
|
||||
* a6-a7 not used
|
||||
*
|
||||
* Return status:
|
||||
* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_ERROR or
|
||||
* INTEL_SIP_SMC_STATUS_REJECTED
|
||||
* a1-3 not used
|
||||
*/
|
||||
#define INTEL_SIP_SMC_FUNCID_FCS_CRYPTION 91
|
||||
#define INTEL_SIP_SMC_FCS_CRYPTION \
|
||||
INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_CRYPTION)
|
||||
|
||||
/**
|
||||
* Request INTEL_SIP_SMC_FCS_SERVICE_REQUEST
|
||||
* Async call for authentication service of HPS software
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 INTEL_SIP_SMC_FCS_SERVICE_REQUEST
|
||||
* a1 the physical address of data block
|
||||
* a2 size of data block
|
||||
* a3-a7 not used
|
||||
*
|
||||
* Return status:
|
||||
* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_ERROR or
|
||||
* INTEL_SIP_SMC_REJECTED
|
||||
* a1-a3 not used
|
||||
*/
|
||||
#define INTEL_SIP_SMC_FUNCID_FCS_SERVICE_REQUEST 92
|
||||
#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST \
|
||||
INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_SERVICE_REQUEST)
|
||||
|
||||
/**
|
||||
* Request INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE
|
||||
* Sync call to send a signed certificate
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 INTEL_SIP_SMC_FCS_SEND_CERTIFICATE
|
||||
* a1 the physical address of CERTIFICATE block
|
||||
* a2 size of data block
|
||||
* a3-a7 not used
|
||||
*
|
||||
* Return status:
|
||||
* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_FCS_REJECTED
|
||||
* a1-a3 not used
|
||||
*/
|
||||
#define INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE 93
|
||||
#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE \
|
||||
INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE)
|
||||
|
||||
/**
|
||||
* Request INTEL_SIP_SMC_FCS_GET_PROVISION_DATA
|
||||
* Sync call to dump all the fuses and key hashes
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 INTEL_SIP_SMC_FCS_GET_PROVISION_DATA
|
||||
* a1 the physical address for firmware to write structure of fuse and
|
||||
* key hashes
|
||||
* a2-a7 not used
|
||||
*
|
||||
* Return status:
|
||||
* a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or
|
||||
* INTEL_SIP_SMC_FCS_REJECTED
|
||||
* a1 mailbox error
|
||||
* a2 physical address for the structure of fuse and key hashes
|
||||
* a3 the size of structure
|
||||
*
|
||||
*/
|
||||
#define INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA 94
|
||||
#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA \
|
||||
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
#define SVC_STATUS_BUSY 4
|
||||
#define SVC_STATUS_ERROR 5
|
||||
#define SVC_STATUS_NO_SUPPORT 6
|
||||
|
||||
/*
|
||||
#define SVC_STATUS_INVALID_PARAM 7
|
||||
/**
|
||||
* Flag bit for COMMAND_RECONFIG
|
||||
*
|
||||
* COMMAND_RECONFIG_FLAG_PARTIAL:
|
||||
|
@ -67,6 +67,8 @@
|
|||
#define SVC_RECONFIG_REQUEST_TIMEOUT_MS 300
|
||||
#define SVC_RECONFIG_BUFFER_TIMEOUT_MS 720
|
||||
#define SVC_RSU_REQUEST_TIMEOUT_MS 300
|
||||
#define SVC_FCS_REQUEST_TIMEOUT_MS 2000
|
||||
#define SVC_COMPLETED_TIMEOUT_MS 30000
|
||||
|
||||
struct stratix10_svc_chan;
|
||||
|
||||
|
@ -111,20 +113,47 @@ struct stratix10_svc_chan;
|
|||
*
|
||||
* @COMMAND_FIRMWARE_VERSION: query running firmware version, return status
|
||||
* is SVC_STATUS_OK or SVC_STATUS_ERROR
|
||||
*
|
||||
* @COMMAND_FCS_REQUEST_SERVICE: request validation of image from firmware,
|
||||
* return status is SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM
|
||||
*
|
||||
* @COMMAND_FCS_SEND_CERTIFICATE: send a certificate, return status is
|
||||
* SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
|
||||
*
|
||||
* @COMMAND_FCS_GET_PROVISION_DATA: read the provisioning data, return status is
|
||||
* SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
|
||||
*
|
||||
* @COMMAND_FCS_DATA_ENCRYPTION: encrypt the data, return status is
|
||||
* SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
|
||||
*
|
||||
* @COMMAND_FCS_DATA_DECRYPTION: decrypt the data, return status is
|
||||
* SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
|
||||
*
|
||||
* @COMMAND_FCS_RANDOM_NUMBER_GEN: generate a random number, return status
|
||||
* is SVC_STATUS_OK, SVC_STATUS_ERROR
|
||||
*/
|
||||
enum stratix10_svc_command_code {
|
||||
/* for FPGA */
|
||||
COMMAND_NOOP = 0,
|
||||
COMMAND_RECONFIG,
|
||||
COMMAND_RECONFIG_DATA_SUBMIT,
|
||||
COMMAND_RECONFIG_DATA_CLAIM,
|
||||
COMMAND_RECONFIG_STATUS,
|
||||
COMMAND_RSU_STATUS,
|
||||
/* for RSU */
|
||||
COMMAND_RSU_STATUS = 10,
|
||||
COMMAND_RSU_UPDATE,
|
||||
COMMAND_RSU_NOTIFY,
|
||||
COMMAND_RSU_RETRY,
|
||||
COMMAND_RSU_MAX_RETRY,
|
||||
COMMAND_RSU_DCMF_VERSION,
|
||||
COMMAND_FIRMWARE_VERSION,
|
||||
/* for FCS */
|
||||
COMMAND_FCS_REQUEST_SERVICE = 20,
|
||||
COMMAND_FCS_SEND_CERTIFICATE,
|
||||
COMMAND_FCS_GET_PROVISION_DATA,
|
||||
COMMAND_FCS_DATA_ENCRYPTION,
|
||||
COMMAND_FCS_DATA_DECRYPTION,
|
||||
COMMAND_FCS_RANDOM_NUMBER_GEN,
|
||||
/* for general status poll */
|
||||
COMMAND_POLL_SERVICE_STATUS = 40,
|
||||
};
|
||||
|
@ -132,13 +161,17 @@ enum stratix10_svc_command_code {
|
|||
/**
|
||||
* struct stratix10_svc_client_msg - message sent by client to service
|
||||
* @payload: starting address of data need be processed
|
||||
* @payload_length: data size in bytes
|
||||
* @payload_length: to be processed data size in bytes
|
||||
* @payload_output: starting address of processed data
|
||||
* @payload_length_output: processed data size in bytes
|
||||
* @command: service command
|
||||
* @arg: args to be passed via registers and not physically mapped buffers
|
||||
*/
|
||||
struct stratix10_svc_client_msg {
|
||||
void *payload;
|
||||
size_t payload_length;
|
||||
void *payload_output;
|
||||
size_t payload_length_output;
|
||||
enum stratix10_svc_command_code command;
|
||||
u64 arg[3];
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче