mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
2337 lines
58 KiB
C
2337 lines
58 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_aes_data fcs_aes_init_payload;
|
|
static fcs_crypto_service_data fcs_sha_get_digest_param;
|
|
static fcs_crypto_service_data fcs_sha_mac_verify_param;
|
|
static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
|
|
static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
|
|
static fcs_crypto_service_data fcs_sha2_data_sign_param;
|
|
static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
|
|
static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
|
|
static fcs_crypto_service_data fcs_ecdh_request_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 bool is_32_bytes_aligned(uint32_t data)
|
|
{
|
|
if ((data % (8U * MBOX_WORD_BYTE)) != 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;
|
|
|
|
data_addr->is_updated = 0;
|
|
|
|
*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;
|
|
|
|
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;
|
|
}
|
|
|
|
fcs_encrypt_payload payload = {
|
|
FCS_ENCRYPTION_DATA_0,
|
|
src_addr,
|
|
src_size,
|
|
dst_addr,
|
|
dst_size };
|
|
load_size = sizeof(payload) / MBOX_WORD_BYTE;
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
|
|
uint32_t src_addr, uint32_t src_size,
|
|
uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
uint32_t payload_size;
|
|
uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
|
|
uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
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;
|
|
}
|
|
|
|
if (!is_size_4_bytes_aligned(src_size)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
fcs_encrypt_ext_payload payload = {
|
|
session_id,
|
|
context_id,
|
|
FCS_CRYPTION_CRYPTO_HEADER,
|
|
src_addr,
|
|
src_size,
|
|
dst_addr,
|
|
*dst_size
|
|
};
|
|
|
|
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
|
|
(uint32_t *) &payload, payload_size,
|
|
CMD_CASUAL, resp_data, &resp_len);
|
|
|
|
if (status < 0) {
|
|
*mbox_error = -status;
|
|
return INTEL_SIP_SMC_STATUS_ERROR;
|
|
}
|
|
|
|
if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
|
|
*mbox_error = MBOX_RET_ERROR;
|
|
return INTEL_SIP_SMC_STATUS_ERROR;
|
|
}
|
|
|
|
*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
|
|
inv_dcache_range(dst_addr, *dst_size);
|
|
|
|
return INTEL_SIP_SMC_STATUS_OK;
|
|
}
|
|
|
|
int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
|
|
uint32_t src_addr, uint32_t src_size,
|
|
uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
uintptr_t id_offset;
|
|
uint32_t payload_size;
|
|
uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
|
|
uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
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;
|
|
}
|
|
|
|
if (!is_size_4_bytes_aligned(src_size)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
|
|
id_offset = src_addr + FCS_OWNER_ID_OFFSET;
|
|
fcs_decrypt_ext_payload payload = {
|
|
session_id,
|
|
context_id,
|
|
FCS_CRYPTION_CRYPTO_HEADER,
|
|
{mmio_read_32(id_offset),
|
|
mmio_read_32(id_offset + MBOX_WORD_BYTE)},
|
|
src_addr,
|
|
src_size,
|
|
dst_addr,
|
|
*dst_size
|
|
};
|
|
|
|
payload_size = sizeof(payload) / MBOX_WORD_BYTE;
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
|
|
(uint32_t *) &payload, payload_size,
|
|
CMD_CASUAL, resp_data, &resp_len);
|
|
|
|
if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
|
|
status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
|
|
*mbox_error = -status;
|
|
} else if (status < 0) {
|
|
*mbox_error = -status;
|
|
return INTEL_SIP_SMC_STATUS_ERROR;
|
|
}
|
|
|
|
if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
|
|
*mbox_error = MBOX_RET_ERROR;
|
|
return INTEL_SIP_SMC_STATUS_ERROR;
|
|
}
|
|
|
|
*dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
|
|
inv_dcache_range(dst_addr, *dst_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;
|
|
}
|
|
|
|
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_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_ATTEST_FIRMWARE_CERT ||
|
|
cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
|
|
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_ATTEST_FIRMWARE_CERT ||
|
|
cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
|
|
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) {
|
|
inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */
|
|
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_update_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, uint8_t is_finalised,
|
|
uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t resp_len;
|
|
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;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
|
|
if (fcs_sha_get_digest_param.is_updated) {
|
|
fcs_sha_get_digest_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised != 0U) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha_get_digest_param.is_updated = 1;
|
|
}
|
|
|
|
crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
(fcs_sha_get_digest_param.crypto_param_size &
|
|
FCS_CS_FIELD_SIZE_MASK));
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha_get_digest_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha_get_digest_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
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);
|
|
|
|
if (is_finalised != 0U) {
|
|
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;
|
|
}
|
|
|
|
int intel_fcs_get_digest_smmu_update_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, uint8_t is_finalised,
|
|
uint32_t *mbox_error, uint32_t *send_id)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t resp_len;
|
|
uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
|
|
|
|
/* Source data must be 8 bytes aligned */
|
|
if (dst_size == NULL || mbox_error == NULL ||
|
|
!is_8_bytes_aligned(src_size)) {
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
|
|
if (fcs_sha_get_digest_param.is_updated) {
|
|
fcs_sha_get_digest_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised != 0U) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha_get_digest_param.is_updated = 1;
|
|
}
|
|
|
|
crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
(fcs_sha_get_digest_param.crypto_param_size &
|
|
FCS_CS_FIELD_SIZE_MASK));
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha_get_digest_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha_get_digest_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
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_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
|
|
payload, i, CMD_INDIRECT);
|
|
|
|
if (is_finalised != 0U) {
|
|
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;
|
|
}
|
|
|
|
int intel_fcs_mac_verify_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_mac_verify_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_mac_verify_update_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 data_size,
|
|
uint8_t is_finalised, uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t resp_len;
|
|
uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
|
|
uintptr_t mac_offset;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
if (dst_size == NULL || mbox_error == NULL) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha_mac_verify_param.session_id != session_id ||
|
|
fcs_sha_mac_verify_param.context_id != context_id) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (data_size > src_size) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (!is_size_4_bytes_aligned(src_size) ||
|
|
!is_8_bytes_aligned(data_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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
|
|
if (fcs_sha_mac_verify_param.is_updated) {
|
|
fcs_sha_mac_verify_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha_mac_verify_param.is_updated = 1;
|
|
}
|
|
|
|
crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
(fcs_sha_mac_verify_param.crypto_param_size &
|
|
FCS_CS_FIELD_SIZE_MASK));
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha_mac_verify_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha_mac_verify_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha_mac_verify_param.key_id;
|
|
i++;
|
|
/* Crypto parameters */
|
|
payload[i] = ((fcs_sha_mac_verify_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] = data_size;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_FINALIZE) {
|
|
/* Copy mac data to command */
|
|
mac_offset = src_addr + data_size;
|
|
|
|
if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
|
|
FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
|
|
src_size - data_size);
|
|
|
|
i += (src_size - data_size) / MBOX_WORD_BYTE;
|
|
}
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
|
|
payload, i, CMD_CASUAL,
|
|
(uint32_t *) dst_addr, &resp_len);
|
|
|
|
if (is_finalised) {
|
|
memset((void *)&fcs_sha_mac_verify_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;
|
|
}
|
|
|
|
int intel_fcs_mac_verify_smmu_update_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 data_size,
|
|
uint8_t is_finalised, uint32_t *mbox_error,
|
|
uint32_t *send_id)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t resp_len;
|
|
uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
|
|
uintptr_t mac_offset;
|
|
uint32_t dst_size_check = 0;
|
|
/*
|
|
* Source data must be 4 bytes aligned
|
|
* User data must be 8 bytes aligned
|
|
*/
|
|
if (dst_size == NULL || mbox_error == NULL ||
|
|
!is_size_4_bytes_aligned(src_size) ||
|
|
!is_8_bytes_aligned(data_size)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (data_size > src_size) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha_mac_verify_param.session_id != session_id ||
|
|
fcs_sha_mac_verify_param.context_id != context_id) {
|
|
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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
|
|
if (fcs_sha_mac_verify_param.is_updated) {
|
|
fcs_sha_mac_verify_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha_mac_verify_param.is_updated = 1;
|
|
}
|
|
|
|
crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
(fcs_sha_mac_verify_param.crypto_param_size &
|
|
FCS_CS_FIELD_SIZE_MASK));
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha_mac_verify_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha_mac_verify_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha_mac_verify_param.key_id;
|
|
i++;
|
|
/* Crypto parameters */
|
|
payload[i] = ((fcs_sha_mac_verify_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] = data_size;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_FINALIZE) {
|
|
/* Copy mac data to command
|
|
* Using dst_addr (physical address) to store mac_offset
|
|
* mac_offset = MAC data
|
|
*/
|
|
mac_offset = dst_addr;
|
|
|
|
if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
|
|
FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
|
|
src_size - data_size);
|
|
|
|
memset((void *) dst_addr, 0, *dst_size);
|
|
|
|
i += (src_size - data_size) / MBOX_WORD_BYTE;
|
|
}
|
|
|
|
status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
|
|
payload, i, CMD_INDIRECT);
|
|
|
|
if (is_finalised) {
|
|
memset((void *)&fcs_sha_mac_verify_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_hash_sign_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_ecdsa_hash_sign_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdsa_hash_sign_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 payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
uintptr_t hash_data_addr;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
|
|
fcs_ecdsa_hash_sign_param.context_id != context_id) {
|
|
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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare command payload */
|
|
/* Crypto header */
|
|
i = 0;
|
|
payload[i] = fcs_ecdsa_hash_sign_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sign_param.context_id;
|
|
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sign_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_ecdsa_hash_sign_param.key_id;
|
|
|
|
/* Crypto parameters */
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
|
|
/* Hash Data */
|
|
i++;
|
|
hash_data_addr = src_addr;
|
|
|
|
if ((i + ((src_size) / MBOX_WORD_BYTE)) >
|
|
FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
|
|
src_size);
|
|
|
|
i += src_size / MBOX_WORD_BYTE;
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
|
|
payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
|
|
&resp_len);
|
|
|
|
memset((void *) &fcs_ecdsa_hash_sign_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_hash_sig_verify_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_ecdsa_hash_sig_verify_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdsa_hash_sig_verify_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 = 0;
|
|
uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
uintptr_t hash_sig_pubkey_addr;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
|
|
fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
|
|
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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare command payload */
|
|
/* Crypto header */
|
|
i = 0;
|
|
payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
|
|
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
|
|
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sig_verify_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_ecdsa_hash_sig_verify_param.key_id;
|
|
|
|
/* Crypto parameters */
|
|
i++;
|
|
payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
|
|
/* Hash Data Word, Signature Data Word and Public Key Data word */
|
|
i++;
|
|
hash_sig_pubkey_addr = src_addr;
|
|
|
|
if ((i + ((src_size) / MBOX_WORD_BYTE)) >
|
|
FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i],
|
|
(uint8_t *) hash_sig_pubkey_addr, src_size);
|
|
|
|
i += (src_size / MBOX_WORD_BYTE);
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
|
|
payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
|
|
&resp_len);
|
|
|
|
memset((void *)&fcs_ecdsa_hash_sig_verify_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sign_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_sha2_data_sign_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sign_update_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, uint8_t is_finalised,
|
|
uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
int i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha2_data_sign_param.session_id != session_id ||
|
|
fcs_sha2_data_sign_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;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
if (fcs_sha2_data_sign_param.is_updated) {
|
|
fcs_sha2_data_sign_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised != 0U) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha2_data_sign_param.is_updated = 1;
|
|
}
|
|
crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_sha2_data_sign_param.crypto_param_size;
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha2_data_sign_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sign_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha2_data_sign_param.key_id;
|
|
/* Crypto parameters */
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sign_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
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_ECDSA_SHA2_DATA_SIGN_REQ, payload,
|
|
i, CMD_CASUAL, (uint32_t *) dst_addr,
|
|
&resp_len);
|
|
|
|
if (is_finalised != 0U) {
|
|
memset((void *)&fcs_sha2_data_sign_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sign_smmu_update_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, uint8_t is_finalised,
|
|
uint32_t *mbox_error, uint32_t *send_id)
|
|
{
|
|
int status;
|
|
int i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
|
|
/* Source data must be 8 bytes aligned */
|
|
if ((dst_size == NULL) || (mbox_error == NULL ||
|
|
!is_8_bytes_aligned(src_size))) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha2_data_sign_param.session_id != session_id ||
|
|
fcs_sha2_data_sign_param.context_id != context_id) {
|
|
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;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
if (fcs_sha2_data_sign_param.is_updated) {
|
|
fcs_sha2_data_sign_param.crypto_param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised != 0U) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha2_data_sign_param.is_updated = 1;
|
|
}
|
|
crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_sha2_data_sign_param.crypto_param_size;
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha2_data_sign_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sign_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha2_data_sign_param.key_id;
|
|
/* Crypto parameters */
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sign_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
i++;
|
|
}
|
|
|
|
/* Data source address and size */
|
|
payload[i] = src_addr;
|
|
i++;
|
|
payload[i] = src_size;
|
|
i++;
|
|
|
|
status = mailbox_send_cmd_async(send_id,
|
|
MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
|
|
payload, i, CMD_INDIRECT);
|
|
|
|
if (is_finalised != 0U) {
|
|
memset((void *)&fcs_sha2_data_sign_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sig_verify_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_sha2_data_sig_verify_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sig_verify_update_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 data_size,
|
|
uint8_t is_finalised, uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
uintptr_t sig_pubkey_offset;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
|
|
fcs_sha2_data_sig_verify_param.context_id != context_id) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (data_size > src_size) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (!is_size_4_bytes_aligned(src_size)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (!is_8_bytes_aligned(data_size) ||
|
|
!is_8_bytes_aligned(src_addr)) {
|
|
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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
if (fcs_sha2_data_sig_verify_param.is_updated)
|
|
fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
|
|
else
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
|
|
if (is_finalised != 0U)
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha2_data_sig_verify_param.is_updated = 1;
|
|
}
|
|
crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_sha2_data_sig_verify_param.crypto_param_size;
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha2_data_sig_verify_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sig_verify_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha2_data_sig_verify_param.key_id;
|
|
i++;
|
|
/* Crypto parameters */
|
|
payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
i++;
|
|
}
|
|
|
|
/* Data source address and size */
|
|
payload[i] = src_addr;
|
|
i++;
|
|
payload[i] = data_size;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_FINALIZE) {
|
|
/* Signature + Public Key Data */
|
|
sig_pubkey_offset = src_addr + data_size;
|
|
|
|
if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
|
|
FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
|
|
src_size - data_size);
|
|
|
|
i += (src_size - data_size) / MBOX_WORD_BYTE;
|
|
}
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID,
|
|
MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
|
|
CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
|
|
|
|
if (is_finalised != 0U) {
|
|
memset((void *) &fcs_sha2_data_sig_verify_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_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 data_size,
|
|
uint8_t is_finalised, uint32_t *mbox_error,
|
|
uint32_t *send_id)
|
|
{
|
|
int status;
|
|
uint32_t i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
uintptr_t sig_pubkey_offset;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
/*
|
|
* Source data must be 4 bytes aligned
|
|
* Source address must be 8 bytes aligned
|
|
* User data must be 8 bytes aligned
|
|
*/
|
|
if ((dst_size == NULL) || (mbox_error == NULL) ||
|
|
!is_size_4_bytes_aligned(src_size) ||
|
|
!is_8_bytes_aligned(src_addr) ||
|
|
!is_8_bytes_aligned(data_size)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
|
|
fcs_sha2_data_sig_verify_param.context_id != context_id) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if (data_size > 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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare crypto header */
|
|
flag = 0;
|
|
if (fcs_sha2_data_sig_verify_param.is_updated)
|
|
fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
|
|
else
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
|
|
if (is_finalised != 0U)
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_sha2_data_sig_verify_param.is_updated = 1;
|
|
}
|
|
crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_sha2_data_sig_verify_param.crypto_param_size;
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
payload[i] = fcs_sha2_data_sig_verify_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_sha2_data_sig_verify_param.context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
payload[i] = fcs_sha2_data_sig_verify_param.key_id;
|
|
i++;
|
|
/* Crypto parameters */
|
|
payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
i++;
|
|
}
|
|
|
|
/* Data source address and size */
|
|
payload[i] = src_addr;
|
|
i++;
|
|
payload[i] = data_size;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_FINALIZE) {
|
|
/* Copy mac data to command
|
|
* Using dst_addr (physical address) to store sig_pubkey_offset
|
|
* sig_pubkey_offset is Signature + Public Key Data
|
|
*/
|
|
sig_pubkey_offset = dst_addr;
|
|
|
|
if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) >
|
|
FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
|
|
src_size - data_size);
|
|
|
|
memset((void *) dst_addr, 0, *dst_size);
|
|
|
|
i += (src_size - data_size) / MBOX_WORD_BYTE;
|
|
}
|
|
|
|
status = mailbox_send_cmd_async(send_id,
|
|
MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
|
|
payload, i, CMD_INDIRECT);
|
|
|
|
if (is_finalised != 0U) {
|
|
memset((void *) &fcs_sha2_data_sig_verify_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;
|
|
}
|
|
|
|
int intel_fcs_ecdsa_get_pubkey_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_ecdsa_get_pubkey_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
|
|
uint64_t dst_addr, uint32_t *dst_size,
|
|
uint32_t *mbox_error)
|
|
{
|
|
int status;
|
|
int i;
|
|
uint32_t crypto_header;
|
|
uint32_t ret_size;
|
|
uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {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;
|
|
}
|
|
|
|
if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
|
|
fcs_ecdsa_get_pubkey_param.context_id != context_id) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
ret_size = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
|
|
FCS_CS_FIELD_FLAG_UPDATE |
|
|
FCS_CS_FIELD_FLAG_FINALIZE) <<
|
|
FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_ecdsa_get_pubkey_param.crypto_param_size;
|
|
i = 0;
|
|
/* Prepare command payload */
|
|
payload[i] = session_id;
|
|
i++;
|
|
payload[i] = context_id;
|
|
i++;
|
|
payload[i] = crypto_header;
|
|
i++;
|
|
payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
|
|
i++;
|
|
payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
|
|
INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
i++;
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
|
|
payload, i, CMD_CASUAL,
|
|
(uint32_t *) dst_addr, &ret_size);
|
|
|
|
memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
|
|
sizeof(fcs_crypto_service_data));
|
|
|
|
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_ecdh_request_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_ecdh_request_param,
|
|
mbox_error);
|
|
}
|
|
|
|
int intel_fcs_ecdh_request_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 payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
|
|
uint32_t resp_len;
|
|
uintptr_t pubkey;
|
|
uint32_t dst_size_check = 0;
|
|
|
|
if ((dst_size == NULL) || (mbox_error == NULL)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
|
|
if (fcs_ecdh_request_param.session_id != session_id ||
|
|
fcs_ecdh_request_param.context_id != context_id) {
|
|
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;
|
|
}
|
|
|
|
dst_size_check = *dst_size;
|
|
if ((dst_size_check > FCS_MAX_DATA_SIZE ||
|
|
dst_size_check < FCS_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_MAX_DATA_SIZE ||
|
|
src_size < FCS_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
resp_len = *dst_size / MBOX_WORD_BYTE;
|
|
|
|
/* Prepare command payload */
|
|
i = 0;
|
|
/* Crypto header */
|
|
payload[i] = fcs_ecdh_request_param.session_id;
|
|
i++;
|
|
payload[i] = fcs_ecdh_request_param.context_id;
|
|
i++;
|
|
payload[i] = fcs_ecdh_request_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_ecdh_request_param.key_id;
|
|
i++;
|
|
/* Crypto parameters */
|
|
payload[i] = fcs_ecdh_request_param.crypto_param
|
|
& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
|
|
i++;
|
|
/* Public key data */
|
|
pubkey = src_addr;
|
|
|
|
if ((i + ((src_size) / MBOX_WORD_BYTE)) >
|
|
FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
|
|
i += src_size / MBOX_WORD_BYTE;
|
|
|
|
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
|
|
payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
|
|
&resp_len);
|
|
|
|
memset((void *)&fcs_ecdh_request_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;
|
|
}
|
|
|
|
int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
|
|
uint32_t key_id, uint64_t param_addr,
|
|
uint32_t param_size, uint32_t *mbox_error)
|
|
{
|
|
/* ptr to get param_addr value */
|
|
uint64_t *param_addr_ptr;
|
|
|
|
param_addr_ptr = (uint64_t *) param_addr;
|
|
|
|
/* Check if mbox_error is not NULL or 0xF or 0x3FF */
|
|
if (mbox_error == NULL || *mbox_error > 0xF ||
|
|
(*mbox_error != 0 && *mbox_error != 0x3FF)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
/* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */
|
|
if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
/*
|
|
* Check if not ECB, CBC and CTR mode, addr ptr is NULL.
|
|
* Return "Reject" status
|
|
*/
|
|
if ((param_addr_ptr == NULL) ||
|
|
(((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
|
|
((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
|
|
((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE))) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
/*
|
|
* Since crypto param size vary between mode.
|
|
* Check CBC/CTR here and limit to size 28 bytes
|
|
*/
|
|
if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
|
|
((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
|
|
(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
/*
|
|
* Since crypto param size vary between mode.
|
|
* Check ECB here and limit to size 12 bytes
|
|
*/
|
|
if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
|
|
(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
|
|
|
|
fcs_aes_init_payload.session_id = session_id;
|
|
fcs_aes_init_payload.context_id = context_id;
|
|
fcs_aes_init_payload.param_size = param_size;
|
|
fcs_aes_init_payload.key_id = key_id;
|
|
|
|
memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
|
|
(uint8_t *) param_addr, param_size);
|
|
|
|
fcs_aes_init_payload.is_updated = 0;
|
|
|
|
*mbox_error = 0;
|
|
|
|
return INTEL_SIP_SMC_STATUS_OK;
|
|
}
|
|
|
|
int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
|
|
uint32_t context_id, uint64_t src_addr,
|
|
uint32_t src_size, uint64_t dst_addr,
|
|
uint32_t dst_size, uint8_t is_finalised,
|
|
uint32_t *send_id)
|
|
{
|
|
int status;
|
|
int i;
|
|
uint32_t flag;
|
|
uint32_t crypto_header;
|
|
uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
|
|
|
|
if (fcs_aes_init_payload.session_id != session_id ||
|
|
fcs_aes_init_payload.context_id != context_id) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if ((!is_8_bytes_aligned(src_addr)) ||
|
|
(!is_32_bytes_aligned(src_size)) ||
|
|
(!is_address_in_ddr_range(src_addr, src_size))) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if ((!is_8_bytes_aligned(dst_addr)) ||
|
|
(!is_32_bytes_aligned(dst_size)) ||
|
|
(!is_address_in_ddr_range(dst_addr, dst_size))) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
|
|
dst_size < FCS_AES_MIN_DATA_SIZE) ||
|
|
(src_size > FCS_AES_MAX_DATA_SIZE ||
|
|
src_size < FCS_AES_MIN_DATA_SIZE)) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
/* Prepare crypto header*/
|
|
flag = 0;
|
|
if (fcs_aes_init_payload.is_updated) {
|
|
fcs_aes_init_payload.param_size = 0;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_INIT;
|
|
}
|
|
|
|
if (is_finalised != 0U) {
|
|
flag |= FCS_CS_FIELD_FLAG_FINALIZE;
|
|
} else {
|
|
flag |= FCS_CS_FIELD_FLAG_UPDATE;
|
|
fcs_aes_init_payload.is_updated = 1;
|
|
}
|
|
crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
|
|
fcs_aes_init_payload.param_size;
|
|
|
|
i = 0U;
|
|
fcs_aes_crypt_payload[i] = session_id;
|
|
i++;
|
|
fcs_aes_crypt_payload[i] = context_id;
|
|
i++;
|
|
fcs_aes_crypt_payload[i] = crypto_header;
|
|
i++;
|
|
|
|
if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
|
|
FCS_CS_FIELD_FLAG_INIT) {
|
|
fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
|
|
i++;
|
|
|
|
if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) >
|
|
FCS_AES_CMD_MAX_WORD_SIZE) {
|
|
return INTEL_SIP_SMC_STATUS_REJECTED;
|
|
}
|
|
|
|
memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
|
|
(uint8_t *) fcs_aes_init_payload.crypto_param,
|
|
fcs_aes_init_payload.param_size);
|
|
|
|
i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
|
|
}
|
|
|
|
fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
|
|
i++;
|
|
fcs_aes_crypt_payload[i] = src_size;
|
|
i++;
|
|
fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
|
|
i++;
|
|
fcs_aes_crypt_payload[i] = dst_size;
|
|
i++;
|
|
|
|
status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
|
|
fcs_aes_crypt_payload, i,
|
|
CMD_INDIRECT);
|
|
|
|
if (is_finalised != 0U) {
|
|
memset((void *)&fcs_aes_init_payload, 0,
|
|
sizeof(fcs_aes_init_payload));
|
|
}
|
|
|
|
if (status < 0U) {
|
|
return INTEL_SIP_SMC_STATUS_ERROR;
|
|
}
|
|
|
|
return INTEL_SIP_SMC_STATUS_OK;
|
|
}
|