arm-trusted-firmware/plat/intel/soc/common/sip/socfpga_sip_fcs.c

800 lines
18 KiB
C

/*
* Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <lib/mmio.h>
#include "socfpga_fcs.h"
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
/* FCS static variables */
static fcs_crypto_service_data fcs_sha_get_digest_param;
bool is_size_4_bytes_aligned(uint32_t size)
{
if ((size % MBOX_WORD_BYTE) != 0U) {
return false;
} else {
return true;
}
}
static bool is_8_bytes_aligned(uint32_t data)
{
if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
return false;
} else {
return true;
}
}
static int intel_fcs_crypto_service_init(uint32_t session_id,
uint32_t context_id, uint32_t key_id,
uint32_t param_size, uint64_t param_data,
fcs_crypto_service_data *data_addr,
uint32_t *mbox_error)
{
if (mbox_error == NULL) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (param_size != 4) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
memset(data_addr, 0, sizeof(fcs_crypto_service_data));
data_addr->session_id = session_id;
data_addr->context_id = context_id;
data_addr->key_id = key_id;
data_addr->crypto_param_size = param_size;
data_addr->crypto_param = param_data;
*mbox_error = 0;
return INTEL_SIP_SMC_STATUS_OK;
}
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error)
{
int status;
unsigned int i;
unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
CMD_CASUAL, random_data, &resp_len);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
if (resp_len != FCS_RANDOM_WORD_SIZE) {
*mbox_error = GENERIC_RESPONSE_ERROR;
return INTEL_SIP_SMC_STATUS_ERROR;
}
*ret_size = FCS_RANDOM_BYTE_SIZE;
for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
mmio_write_32(addr, random_data[i]);
addr += MBOX_WORD_BYTE;
}
flush_dcache_range(addr - *ret_size, *ret_size);
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
uint32_t size, uint32_t *send_id)
{
int status;
uint32_t payload_size;
uint32_t crypto_header;
if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
MBOX_WORD_BYTE) || size == 0U) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_size_4_bytes_aligned(size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
FCS_CS_FIELD_FLAG_OFFSET;
fcs_rng_payload payload = {
session_id,
context_id,
crypto_header,
size
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
(uint32_t *) &payload, payload_size,
CMD_INDIRECT);
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t *send_id)
{
int status;
if (!is_address_in_ddr_range(addr, size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_size_4_bytes_aligned(size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
(uint32_t *)addr, size / MBOX_WORD_BYTE,
CMD_DIRECT);
flush_dcache_range(addr, size);
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
{
int status;
status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
NULL, 0U, CMD_DIRECT);
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
uint32_t test_bit, uint32_t *mbox_error)
{
int status;
uint32_t first_word;
uint32_t payload_size;
if ((test_bit != MBOX_TEST_BIT) &&
(test_bit != 0)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if ((counter_type < FCS_BIG_CNTR_SEL) ||
(counter_type > FCS_SVN_CNTR_3_SEL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if ((counter_type == FCS_BIG_CNTR_SEL) &&
(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
(counter_type <= FCS_SVN_CNTR_3_SEL) &&
(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
first_word = test_bit | counter_type;
fcs_cntr_set_preauth_payload payload = {
first_word,
counter_value
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, NULL, NULL);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
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 load_size;
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(src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
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, MBOX_FCS_DECRYPT_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_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error)
{
int status;
unsigned int resp_len = FCS_SHA384_WORD_SIZE;
if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
CMD_CASUAL, (uint32_t *) addr, &resp_len);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
if (resp_len != FCS_SHA384_WORD_SIZE) {
*mbox_error = GENERIC_RESPONSE_ERROR;
return INTEL_SIP_SMC_STATUS_ERROR;
}
*ret_size = FCS_SHA384_BYTE_SIZE;
flush_dcache_range(addr, *ret_size);
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
{
int status;
if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
psgsigma_teardown_msg message = {
RESERVED_AS_ZERO,
PSGSIGMA_TEARDOWN_MAGIC,
session_id
};
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
CMD_CASUAL, NULL, NULL);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
{
int status;
uint32_t load_size;
uint32_t chip_id[2];
load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
*id_low = chip_id[0];
*id_high = chip_id[1];
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
{
int status;
uint32_t send_size = src_size / MBOX_WORD_BYTE;
uint32_t ret_size = *dst_size / 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;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
(uint32_t *) src_addr, send_size, 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_get_measurement(uint64_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
{
int status;
uint32_t send_size = src_size / MBOX_WORD_BYTE;
uint32_t ret_size = *dst_size / 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;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
(uint32_t *) src_addr, send_size, 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_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;
}
int intel_fcs_open_crypto_service_session(uint32_t *session_id,
uint32_t *mbox_error)
{
int status;
uint32_t resp_len = 1U;
if ((session_id == NULL) || (mbox_error == NULL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
NULL, 0U, CMD_CASUAL, session_id, &resp_len);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_close_crypto_service_session(uint32_t session_id,
uint32_t *mbox_error)
{
int status;
if (mbox_error == NULL) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
&session_id, 1U, CMD_CASUAL, NULL, NULL);
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
uint32_t *send_id)
{
int status;
if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
MBOX_WORD_BYTE)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(src_addr, src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
(uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
CMD_INDIRECT);
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error)
{
int status;
uint32_t i;
uint32_t payload_size;
uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
uint32_t op_status = 0U;
if ((dst_size == NULL) || (mbox_error == NULL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, resp_data, &resp_len);
if (resp_len > 0) {
op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
return INTEL_SIP_SMC_STATUS_ERROR;
}
if (resp_len > 1) {
/* Export key object is start at second response data */
*dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
for (i = 1U; i < resp_len; i++) {
mmio_write_32(dst_addr, resp_data[i]);
dst_addr += MBOX_WORD_BYTE;
}
flush_dcache_range(dst_addr - *dst_size, *dst_size);
} else {
/* Unexpected response, missing key object in response */
*mbox_error = MBOX_RET_ERROR;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
uint32_t *mbox_error)
{
int status;
uint32_t payload_size;
uint32_t resp_len = 1U;
uint32_t resp_data = 0U;
uint32_t op_status = 0U;
if (mbox_error == NULL) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, &resp_data, &resp_len);
if (resp_len > 0) {
op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error)
{
int status;
uint32_t payload_size;
uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
uint32_t op_status = 0U;
if ((dst_size == NULL) || (mbox_error == NULL)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
fcs_cs_key_payload payload = {
session_id,
RESERVED_AS_ZERO,
RESERVED_AS_ZERO,
key_id
};
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
(uint32_t *) &payload, payload_size,
CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
if (resp_len > 0) {
op_status = mmio_read_32(dst_addr) &
FCS_CS_KEY_RESP_STATUS_MASK;
}
if (status < 0) {
*mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
return INTEL_SIP_SMC_STATUS_ERROR;
}
*dst_size = resp_len * MBOX_WORD_BYTE;
flush_dcache_range(dst_addr, *dst_size);
return INTEL_SIP_SMC_STATUS_OK;
}
int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error)
{
return intel_fcs_crypto_service_init(session_id, context_id,
key_id, param_size, param_data,
(void *) &fcs_sha_get_digest_param,
mbox_error);
}
int intel_fcs_get_digest_finalize(uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error)
{
int status;
uint32_t i;
uint32_t resp_len = *dst_size / MBOX_WORD_BYTE;
uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
if (dst_size == NULL || mbox_error == NULL) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
if (fcs_sha_get_digest_param.session_id != session_id ||
fcs_sha_get_digest_param.context_id != context_id) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
/* Source data must be 8 bytes aligned */
if (!is_8_bytes_aligned(src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
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;
}
/* Prepare command payload */
i = 0;
/* Crypto header */
payload[i] = fcs_sha_get_digest_param.session_id;
i++;
payload[i] = fcs_sha_get_digest_param.context_id;
i++;
payload[i] = fcs_sha_get_digest_param.crypto_param_size
& FCS_CS_FIELD_SIZE_MASK;
payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
| FCS_CS_FIELD_FLAG_FINALIZE)
<< FCS_CS_FIELD_FLAG_OFFSET;
i++;
payload[i] = fcs_sha_get_digest_param.key_id;
i++;
/* Crypto parameters */
payload[i] = fcs_sha_get_digest_param.crypto_param
& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
payload[i] |= ((fcs_sha_get_digest_param.crypto_param
>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
i++;
/* Data source address and size */
payload[i] = src_addr;
i++;
payload[i] = src_size;
i++;
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
payload, i, CMD_CASUAL,
(uint32_t *) dst_addr, &resp_len);
memset((void *)&fcs_sha_get_digest_param, 0, sizeof(fcs_crypto_service_data));
if (status < 0) {
*mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
*dst_size = resp_len * MBOX_WORD_BYTE;
flush_dcache_range(dst_addr, *dst_size);
return INTEL_SIP_SMC_STATUS_OK;
}