1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2020-2022, Intel Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <arch_helpers.h> 8*91f16700Schasinglulu #include <lib/mmio.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include "socfpga_fcs.h" 11*91f16700Schasinglulu #include "socfpga_mailbox.h" 12*91f16700Schasinglulu #include "socfpga_sip_svc.h" 13*91f16700Schasinglulu 14*91f16700Schasinglulu /* FCS static variables */ 15*91f16700Schasinglulu static fcs_crypto_service_aes_data fcs_aes_init_payload; 16*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha_get_digest_param; 17*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha_mac_verify_param; 18*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_hash_sign_param; 19*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param; 20*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha2_data_sign_param; 21*91f16700Schasinglulu static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; 22*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; 23*91f16700Schasinglulu static fcs_crypto_service_data fcs_ecdh_request_param; 24*91f16700Schasinglulu 25*91f16700Schasinglulu bool is_size_4_bytes_aligned(uint32_t size) 26*91f16700Schasinglulu { 27*91f16700Schasinglulu if ((size % MBOX_WORD_BYTE) != 0U) { 28*91f16700Schasinglulu return false; 29*91f16700Schasinglulu } else { 30*91f16700Schasinglulu return true; 31*91f16700Schasinglulu } 32*91f16700Schasinglulu } 33*91f16700Schasinglulu 34*91f16700Schasinglulu static bool is_8_bytes_aligned(uint32_t data) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) { 37*91f16700Schasinglulu return false; 38*91f16700Schasinglulu } else { 39*91f16700Schasinglulu return true; 40*91f16700Schasinglulu } 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu static bool is_32_bytes_aligned(uint32_t data) 44*91f16700Schasinglulu { 45*91f16700Schasinglulu if ((data % (8U * MBOX_WORD_BYTE)) != 0U) { 46*91f16700Schasinglulu return false; 47*91f16700Schasinglulu } else { 48*91f16700Schasinglulu return true; 49*91f16700Schasinglulu } 50*91f16700Schasinglulu } 51*91f16700Schasinglulu 52*91f16700Schasinglulu static int intel_fcs_crypto_service_init(uint32_t session_id, 53*91f16700Schasinglulu uint32_t context_id, uint32_t key_id, 54*91f16700Schasinglulu uint32_t param_size, uint64_t param_data, 55*91f16700Schasinglulu fcs_crypto_service_data *data_addr, 56*91f16700Schasinglulu uint32_t *mbox_error) 57*91f16700Schasinglulu { 58*91f16700Schasinglulu if (mbox_error == NULL) { 59*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 60*91f16700Schasinglulu } 61*91f16700Schasinglulu 62*91f16700Schasinglulu if (param_size != 4) { 63*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 64*91f16700Schasinglulu } 65*91f16700Schasinglulu 66*91f16700Schasinglulu memset(data_addr, 0, sizeof(fcs_crypto_service_data)); 67*91f16700Schasinglulu 68*91f16700Schasinglulu data_addr->session_id = session_id; 69*91f16700Schasinglulu data_addr->context_id = context_id; 70*91f16700Schasinglulu data_addr->key_id = key_id; 71*91f16700Schasinglulu data_addr->crypto_param_size = param_size; 72*91f16700Schasinglulu data_addr->crypto_param = param_data; 73*91f16700Schasinglulu 74*91f16700Schasinglulu data_addr->is_updated = 0; 75*91f16700Schasinglulu 76*91f16700Schasinglulu *mbox_error = 0; 77*91f16700Schasinglulu 78*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 82*91f16700Schasinglulu uint32_t *mbox_error) 83*91f16700Schasinglulu { 84*91f16700Schasinglulu int status; 85*91f16700Schasinglulu unsigned int i; 86*91f16700Schasinglulu unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 87*91f16700Schasinglulu uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 88*91f16700Schasinglulu 89*91f16700Schasinglulu if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 90*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 94*91f16700Schasinglulu CMD_CASUAL, random_data, &resp_len); 95*91f16700Schasinglulu 96*91f16700Schasinglulu if (status < 0) { 97*91f16700Schasinglulu *mbox_error = -status; 98*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 99*91f16700Schasinglulu } 100*91f16700Schasinglulu 101*91f16700Schasinglulu if (resp_len != FCS_RANDOM_WORD_SIZE) { 102*91f16700Schasinglulu *mbox_error = GENERIC_RESPONSE_ERROR; 103*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 104*91f16700Schasinglulu } 105*91f16700Schasinglulu 106*91f16700Schasinglulu *ret_size = FCS_RANDOM_BYTE_SIZE; 107*91f16700Schasinglulu 108*91f16700Schasinglulu for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 109*91f16700Schasinglulu mmio_write_32(addr, random_data[i]); 110*91f16700Schasinglulu addr += MBOX_WORD_BYTE; 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu flush_dcache_range(addr - *ret_size, *ret_size); 114*91f16700Schasinglulu 115*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 116*91f16700Schasinglulu } 117*91f16700Schasinglulu 118*91f16700Schasinglulu int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 119*91f16700Schasinglulu uint32_t size, uint32_t *send_id) 120*91f16700Schasinglulu { 121*91f16700Schasinglulu int status; 122*91f16700Schasinglulu uint32_t payload_size; 123*91f16700Schasinglulu uint32_t crypto_header; 124*91f16700Schasinglulu 125*91f16700Schasinglulu if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 126*91f16700Schasinglulu MBOX_WORD_BYTE) || size == 0U) { 127*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 128*91f16700Schasinglulu } 129*91f16700Schasinglulu 130*91f16700Schasinglulu if (!is_size_4_bytes_aligned(size)) { 131*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 132*91f16700Schasinglulu } 133*91f16700Schasinglulu 134*91f16700Schasinglulu crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 135*91f16700Schasinglulu FCS_CS_FIELD_FLAG_OFFSET; 136*91f16700Schasinglulu 137*91f16700Schasinglulu fcs_rng_payload payload = { 138*91f16700Schasinglulu session_id, 139*91f16700Schasinglulu context_id, 140*91f16700Schasinglulu crypto_header, 141*91f16700Schasinglulu size 142*91f16700Schasinglulu }; 143*91f16700Schasinglulu 144*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 145*91f16700Schasinglulu 146*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 147*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 148*91f16700Schasinglulu CMD_INDIRECT); 149*91f16700Schasinglulu 150*91f16700Schasinglulu if (status < 0) { 151*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 152*91f16700Schasinglulu } 153*91f16700Schasinglulu 154*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 155*91f16700Schasinglulu } 156*91f16700Schasinglulu 157*91f16700Schasinglulu uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size, 158*91f16700Schasinglulu uint32_t *send_id) 159*91f16700Schasinglulu { 160*91f16700Schasinglulu int status; 161*91f16700Schasinglulu 162*91f16700Schasinglulu if (!is_address_in_ddr_range(addr, size)) { 163*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 164*91f16700Schasinglulu } 165*91f16700Schasinglulu 166*91f16700Schasinglulu if (!is_size_4_bytes_aligned(size)) { 167*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 168*91f16700Schasinglulu } 169*91f16700Schasinglulu 170*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 171*91f16700Schasinglulu (uint32_t *)addr, size / MBOX_WORD_BYTE, 172*91f16700Schasinglulu CMD_DIRECT); 173*91f16700Schasinglulu 174*91f16700Schasinglulu flush_dcache_range(addr, size); 175*91f16700Schasinglulu 176*91f16700Schasinglulu if (status < 0) { 177*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 178*91f16700Schasinglulu } 179*91f16700Schasinglulu 180*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 181*91f16700Schasinglulu } 182*91f16700Schasinglulu 183*91f16700Schasinglulu uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 184*91f16700Schasinglulu { 185*91f16700Schasinglulu int status; 186*91f16700Schasinglulu 187*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 188*91f16700Schasinglulu NULL, 0U, CMD_DIRECT); 189*91f16700Schasinglulu 190*91f16700Schasinglulu if (status < 0) { 191*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 192*91f16700Schasinglulu } 193*91f16700Schasinglulu 194*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 195*91f16700Schasinglulu } 196*91f16700Schasinglulu 197*91f16700Schasinglulu uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value, 198*91f16700Schasinglulu uint32_t test_bit, uint32_t *mbox_error) 199*91f16700Schasinglulu { 200*91f16700Schasinglulu int status; 201*91f16700Schasinglulu uint32_t first_word; 202*91f16700Schasinglulu uint32_t payload_size; 203*91f16700Schasinglulu 204*91f16700Schasinglulu if ((test_bit != MBOX_TEST_BIT) && 205*91f16700Schasinglulu (test_bit != 0)) { 206*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 207*91f16700Schasinglulu } 208*91f16700Schasinglulu 209*91f16700Schasinglulu if ((counter_type < FCS_BIG_CNTR_SEL) || 210*91f16700Schasinglulu (counter_type > FCS_SVN_CNTR_3_SEL)) { 211*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 212*91f16700Schasinglulu } 213*91f16700Schasinglulu 214*91f16700Schasinglulu if ((counter_type == FCS_BIG_CNTR_SEL) && 215*91f16700Schasinglulu (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 216*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 217*91f16700Schasinglulu } 218*91f16700Schasinglulu 219*91f16700Schasinglulu if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 220*91f16700Schasinglulu (counter_type <= FCS_SVN_CNTR_3_SEL) && 221*91f16700Schasinglulu (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 222*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 223*91f16700Schasinglulu } 224*91f16700Schasinglulu 225*91f16700Schasinglulu first_word = test_bit | counter_type; 226*91f16700Schasinglulu fcs_cntr_set_preauth_payload payload = { 227*91f16700Schasinglulu first_word, 228*91f16700Schasinglulu counter_value 229*91f16700Schasinglulu }; 230*91f16700Schasinglulu 231*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 232*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 233*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 234*91f16700Schasinglulu CMD_CASUAL, NULL, NULL); 235*91f16700Schasinglulu 236*91f16700Schasinglulu if (status < 0) { 237*91f16700Schasinglulu *mbox_error = -status; 238*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 239*91f16700Schasinglulu } 240*91f16700Schasinglulu 241*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 242*91f16700Schasinglulu } 243*91f16700Schasinglulu 244*91f16700Schasinglulu uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 245*91f16700Schasinglulu uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 246*91f16700Schasinglulu { 247*91f16700Schasinglulu int status; 248*91f16700Schasinglulu uint32_t load_size; 249*91f16700Schasinglulu 250*91f16700Schasinglulu fcs_encrypt_payload payload = { 251*91f16700Schasinglulu FCS_ENCRYPTION_DATA_0, 252*91f16700Schasinglulu src_addr, 253*91f16700Schasinglulu src_size, 254*91f16700Schasinglulu dst_addr, 255*91f16700Schasinglulu dst_size }; 256*91f16700Schasinglulu load_size = sizeof(payload) / MBOX_WORD_BYTE; 257*91f16700Schasinglulu 258*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 259*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, dst_size)) { 260*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 261*91f16700Schasinglulu } 262*91f16700Schasinglulu 263*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size)) { 264*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 265*91f16700Schasinglulu } 266*91f16700Schasinglulu 267*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 268*91f16700Schasinglulu (uint32_t *) &payload, load_size, 269*91f16700Schasinglulu CMD_INDIRECT); 270*91f16700Schasinglulu inv_dcache_range(dst_addr, dst_size); 271*91f16700Schasinglulu 272*91f16700Schasinglulu if (status < 0) { 273*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 274*91f16700Schasinglulu } 275*91f16700Schasinglulu 276*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 277*91f16700Schasinglulu } 278*91f16700Schasinglulu 279*91f16700Schasinglulu uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 280*91f16700Schasinglulu uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 281*91f16700Schasinglulu { 282*91f16700Schasinglulu int status; 283*91f16700Schasinglulu uint32_t load_size; 284*91f16700Schasinglulu uintptr_t id_offset; 285*91f16700Schasinglulu 286*91f16700Schasinglulu inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 287*91f16700Schasinglulu id_offset = src_addr + FCS_OWNER_ID_OFFSET; 288*91f16700Schasinglulu fcs_decrypt_payload payload = { 289*91f16700Schasinglulu FCS_DECRYPTION_DATA_0, 290*91f16700Schasinglulu {mmio_read_32(id_offset), 291*91f16700Schasinglulu mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 292*91f16700Schasinglulu src_addr, 293*91f16700Schasinglulu src_size, 294*91f16700Schasinglulu dst_addr, 295*91f16700Schasinglulu dst_size }; 296*91f16700Schasinglulu load_size = sizeof(payload) / MBOX_WORD_BYTE; 297*91f16700Schasinglulu 298*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 299*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, dst_size)) { 300*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 301*91f16700Schasinglulu } 302*91f16700Schasinglulu 303*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size)) { 304*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 305*91f16700Schasinglulu } 306*91f16700Schasinglulu 307*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 308*91f16700Schasinglulu (uint32_t *) &payload, load_size, 309*91f16700Schasinglulu CMD_INDIRECT); 310*91f16700Schasinglulu inv_dcache_range(dst_addr, dst_size); 311*91f16700Schasinglulu 312*91f16700Schasinglulu if (status < 0) { 313*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 314*91f16700Schasinglulu } 315*91f16700Schasinglulu 316*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 317*91f16700Schasinglulu } 318*91f16700Schasinglulu 319*91f16700Schasinglulu int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id, 320*91f16700Schasinglulu uint32_t src_addr, uint32_t src_size, 321*91f16700Schasinglulu uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 322*91f16700Schasinglulu { 323*91f16700Schasinglulu int status; 324*91f16700Schasinglulu uint32_t payload_size; 325*91f16700Schasinglulu uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 326*91f16700Schasinglulu uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 327*91f16700Schasinglulu 328*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 329*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 330*91f16700Schasinglulu } 331*91f16700Schasinglulu 332*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 333*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 334*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 335*91f16700Schasinglulu } 336*91f16700Schasinglulu 337*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size)) { 338*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 339*91f16700Schasinglulu } 340*91f16700Schasinglulu 341*91f16700Schasinglulu fcs_encrypt_ext_payload payload = { 342*91f16700Schasinglulu session_id, 343*91f16700Schasinglulu context_id, 344*91f16700Schasinglulu FCS_CRYPTION_CRYPTO_HEADER, 345*91f16700Schasinglulu src_addr, 346*91f16700Schasinglulu src_size, 347*91f16700Schasinglulu dst_addr, 348*91f16700Schasinglulu *dst_size 349*91f16700Schasinglulu }; 350*91f16700Schasinglulu 351*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 352*91f16700Schasinglulu 353*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 354*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 355*91f16700Schasinglulu CMD_CASUAL, resp_data, &resp_len); 356*91f16700Schasinglulu 357*91f16700Schasinglulu if (status < 0) { 358*91f16700Schasinglulu *mbox_error = -status; 359*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 360*91f16700Schasinglulu } 361*91f16700Schasinglulu 362*91f16700Schasinglulu if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 363*91f16700Schasinglulu *mbox_error = MBOX_RET_ERROR; 364*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 365*91f16700Schasinglulu } 366*91f16700Schasinglulu 367*91f16700Schasinglulu *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 368*91f16700Schasinglulu inv_dcache_range(dst_addr, *dst_size); 369*91f16700Schasinglulu 370*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 371*91f16700Schasinglulu } 372*91f16700Schasinglulu 373*91f16700Schasinglulu int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id, 374*91f16700Schasinglulu uint32_t src_addr, uint32_t src_size, 375*91f16700Schasinglulu uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 376*91f16700Schasinglulu { 377*91f16700Schasinglulu int status; 378*91f16700Schasinglulu uintptr_t id_offset; 379*91f16700Schasinglulu uint32_t payload_size; 380*91f16700Schasinglulu uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 381*91f16700Schasinglulu uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 382*91f16700Schasinglulu 383*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 384*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 385*91f16700Schasinglulu } 386*91f16700Schasinglulu 387*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 388*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 389*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 390*91f16700Schasinglulu } 391*91f16700Schasinglulu 392*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size)) { 393*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 394*91f16700Schasinglulu } 395*91f16700Schasinglulu 396*91f16700Schasinglulu inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 397*91f16700Schasinglulu id_offset = src_addr + FCS_OWNER_ID_OFFSET; 398*91f16700Schasinglulu fcs_decrypt_ext_payload payload = { 399*91f16700Schasinglulu session_id, 400*91f16700Schasinglulu context_id, 401*91f16700Schasinglulu FCS_CRYPTION_CRYPTO_HEADER, 402*91f16700Schasinglulu {mmio_read_32(id_offset), 403*91f16700Schasinglulu mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 404*91f16700Schasinglulu src_addr, 405*91f16700Schasinglulu src_size, 406*91f16700Schasinglulu dst_addr, 407*91f16700Schasinglulu *dst_size 408*91f16700Schasinglulu }; 409*91f16700Schasinglulu 410*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 411*91f16700Schasinglulu 412*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 413*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 414*91f16700Schasinglulu CMD_CASUAL, resp_data, &resp_len); 415*91f16700Schasinglulu 416*91f16700Schasinglulu if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 || 417*91f16700Schasinglulu status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) { 418*91f16700Schasinglulu *mbox_error = -status; 419*91f16700Schasinglulu } else if (status < 0) { 420*91f16700Schasinglulu *mbox_error = -status; 421*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 422*91f16700Schasinglulu } 423*91f16700Schasinglulu 424*91f16700Schasinglulu if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 425*91f16700Schasinglulu *mbox_error = MBOX_RET_ERROR; 426*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 427*91f16700Schasinglulu } 428*91f16700Schasinglulu 429*91f16700Schasinglulu *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 430*91f16700Schasinglulu inv_dcache_range(dst_addr, *dst_size); 431*91f16700Schasinglulu 432*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 433*91f16700Schasinglulu } 434*91f16700Schasinglulu 435*91f16700Schasinglulu int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 436*91f16700Schasinglulu { 437*91f16700Schasinglulu int status; 438*91f16700Schasinglulu 439*91f16700Schasinglulu if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 440*91f16700Schasinglulu (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 441*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 442*91f16700Schasinglulu } 443*91f16700Schasinglulu 444*91f16700Schasinglulu psgsigma_teardown_msg message = { 445*91f16700Schasinglulu RESERVED_AS_ZERO, 446*91f16700Schasinglulu PSGSIGMA_TEARDOWN_MAGIC, 447*91f16700Schasinglulu session_id 448*91f16700Schasinglulu }; 449*91f16700Schasinglulu 450*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 451*91f16700Schasinglulu (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 452*91f16700Schasinglulu CMD_CASUAL, NULL, NULL); 453*91f16700Schasinglulu 454*91f16700Schasinglulu if (status < 0) { 455*91f16700Schasinglulu *mbox_error = -status; 456*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 457*91f16700Schasinglulu } 458*91f16700Schasinglulu 459*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 460*91f16700Schasinglulu } 461*91f16700Schasinglulu 462*91f16700Schasinglulu int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 463*91f16700Schasinglulu { 464*91f16700Schasinglulu int status; 465*91f16700Schasinglulu uint32_t load_size; 466*91f16700Schasinglulu uint32_t chip_id[2]; 467*91f16700Schasinglulu 468*91f16700Schasinglulu load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 469*91f16700Schasinglulu 470*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 471*91f16700Schasinglulu 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 472*91f16700Schasinglulu 473*91f16700Schasinglulu if (status < 0) { 474*91f16700Schasinglulu *mbox_error = -status; 475*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 476*91f16700Schasinglulu } 477*91f16700Schasinglulu 478*91f16700Schasinglulu *id_low = chip_id[0]; 479*91f16700Schasinglulu *id_high = chip_id[1]; 480*91f16700Schasinglulu 481*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 482*91f16700Schasinglulu } 483*91f16700Schasinglulu 484*91f16700Schasinglulu int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 485*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 486*91f16700Schasinglulu { 487*91f16700Schasinglulu int status; 488*91f16700Schasinglulu uint32_t send_size = src_size / MBOX_WORD_BYTE; 489*91f16700Schasinglulu uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 490*91f16700Schasinglulu 491*91f16700Schasinglulu 492*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 493*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 494*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 495*91f16700Schasinglulu } 496*91f16700Schasinglulu 497*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 498*91f16700Schasinglulu (uint32_t *) src_addr, send_size, CMD_CASUAL, 499*91f16700Schasinglulu (uint32_t *) dst_addr, &ret_size); 500*91f16700Schasinglulu 501*91f16700Schasinglulu if (status < 0) { 502*91f16700Schasinglulu *mbox_error = -status; 503*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 504*91f16700Schasinglulu } 505*91f16700Schasinglulu 506*91f16700Schasinglulu *dst_size = ret_size * MBOX_WORD_BYTE; 507*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 508*91f16700Schasinglulu 509*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 510*91f16700Schasinglulu } 511*91f16700Schasinglulu 512*91f16700Schasinglulu int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 513*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 514*91f16700Schasinglulu { 515*91f16700Schasinglulu int status; 516*91f16700Schasinglulu uint32_t send_size = src_size / MBOX_WORD_BYTE; 517*91f16700Schasinglulu uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 518*91f16700Schasinglulu 519*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 520*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 521*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 522*91f16700Schasinglulu } 523*91f16700Schasinglulu 524*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 525*91f16700Schasinglulu (uint32_t *) src_addr, send_size, CMD_CASUAL, 526*91f16700Schasinglulu (uint32_t *) dst_addr, &ret_size); 527*91f16700Schasinglulu 528*91f16700Schasinglulu if (status < 0) { 529*91f16700Schasinglulu *mbox_error = -status; 530*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 531*91f16700Schasinglulu } 532*91f16700Schasinglulu 533*91f16700Schasinglulu *dst_size = ret_size * MBOX_WORD_BYTE; 534*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 535*91f16700Schasinglulu 536*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 537*91f16700Schasinglulu } 538*91f16700Schasinglulu 539*91f16700Schasinglulu uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 540*91f16700Schasinglulu uint32_t *mbox_error) 541*91f16700Schasinglulu { 542*91f16700Schasinglulu int status; 543*91f16700Schasinglulu unsigned int resp_len = FCS_SHA384_WORD_SIZE; 544*91f16700Schasinglulu 545*91f16700Schasinglulu if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 546*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 547*91f16700Schasinglulu } 548*91f16700Schasinglulu 549*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 550*91f16700Schasinglulu CMD_CASUAL, (uint32_t *) addr, &resp_len); 551*91f16700Schasinglulu 552*91f16700Schasinglulu if (status < 0) { 553*91f16700Schasinglulu *mbox_error = -status; 554*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 555*91f16700Schasinglulu } 556*91f16700Schasinglulu 557*91f16700Schasinglulu if (resp_len != FCS_SHA384_WORD_SIZE) { 558*91f16700Schasinglulu *mbox_error = GENERIC_RESPONSE_ERROR; 559*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 560*91f16700Schasinglulu } 561*91f16700Schasinglulu 562*91f16700Schasinglulu *ret_size = FCS_SHA384_BYTE_SIZE; 563*91f16700Schasinglulu 564*91f16700Schasinglulu flush_dcache_range(addr, *ret_size); 565*91f16700Schasinglulu 566*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 567*91f16700Schasinglulu } 568*91f16700Schasinglulu 569*91f16700Schasinglulu int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr, 570*91f16700Schasinglulu uint32_t *dst_size, uint32_t *mbox_error) 571*91f16700Schasinglulu { 572*91f16700Schasinglulu int status; 573*91f16700Schasinglulu uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 574*91f16700Schasinglulu 575*91f16700Schasinglulu if (mbox_error == NULL) { 576*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 577*91f16700Schasinglulu } 578*91f16700Schasinglulu 579*91f16700Schasinglulu if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 580*91f16700Schasinglulu cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 581*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 582*91f16700Schasinglulu } 583*91f16700Schasinglulu 584*91f16700Schasinglulu if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 585*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 586*91f16700Schasinglulu } 587*91f16700Schasinglulu 588*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 589*91f16700Schasinglulu (uint32_t *) &cert_request, 1U, CMD_CASUAL, 590*91f16700Schasinglulu (uint32_t *) dst_addr, &ret_size); 591*91f16700Schasinglulu 592*91f16700Schasinglulu if (status < 0) { 593*91f16700Schasinglulu *mbox_error = -status; 594*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 595*91f16700Schasinglulu } 596*91f16700Schasinglulu 597*91f16700Schasinglulu *dst_size = ret_size * MBOX_WORD_BYTE; 598*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 599*91f16700Schasinglulu 600*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 601*91f16700Schasinglulu } 602*91f16700Schasinglulu 603*91f16700Schasinglulu int intel_fcs_create_cert_on_reload(uint32_t cert_request, 604*91f16700Schasinglulu uint32_t *mbox_error) 605*91f16700Schasinglulu { 606*91f16700Schasinglulu int status; 607*91f16700Schasinglulu 608*91f16700Schasinglulu if (mbox_error == NULL) { 609*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 610*91f16700Schasinglulu } 611*91f16700Schasinglulu 612*91f16700Schasinglulu if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 613*91f16700Schasinglulu cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 614*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 615*91f16700Schasinglulu } 616*91f16700Schasinglulu 617*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 618*91f16700Schasinglulu (uint32_t *) &cert_request, 1U, CMD_CASUAL, 619*91f16700Schasinglulu NULL, NULL); 620*91f16700Schasinglulu 621*91f16700Schasinglulu if (status < 0) { 622*91f16700Schasinglulu *mbox_error = -status; 623*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 624*91f16700Schasinglulu } 625*91f16700Schasinglulu 626*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 627*91f16700Schasinglulu } 628*91f16700Schasinglulu 629*91f16700Schasinglulu int intel_fcs_open_crypto_service_session(uint32_t *session_id, 630*91f16700Schasinglulu uint32_t *mbox_error) 631*91f16700Schasinglulu { 632*91f16700Schasinglulu int status; 633*91f16700Schasinglulu uint32_t resp_len = 1U; 634*91f16700Schasinglulu 635*91f16700Schasinglulu if ((session_id == NULL) || (mbox_error == NULL)) { 636*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 637*91f16700Schasinglulu } 638*91f16700Schasinglulu 639*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 640*91f16700Schasinglulu NULL, 0U, CMD_CASUAL, session_id, &resp_len); 641*91f16700Schasinglulu 642*91f16700Schasinglulu if (status < 0) { 643*91f16700Schasinglulu *mbox_error = -status; 644*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 645*91f16700Schasinglulu } 646*91f16700Schasinglulu 647*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 648*91f16700Schasinglulu } 649*91f16700Schasinglulu 650*91f16700Schasinglulu int intel_fcs_close_crypto_service_session(uint32_t session_id, 651*91f16700Schasinglulu uint32_t *mbox_error) 652*91f16700Schasinglulu { 653*91f16700Schasinglulu int status; 654*91f16700Schasinglulu 655*91f16700Schasinglulu if (mbox_error == NULL) { 656*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 657*91f16700Schasinglulu } 658*91f16700Schasinglulu 659*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 660*91f16700Schasinglulu &session_id, 1U, CMD_CASUAL, NULL, NULL); 661*91f16700Schasinglulu 662*91f16700Schasinglulu if (status < 0) { 663*91f16700Schasinglulu *mbox_error = -status; 664*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 665*91f16700Schasinglulu } 666*91f16700Schasinglulu 667*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 668*91f16700Schasinglulu } 669*91f16700Schasinglulu 670*91f16700Schasinglulu int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 671*91f16700Schasinglulu uint32_t *send_id) 672*91f16700Schasinglulu { 673*91f16700Schasinglulu int status; 674*91f16700Schasinglulu 675*91f16700Schasinglulu if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 676*91f16700Schasinglulu MBOX_WORD_BYTE)) { 677*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 678*91f16700Schasinglulu } 679*91f16700Schasinglulu 680*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size)) { 681*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 682*91f16700Schasinglulu } 683*91f16700Schasinglulu 684*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 685*91f16700Schasinglulu (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 686*91f16700Schasinglulu CMD_INDIRECT); 687*91f16700Schasinglulu 688*91f16700Schasinglulu if (status < 0) { 689*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 690*91f16700Schasinglulu } 691*91f16700Schasinglulu 692*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 693*91f16700Schasinglulu } 694*91f16700Schasinglulu 695*91f16700Schasinglulu int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 696*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 697*91f16700Schasinglulu uint32_t *mbox_error) 698*91f16700Schasinglulu { 699*91f16700Schasinglulu int status; 700*91f16700Schasinglulu uint32_t i; 701*91f16700Schasinglulu uint32_t payload_size; 702*91f16700Schasinglulu uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 703*91f16700Schasinglulu uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 704*91f16700Schasinglulu uint32_t op_status = 0U; 705*91f16700Schasinglulu 706*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 707*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 708*91f16700Schasinglulu } 709*91f16700Schasinglulu 710*91f16700Schasinglulu if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 711*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 712*91f16700Schasinglulu } 713*91f16700Schasinglulu 714*91f16700Schasinglulu fcs_cs_key_payload payload = { 715*91f16700Schasinglulu session_id, 716*91f16700Schasinglulu RESERVED_AS_ZERO, 717*91f16700Schasinglulu RESERVED_AS_ZERO, 718*91f16700Schasinglulu key_id 719*91f16700Schasinglulu }; 720*91f16700Schasinglulu 721*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 722*91f16700Schasinglulu 723*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 724*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 725*91f16700Schasinglulu CMD_CASUAL, resp_data, &resp_len); 726*91f16700Schasinglulu 727*91f16700Schasinglulu if (resp_len > 0) { 728*91f16700Schasinglulu op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 729*91f16700Schasinglulu } 730*91f16700Schasinglulu 731*91f16700Schasinglulu if (status < 0) { 732*91f16700Schasinglulu *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 733*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 734*91f16700Schasinglulu } 735*91f16700Schasinglulu 736*91f16700Schasinglulu if (resp_len > 1) { 737*91f16700Schasinglulu 738*91f16700Schasinglulu /* Export key object is start at second response data */ 739*91f16700Schasinglulu *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 740*91f16700Schasinglulu 741*91f16700Schasinglulu for (i = 1U; i < resp_len; i++) { 742*91f16700Schasinglulu mmio_write_32(dst_addr, resp_data[i]); 743*91f16700Schasinglulu dst_addr += MBOX_WORD_BYTE; 744*91f16700Schasinglulu } 745*91f16700Schasinglulu 746*91f16700Schasinglulu flush_dcache_range(dst_addr - *dst_size, *dst_size); 747*91f16700Schasinglulu 748*91f16700Schasinglulu } else { 749*91f16700Schasinglulu 750*91f16700Schasinglulu /* Unexpected response, missing key object in response */ 751*91f16700Schasinglulu *mbox_error = MBOX_RET_ERROR; 752*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 753*91f16700Schasinglulu } 754*91f16700Schasinglulu 755*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 756*91f16700Schasinglulu } 757*91f16700Schasinglulu 758*91f16700Schasinglulu int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 759*91f16700Schasinglulu uint32_t *mbox_error) 760*91f16700Schasinglulu { 761*91f16700Schasinglulu int status; 762*91f16700Schasinglulu uint32_t payload_size; 763*91f16700Schasinglulu uint32_t resp_len = 1U; 764*91f16700Schasinglulu uint32_t resp_data = 0U; 765*91f16700Schasinglulu uint32_t op_status = 0U; 766*91f16700Schasinglulu 767*91f16700Schasinglulu if (mbox_error == NULL) { 768*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 769*91f16700Schasinglulu } 770*91f16700Schasinglulu 771*91f16700Schasinglulu fcs_cs_key_payload payload = { 772*91f16700Schasinglulu session_id, 773*91f16700Schasinglulu RESERVED_AS_ZERO, 774*91f16700Schasinglulu RESERVED_AS_ZERO, 775*91f16700Schasinglulu key_id 776*91f16700Schasinglulu }; 777*91f16700Schasinglulu 778*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 779*91f16700Schasinglulu 780*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 781*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 782*91f16700Schasinglulu CMD_CASUAL, &resp_data, &resp_len); 783*91f16700Schasinglulu 784*91f16700Schasinglulu if (resp_len > 0) { 785*91f16700Schasinglulu op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 786*91f16700Schasinglulu } 787*91f16700Schasinglulu 788*91f16700Schasinglulu if (status < 0) { 789*91f16700Schasinglulu *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 790*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 791*91f16700Schasinglulu } 792*91f16700Schasinglulu 793*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 794*91f16700Schasinglulu } 795*91f16700Schasinglulu 796*91f16700Schasinglulu int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 797*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 798*91f16700Schasinglulu uint32_t *mbox_error) 799*91f16700Schasinglulu { 800*91f16700Schasinglulu int status; 801*91f16700Schasinglulu uint32_t payload_size; 802*91f16700Schasinglulu uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 803*91f16700Schasinglulu uint32_t op_status = 0U; 804*91f16700Schasinglulu 805*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 806*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 807*91f16700Schasinglulu } 808*91f16700Schasinglulu 809*91f16700Schasinglulu if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 810*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 811*91f16700Schasinglulu } 812*91f16700Schasinglulu 813*91f16700Schasinglulu fcs_cs_key_payload payload = { 814*91f16700Schasinglulu session_id, 815*91f16700Schasinglulu RESERVED_AS_ZERO, 816*91f16700Schasinglulu RESERVED_AS_ZERO, 817*91f16700Schasinglulu key_id 818*91f16700Schasinglulu }; 819*91f16700Schasinglulu 820*91f16700Schasinglulu payload_size = sizeof(payload) / MBOX_WORD_BYTE; 821*91f16700Schasinglulu 822*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 823*91f16700Schasinglulu (uint32_t *) &payload, payload_size, 824*91f16700Schasinglulu CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 825*91f16700Schasinglulu 826*91f16700Schasinglulu if (resp_len > 0) { 827*91f16700Schasinglulu inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */ 828*91f16700Schasinglulu op_status = mmio_read_32(dst_addr) & 829*91f16700Schasinglulu FCS_CS_KEY_RESP_STATUS_MASK; 830*91f16700Schasinglulu } 831*91f16700Schasinglulu 832*91f16700Schasinglulu if (status < 0) { 833*91f16700Schasinglulu *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 834*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 835*91f16700Schasinglulu } 836*91f16700Schasinglulu 837*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 838*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 839*91f16700Schasinglulu 840*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 841*91f16700Schasinglulu } 842*91f16700Schasinglulu 843*91f16700Schasinglulu int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 844*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 845*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 846*91f16700Schasinglulu { 847*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 848*91f16700Schasinglulu key_id, param_size, param_data, 849*91f16700Schasinglulu (void *) &fcs_sha_get_digest_param, 850*91f16700Schasinglulu mbox_error); 851*91f16700Schasinglulu } 852*91f16700Schasinglulu 853*91f16700Schasinglulu int intel_fcs_get_digest_update_finalize(uint32_t session_id, 854*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 855*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 856*91f16700Schasinglulu uint32_t *dst_size, uint8_t is_finalised, 857*91f16700Schasinglulu uint32_t *mbox_error) 858*91f16700Schasinglulu { 859*91f16700Schasinglulu int status; 860*91f16700Schasinglulu uint32_t i; 861*91f16700Schasinglulu uint32_t flag; 862*91f16700Schasinglulu uint32_t crypto_header; 863*91f16700Schasinglulu uint32_t resp_len; 864*91f16700Schasinglulu uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 865*91f16700Schasinglulu 866*91f16700Schasinglulu if (dst_size == NULL || mbox_error == NULL) { 867*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 868*91f16700Schasinglulu } 869*91f16700Schasinglulu 870*91f16700Schasinglulu if (fcs_sha_get_digest_param.session_id != session_id || 871*91f16700Schasinglulu fcs_sha_get_digest_param.context_id != context_id) { 872*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 873*91f16700Schasinglulu } 874*91f16700Schasinglulu 875*91f16700Schasinglulu /* Source data must be 8 bytes aligned */ 876*91f16700Schasinglulu if (!is_8_bytes_aligned(src_size)) { 877*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 878*91f16700Schasinglulu } 879*91f16700Schasinglulu 880*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 881*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 882*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 883*91f16700Schasinglulu } 884*91f16700Schasinglulu 885*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 886*91f16700Schasinglulu 887*91f16700Schasinglulu /* Prepare crypto header */ 888*91f16700Schasinglulu flag = 0; 889*91f16700Schasinglulu 890*91f16700Schasinglulu if (fcs_sha_get_digest_param.is_updated) { 891*91f16700Schasinglulu fcs_sha_get_digest_param.crypto_param_size = 0; 892*91f16700Schasinglulu } else { 893*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 894*91f16700Schasinglulu } 895*91f16700Schasinglulu 896*91f16700Schasinglulu if (is_finalised != 0U) { 897*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 898*91f16700Schasinglulu } else { 899*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 900*91f16700Schasinglulu fcs_sha_get_digest_param.is_updated = 1; 901*91f16700Schasinglulu } 902*91f16700Schasinglulu 903*91f16700Schasinglulu crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 904*91f16700Schasinglulu (fcs_sha_get_digest_param.crypto_param_size & 905*91f16700Schasinglulu FCS_CS_FIELD_SIZE_MASK)); 906*91f16700Schasinglulu 907*91f16700Schasinglulu /* Prepare command payload */ 908*91f16700Schasinglulu i = 0; 909*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.session_id; 910*91f16700Schasinglulu i++; 911*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.context_id; 912*91f16700Schasinglulu i++; 913*91f16700Schasinglulu payload[i] = crypto_header; 914*91f16700Schasinglulu i++; 915*91f16700Schasinglulu 916*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 917*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 918*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.key_id; 919*91f16700Schasinglulu i++; 920*91f16700Schasinglulu /* Crypto parameters */ 921*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.crypto_param 922*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 923*91f16700Schasinglulu payload[i] |= ((fcs_sha_get_digest_param.crypto_param 924*91f16700Schasinglulu >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 925*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 926*91f16700Schasinglulu << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 927*91f16700Schasinglulu i++; 928*91f16700Schasinglulu } 929*91f16700Schasinglulu /* Data source address and size */ 930*91f16700Schasinglulu payload[i] = src_addr; 931*91f16700Schasinglulu i++; 932*91f16700Schasinglulu payload[i] = src_size; 933*91f16700Schasinglulu i++; 934*91f16700Schasinglulu 935*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 936*91f16700Schasinglulu payload, i, CMD_CASUAL, 937*91f16700Schasinglulu (uint32_t *) dst_addr, &resp_len); 938*91f16700Schasinglulu 939*91f16700Schasinglulu if (is_finalised != 0U) { 940*91f16700Schasinglulu memset((void *)&fcs_sha_get_digest_param, 0, 941*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 942*91f16700Schasinglulu } 943*91f16700Schasinglulu 944*91f16700Schasinglulu if (status < 0) { 945*91f16700Schasinglulu *mbox_error = -status; 946*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 947*91f16700Schasinglulu } 948*91f16700Schasinglulu 949*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 950*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 951*91f16700Schasinglulu 952*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 953*91f16700Schasinglulu } 954*91f16700Schasinglulu 955*91f16700Schasinglulu int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 956*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 957*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 958*91f16700Schasinglulu uint32_t *dst_size, uint8_t is_finalised, 959*91f16700Schasinglulu uint32_t *mbox_error, uint32_t *send_id) 960*91f16700Schasinglulu { 961*91f16700Schasinglulu int status; 962*91f16700Schasinglulu uint32_t i; 963*91f16700Schasinglulu uint32_t flag; 964*91f16700Schasinglulu uint32_t crypto_header; 965*91f16700Schasinglulu uint32_t resp_len; 966*91f16700Schasinglulu uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 967*91f16700Schasinglulu 968*91f16700Schasinglulu /* Source data must be 8 bytes aligned */ 969*91f16700Schasinglulu if (dst_size == NULL || mbox_error == NULL || 970*91f16700Schasinglulu !is_8_bytes_aligned(src_size)) { 971*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 972*91f16700Schasinglulu } 973*91f16700Schasinglulu 974*91f16700Schasinglulu if (fcs_sha_get_digest_param.session_id != session_id || 975*91f16700Schasinglulu fcs_sha_get_digest_param.context_id != context_id) { 976*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 977*91f16700Schasinglulu } 978*91f16700Schasinglulu 979*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 980*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 981*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 982*91f16700Schasinglulu } 983*91f16700Schasinglulu 984*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 985*91f16700Schasinglulu 986*91f16700Schasinglulu /* Prepare crypto header */ 987*91f16700Schasinglulu flag = 0; 988*91f16700Schasinglulu 989*91f16700Schasinglulu if (fcs_sha_get_digest_param.is_updated) { 990*91f16700Schasinglulu fcs_sha_get_digest_param.crypto_param_size = 0; 991*91f16700Schasinglulu } else { 992*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 993*91f16700Schasinglulu } 994*91f16700Schasinglulu 995*91f16700Schasinglulu if (is_finalised != 0U) { 996*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 997*91f16700Schasinglulu } else { 998*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 999*91f16700Schasinglulu fcs_sha_get_digest_param.is_updated = 1; 1000*91f16700Schasinglulu } 1001*91f16700Schasinglulu 1002*91f16700Schasinglulu crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1003*91f16700Schasinglulu (fcs_sha_get_digest_param.crypto_param_size & 1004*91f16700Schasinglulu FCS_CS_FIELD_SIZE_MASK)); 1005*91f16700Schasinglulu 1006*91f16700Schasinglulu /* Prepare command payload */ 1007*91f16700Schasinglulu i = 0; 1008*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.session_id; 1009*91f16700Schasinglulu i++; 1010*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.context_id; 1011*91f16700Schasinglulu i++; 1012*91f16700Schasinglulu payload[i] = crypto_header; 1013*91f16700Schasinglulu i++; 1014*91f16700Schasinglulu 1015*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1016*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1017*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.key_id; 1018*91f16700Schasinglulu i++; 1019*91f16700Schasinglulu /* Crypto parameters */ 1020*91f16700Schasinglulu payload[i] = fcs_sha_get_digest_param.crypto_param 1021*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1022*91f16700Schasinglulu payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1023*91f16700Schasinglulu >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1024*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1025*91f16700Schasinglulu << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1026*91f16700Schasinglulu i++; 1027*91f16700Schasinglulu } 1028*91f16700Schasinglulu /* Data source address and size */ 1029*91f16700Schasinglulu payload[i] = src_addr; 1030*91f16700Schasinglulu i++; 1031*91f16700Schasinglulu payload[i] = src_size; 1032*91f16700Schasinglulu i++; 1033*91f16700Schasinglulu 1034*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1035*91f16700Schasinglulu payload, i, CMD_INDIRECT); 1036*91f16700Schasinglulu 1037*91f16700Schasinglulu if (is_finalised != 0U) { 1038*91f16700Schasinglulu memset((void *)&fcs_sha_get_digest_param, 0, 1039*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1040*91f16700Schasinglulu } 1041*91f16700Schasinglulu 1042*91f16700Schasinglulu if (status < 0) { 1043*91f16700Schasinglulu *mbox_error = -status; 1044*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1045*91f16700Schasinglulu } 1046*91f16700Schasinglulu 1047*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1048*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1049*91f16700Schasinglulu 1050*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1051*91f16700Schasinglulu } 1052*91f16700Schasinglulu 1053*91f16700Schasinglulu int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1054*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 1055*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 1056*91f16700Schasinglulu { 1057*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 1058*91f16700Schasinglulu key_id, param_size, param_data, 1059*91f16700Schasinglulu (void *) &fcs_sha_mac_verify_param, 1060*91f16700Schasinglulu mbox_error); 1061*91f16700Schasinglulu } 1062*91f16700Schasinglulu 1063*91f16700Schasinglulu int intel_fcs_mac_verify_update_finalize(uint32_t session_id, 1064*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1065*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1066*91f16700Schasinglulu uint32_t *dst_size, uint32_t data_size, 1067*91f16700Schasinglulu uint8_t is_finalised, uint32_t *mbox_error) 1068*91f16700Schasinglulu { 1069*91f16700Schasinglulu int status; 1070*91f16700Schasinglulu uint32_t i; 1071*91f16700Schasinglulu uint32_t flag; 1072*91f16700Schasinglulu uint32_t crypto_header; 1073*91f16700Schasinglulu uint32_t resp_len; 1074*91f16700Schasinglulu uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1075*91f16700Schasinglulu uintptr_t mac_offset; 1076*91f16700Schasinglulu uint32_t dst_size_check = 0; 1077*91f16700Schasinglulu 1078*91f16700Schasinglulu if (dst_size == NULL || mbox_error == NULL) { 1079*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1080*91f16700Schasinglulu } 1081*91f16700Schasinglulu 1082*91f16700Schasinglulu if (fcs_sha_mac_verify_param.session_id != session_id || 1083*91f16700Schasinglulu fcs_sha_mac_verify_param.context_id != context_id) { 1084*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1085*91f16700Schasinglulu } 1086*91f16700Schasinglulu 1087*91f16700Schasinglulu if (data_size > src_size) { 1088*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1089*91f16700Schasinglulu } 1090*91f16700Schasinglulu 1091*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size) || 1092*91f16700Schasinglulu !is_8_bytes_aligned(data_size)) { 1093*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1094*91f16700Schasinglulu } 1095*91f16700Schasinglulu 1096*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1097*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1098*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1099*91f16700Schasinglulu } 1100*91f16700Schasinglulu 1101*91f16700Schasinglulu dst_size_check = *dst_size; 1102*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1103*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1104*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1105*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1106*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1107*91f16700Schasinglulu } 1108*91f16700Schasinglulu 1109*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1110*91f16700Schasinglulu 1111*91f16700Schasinglulu /* Prepare crypto header */ 1112*91f16700Schasinglulu flag = 0; 1113*91f16700Schasinglulu 1114*91f16700Schasinglulu if (fcs_sha_mac_verify_param.is_updated) { 1115*91f16700Schasinglulu fcs_sha_mac_verify_param.crypto_param_size = 0; 1116*91f16700Schasinglulu } else { 1117*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1118*91f16700Schasinglulu } 1119*91f16700Schasinglulu 1120*91f16700Schasinglulu if (is_finalised) { 1121*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1122*91f16700Schasinglulu } else { 1123*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1124*91f16700Schasinglulu fcs_sha_mac_verify_param.is_updated = 1; 1125*91f16700Schasinglulu } 1126*91f16700Schasinglulu 1127*91f16700Schasinglulu crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1128*91f16700Schasinglulu (fcs_sha_mac_verify_param.crypto_param_size & 1129*91f16700Schasinglulu FCS_CS_FIELD_SIZE_MASK)); 1130*91f16700Schasinglulu 1131*91f16700Schasinglulu /* Prepare command payload */ 1132*91f16700Schasinglulu i = 0; 1133*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.session_id; 1134*91f16700Schasinglulu i++; 1135*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.context_id; 1136*91f16700Schasinglulu i++; 1137*91f16700Schasinglulu payload[i] = crypto_header; 1138*91f16700Schasinglulu i++; 1139*91f16700Schasinglulu 1140*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1141*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1142*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.key_id; 1143*91f16700Schasinglulu i++; 1144*91f16700Schasinglulu /* Crypto parameters */ 1145*91f16700Schasinglulu payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1146*91f16700Schasinglulu >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1147*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1148*91f16700Schasinglulu << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1149*91f16700Schasinglulu i++; 1150*91f16700Schasinglulu } 1151*91f16700Schasinglulu /* Data source address and size */ 1152*91f16700Schasinglulu payload[i] = src_addr; 1153*91f16700Schasinglulu i++; 1154*91f16700Schasinglulu payload[i] = data_size; 1155*91f16700Schasinglulu i++; 1156*91f16700Schasinglulu 1157*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1158*91f16700Schasinglulu FCS_CS_FIELD_FLAG_FINALIZE) { 1159*91f16700Schasinglulu /* Copy mac data to command */ 1160*91f16700Schasinglulu mac_offset = src_addr + data_size; 1161*91f16700Schasinglulu 1162*91f16700Schasinglulu if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1163*91f16700Schasinglulu FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1164*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1165*91f16700Schasinglulu } 1166*91f16700Schasinglulu 1167*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1168*91f16700Schasinglulu src_size - data_size); 1169*91f16700Schasinglulu 1170*91f16700Schasinglulu i += (src_size - data_size) / MBOX_WORD_BYTE; 1171*91f16700Schasinglulu } 1172*91f16700Schasinglulu 1173*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1174*91f16700Schasinglulu payload, i, CMD_CASUAL, 1175*91f16700Schasinglulu (uint32_t *) dst_addr, &resp_len); 1176*91f16700Schasinglulu 1177*91f16700Schasinglulu if (is_finalised) { 1178*91f16700Schasinglulu memset((void *)&fcs_sha_mac_verify_param, 0, 1179*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1180*91f16700Schasinglulu } 1181*91f16700Schasinglulu 1182*91f16700Schasinglulu if (status < 0) { 1183*91f16700Schasinglulu *mbox_error = -status; 1184*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1185*91f16700Schasinglulu } 1186*91f16700Schasinglulu 1187*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1188*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1189*91f16700Schasinglulu 1190*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1191*91f16700Schasinglulu } 1192*91f16700Schasinglulu 1193*91f16700Schasinglulu int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1194*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1195*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1196*91f16700Schasinglulu uint32_t *dst_size, uint32_t data_size, 1197*91f16700Schasinglulu uint8_t is_finalised, uint32_t *mbox_error, 1198*91f16700Schasinglulu uint32_t *send_id) 1199*91f16700Schasinglulu { 1200*91f16700Schasinglulu int status; 1201*91f16700Schasinglulu uint32_t i; 1202*91f16700Schasinglulu uint32_t flag; 1203*91f16700Schasinglulu uint32_t crypto_header; 1204*91f16700Schasinglulu uint32_t resp_len; 1205*91f16700Schasinglulu uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1206*91f16700Schasinglulu uintptr_t mac_offset; 1207*91f16700Schasinglulu uint32_t dst_size_check = 0; 1208*91f16700Schasinglulu /* 1209*91f16700Schasinglulu * Source data must be 4 bytes aligned 1210*91f16700Schasinglulu * User data must be 8 bytes aligned 1211*91f16700Schasinglulu */ 1212*91f16700Schasinglulu if (dst_size == NULL || mbox_error == NULL || 1213*91f16700Schasinglulu !is_size_4_bytes_aligned(src_size) || 1214*91f16700Schasinglulu !is_8_bytes_aligned(data_size)) { 1215*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1216*91f16700Schasinglulu } 1217*91f16700Schasinglulu 1218*91f16700Schasinglulu if (data_size > src_size) { 1219*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1220*91f16700Schasinglulu } 1221*91f16700Schasinglulu 1222*91f16700Schasinglulu if (fcs_sha_mac_verify_param.session_id != session_id || 1223*91f16700Schasinglulu fcs_sha_mac_verify_param.context_id != context_id) { 1224*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1225*91f16700Schasinglulu } 1226*91f16700Schasinglulu 1227*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1228*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1229*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1230*91f16700Schasinglulu } 1231*91f16700Schasinglulu 1232*91f16700Schasinglulu dst_size_check = *dst_size; 1233*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1234*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1235*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1236*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1237*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1238*91f16700Schasinglulu } 1239*91f16700Schasinglulu 1240*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1241*91f16700Schasinglulu 1242*91f16700Schasinglulu /* Prepare crypto header */ 1243*91f16700Schasinglulu flag = 0; 1244*91f16700Schasinglulu 1245*91f16700Schasinglulu if (fcs_sha_mac_verify_param.is_updated) { 1246*91f16700Schasinglulu fcs_sha_mac_verify_param.crypto_param_size = 0; 1247*91f16700Schasinglulu } else { 1248*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1249*91f16700Schasinglulu } 1250*91f16700Schasinglulu 1251*91f16700Schasinglulu if (is_finalised) { 1252*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1253*91f16700Schasinglulu } else { 1254*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1255*91f16700Schasinglulu fcs_sha_mac_verify_param.is_updated = 1; 1256*91f16700Schasinglulu } 1257*91f16700Schasinglulu 1258*91f16700Schasinglulu crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1259*91f16700Schasinglulu (fcs_sha_mac_verify_param.crypto_param_size & 1260*91f16700Schasinglulu FCS_CS_FIELD_SIZE_MASK)); 1261*91f16700Schasinglulu 1262*91f16700Schasinglulu /* Prepare command payload */ 1263*91f16700Schasinglulu i = 0; 1264*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.session_id; 1265*91f16700Schasinglulu i++; 1266*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.context_id; 1267*91f16700Schasinglulu i++; 1268*91f16700Schasinglulu payload[i] = crypto_header; 1269*91f16700Schasinglulu i++; 1270*91f16700Schasinglulu 1271*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1272*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1273*91f16700Schasinglulu payload[i] = fcs_sha_mac_verify_param.key_id; 1274*91f16700Schasinglulu i++; 1275*91f16700Schasinglulu /* Crypto parameters */ 1276*91f16700Schasinglulu payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1277*91f16700Schasinglulu >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1278*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1279*91f16700Schasinglulu << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1280*91f16700Schasinglulu i++; 1281*91f16700Schasinglulu } 1282*91f16700Schasinglulu /* Data source address and size */ 1283*91f16700Schasinglulu payload[i] = src_addr; 1284*91f16700Schasinglulu i++; 1285*91f16700Schasinglulu payload[i] = data_size; 1286*91f16700Schasinglulu i++; 1287*91f16700Schasinglulu 1288*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1289*91f16700Schasinglulu FCS_CS_FIELD_FLAG_FINALIZE) { 1290*91f16700Schasinglulu /* Copy mac data to command 1291*91f16700Schasinglulu * Using dst_addr (physical address) to store mac_offset 1292*91f16700Schasinglulu * mac_offset = MAC data 1293*91f16700Schasinglulu */ 1294*91f16700Schasinglulu mac_offset = dst_addr; 1295*91f16700Schasinglulu 1296*91f16700Schasinglulu if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1297*91f16700Schasinglulu FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1298*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1299*91f16700Schasinglulu } 1300*91f16700Schasinglulu 1301*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset, 1302*91f16700Schasinglulu src_size - data_size); 1303*91f16700Schasinglulu 1304*91f16700Schasinglulu memset((void *) dst_addr, 0, *dst_size); 1305*91f16700Schasinglulu 1306*91f16700Schasinglulu i += (src_size - data_size) / MBOX_WORD_BYTE; 1307*91f16700Schasinglulu } 1308*91f16700Schasinglulu 1309*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1310*91f16700Schasinglulu payload, i, CMD_INDIRECT); 1311*91f16700Schasinglulu 1312*91f16700Schasinglulu if (is_finalised) { 1313*91f16700Schasinglulu memset((void *)&fcs_sha_mac_verify_param, 0, 1314*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1315*91f16700Schasinglulu } 1316*91f16700Schasinglulu 1317*91f16700Schasinglulu if (status < 0) { 1318*91f16700Schasinglulu *mbox_error = -status; 1319*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1320*91f16700Schasinglulu } 1321*91f16700Schasinglulu 1322*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1323*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1324*91f16700Schasinglulu 1325*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1326*91f16700Schasinglulu } 1327*91f16700Schasinglulu 1328*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1329*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 1330*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 1331*91f16700Schasinglulu { 1332*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 1333*91f16700Schasinglulu key_id, param_size, param_data, 1334*91f16700Schasinglulu (void *) &fcs_ecdsa_hash_sign_param, 1335*91f16700Schasinglulu mbox_error); 1336*91f16700Schasinglulu } 1337*91f16700Schasinglulu 1338*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id, 1339*91f16700Schasinglulu uint32_t src_addr, uint32_t src_size, 1340*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 1341*91f16700Schasinglulu uint32_t *mbox_error) 1342*91f16700Schasinglulu { 1343*91f16700Schasinglulu int status; 1344*91f16700Schasinglulu uint32_t i; 1345*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1346*91f16700Schasinglulu uint32_t resp_len; 1347*91f16700Schasinglulu uintptr_t hash_data_addr; 1348*91f16700Schasinglulu uint32_t dst_size_check = 0; 1349*91f16700Schasinglulu 1350*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 1351*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1352*91f16700Schasinglulu } 1353*91f16700Schasinglulu 1354*91f16700Schasinglulu if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1355*91f16700Schasinglulu fcs_ecdsa_hash_sign_param.context_id != context_id) { 1356*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1357*91f16700Schasinglulu } 1358*91f16700Schasinglulu 1359*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1360*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1361*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1362*91f16700Schasinglulu } 1363*91f16700Schasinglulu 1364*91f16700Schasinglulu dst_size_check = *dst_size; 1365*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1366*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1367*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1368*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1369*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1370*91f16700Schasinglulu } 1371*91f16700Schasinglulu 1372*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1373*91f16700Schasinglulu 1374*91f16700Schasinglulu /* Prepare command payload */ 1375*91f16700Schasinglulu /* Crypto header */ 1376*91f16700Schasinglulu i = 0; 1377*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1378*91f16700Schasinglulu i++; 1379*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1380*91f16700Schasinglulu 1381*91f16700Schasinglulu i++; 1382*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1383*91f16700Schasinglulu & FCS_CS_FIELD_SIZE_MASK; 1384*91f16700Schasinglulu payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1385*91f16700Schasinglulu | FCS_CS_FIELD_FLAG_FINALIZE) 1386*91f16700Schasinglulu << FCS_CS_FIELD_FLAG_OFFSET; 1387*91f16700Schasinglulu i++; 1388*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1389*91f16700Schasinglulu 1390*91f16700Schasinglulu /* Crypto parameters */ 1391*91f16700Schasinglulu i++; 1392*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1393*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1394*91f16700Schasinglulu 1395*91f16700Schasinglulu /* Hash Data */ 1396*91f16700Schasinglulu i++; 1397*91f16700Schasinglulu hash_data_addr = src_addr; 1398*91f16700Schasinglulu 1399*91f16700Schasinglulu if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1400*91f16700Schasinglulu FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) { 1401*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1402*91f16700Schasinglulu } 1403*91f16700Schasinglulu 1404*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr, 1405*91f16700Schasinglulu src_size); 1406*91f16700Schasinglulu 1407*91f16700Schasinglulu i += src_size / MBOX_WORD_BYTE; 1408*91f16700Schasinglulu 1409*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1410*91f16700Schasinglulu payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1411*91f16700Schasinglulu &resp_len); 1412*91f16700Schasinglulu 1413*91f16700Schasinglulu memset((void *) &fcs_ecdsa_hash_sign_param, 1414*91f16700Schasinglulu 0, sizeof(fcs_crypto_service_data)); 1415*91f16700Schasinglulu 1416*91f16700Schasinglulu if (status < 0) { 1417*91f16700Schasinglulu *mbox_error = -status; 1418*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1419*91f16700Schasinglulu } 1420*91f16700Schasinglulu 1421*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1422*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1423*91f16700Schasinglulu 1424*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1425*91f16700Schasinglulu } 1426*91f16700Schasinglulu 1427*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1428*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 1429*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 1430*91f16700Schasinglulu { 1431*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 1432*91f16700Schasinglulu key_id, param_size, param_data, 1433*91f16700Schasinglulu (void *) &fcs_ecdsa_hash_sig_verify_param, 1434*91f16700Schasinglulu mbox_error); 1435*91f16700Schasinglulu } 1436*91f16700Schasinglulu 1437*91f16700Schasinglulu int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id, 1438*91f16700Schasinglulu uint32_t src_addr, uint32_t src_size, 1439*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 1440*91f16700Schasinglulu uint32_t *mbox_error) 1441*91f16700Schasinglulu { 1442*91f16700Schasinglulu int status; 1443*91f16700Schasinglulu uint32_t i = 0; 1444*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1445*91f16700Schasinglulu uint32_t resp_len; 1446*91f16700Schasinglulu uintptr_t hash_sig_pubkey_addr; 1447*91f16700Schasinglulu uint32_t dst_size_check = 0; 1448*91f16700Schasinglulu 1449*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 1450*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1451*91f16700Schasinglulu } 1452*91f16700Schasinglulu 1453*91f16700Schasinglulu if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id || 1454*91f16700Schasinglulu fcs_ecdsa_hash_sig_verify_param.context_id != context_id) { 1455*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1456*91f16700Schasinglulu } 1457*91f16700Schasinglulu 1458*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1459*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1460*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1461*91f16700Schasinglulu } 1462*91f16700Schasinglulu 1463*91f16700Schasinglulu dst_size_check = *dst_size; 1464*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1465*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1466*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1467*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1468*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1469*91f16700Schasinglulu } 1470*91f16700Schasinglulu 1471*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1472*91f16700Schasinglulu 1473*91f16700Schasinglulu /* Prepare command payload */ 1474*91f16700Schasinglulu /* Crypto header */ 1475*91f16700Schasinglulu i = 0; 1476*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1477*91f16700Schasinglulu 1478*91f16700Schasinglulu i++; 1479*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1480*91f16700Schasinglulu 1481*91f16700Schasinglulu i++; 1482*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1483*91f16700Schasinglulu & FCS_CS_FIELD_SIZE_MASK; 1484*91f16700Schasinglulu payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1485*91f16700Schasinglulu | FCS_CS_FIELD_FLAG_FINALIZE) 1486*91f16700Schasinglulu << FCS_CS_FIELD_FLAG_OFFSET; 1487*91f16700Schasinglulu 1488*91f16700Schasinglulu i++; 1489*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1490*91f16700Schasinglulu 1491*91f16700Schasinglulu /* Crypto parameters */ 1492*91f16700Schasinglulu i++; 1493*91f16700Schasinglulu payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1494*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1495*91f16700Schasinglulu 1496*91f16700Schasinglulu /* Hash Data Word, Signature Data Word and Public Key Data word */ 1497*91f16700Schasinglulu i++; 1498*91f16700Schasinglulu hash_sig_pubkey_addr = src_addr; 1499*91f16700Schasinglulu 1500*91f16700Schasinglulu if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1501*91f16700Schasinglulu FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1502*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1503*91f16700Schasinglulu } 1504*91f16700Schasinglulu 1505*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], 1506*91f16700Schasinglulu (uint8_t *) hash_sig_pubkey_addr, src_size); 1507*91f16700Schasinglulu 1508*91f16700Schasinglulu i += (src_size / MBOX_WORD_BYTE); 1509*91f16700Schasinglulu 1510*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1511*91f16700Schasinglulu payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1512*91f16700Schasinglulu &resp_len); 1513*91f16700Schasinglulu 1514*91f16700Schasinglulu memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1515*91f16700Schasinglulu 0, sizeof(fcs_crypto_service_data)); 1516*91f16700Schasinglulu 1517*91f16700Schasinglulu if (status < 0) { 1518*91f16700Schasinglulu *mbox_error = -status; 1519*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1520*91f16700Schasinglulu } 1521*91f16700Schasinglulu 1522*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1523*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1524*91f16700Schasinglulu 1525*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1526*91f16700Schasinglulu } 1527*91f16700Schasinglulu 1528*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1529*91f16700Schasinglulu uint32_t context_id, uint32_t key_id, 1530*91f16700Schasinglulu uint32_t param_size, uint64_t param_data, 1531*91f16700Schasinglulu uint32_t *mbox_error) 1532*91f16700Schasinglulu { 1533*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 1534*91f16700Schasinglulu key_id, param_size, param_data, 1535*91f16700Schasinglulu (void *) &fcs_sha2_data_sign_param, 1536*91f16700Schasinglulu mbox_error); 1537*91f16700Schasinglulu } 1538*91f16700Schasinglulu 1539*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id, 1540*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1541*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1542*91f16700Schasinglulu uint32_t *dst_size, uint8_t is_finalised, 1543*91f16700Schasinglulu uint32_t *mbox_error) 1544*91f16700Schasinglulu { 1545*91f16700Schasinglulu int status; 1546*91f16700Schasinglulu int i; 1547*91f16700Schasinglulu uint32_t flag; 1548*91f16700Schasinglulu uint32_t crypto_header; 1549*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1550*91f16700Schasinglulu uint32_t resp_len; 1551*91f16700Schasinglulu 1552*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 1553*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1554*91f16700Schasinglulu } 1555*91f16700Schasinglulu 1556*91f16700Schasinglulu if (fcs_sha2_data_sign_param.session_id != session_id || 1557*91f16700Schasinglulu fcs_sha2_data_sign_param.context_id != context_id) { 1558*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1559*91f16700Schasinglulu } 1560*91f16700Schasinglulu 1561*91f16700Schasinglulu /* Source data must be 8 bytes aligned */ 1562*91f16700Schasinglulu if (!is_8_bytes_aligned(src_size)) { 1563*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1564*91f16700Schasinglulu } 1565*91f16700Schasinglulu 1566*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1567*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1568*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1569*91f16700Schasinglulu } 1570*91f16700Schasinglulu 1571*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1572*91f16700Schasinglulu 1573*91f16700Schasinglulu /* Prepare crypto header */ 1574*91f16700Schasinglulu flag = 0; 1575*91f16700Schasinglulu if (fcs_sha2_data_sign_param.is_updated) { 1576*91f16700Schasinglulu fcs_sha2_data_sign_param.crypto_param_size = 0; 1577*91f16700Schasinglulu } else { 1578*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1579*91f16700Schasinglulu } 1580*91f16700Schasinglulu 1581*91f16700Schasinglulu if (is_finalised != 0U) { 1582*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1583*91f16700Schasinglulu } else { 1584*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1585*91f16700Schasinglulu fcs_sha2_data_sign_param.is_updated = 1; 1586*91f16700Schasinglulu } 1587*91f16700Schasinglulu crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1588*91f16700Schasinglulu fcs_sha2_data_sign_param.crypto_param_size; 1589*91f16700Schasinglulu 1590*91f16700Schasinglulu /* Prepare command payload */ 1591*91f16700Schasinglulu i = 0; 1592*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.session_id; 1593*91f16700Schasinglulu i++; 1594*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.context_id; 1595*91f16700Schasinglulu i++; 1596*91f16700Schasinglulu payload[i] = crypto_header; 1597*91f16700Schasinglulu i++; 1598*91f16700Schasinglulu 1599*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1600*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1601*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.key_id; 1602*91f16700Schasinglulu /* Crypto parameters */ 1603*91f16700Schasinglulu i++; 1604*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.crypto_param 1605*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1606*91f16700Schasinglulu i++; 1607*91f16700Schasinglulu } 1608*91f16700Schasinglulu 1609*91f16700Schasinglulu /* Data source address and size */ 1610*91f16700Schasinglulu payload[i] = src_addr; 1611*91f16700Schasinglulu i++; 1612*91f16700Schasinglulu payload[i] = src_size; 1613*91f16700Schasinglulu i++; 1614*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, 1615*91f16700Schasinglulu MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 1616*91f16700Schasinglulu i, CMD_CASUAL, (uint32_t *) dst_addr, 1617*91f16700Schasinglulu &resp_len); 1618*91f16700Schasinglulu 1619*91f16700Schasinglulu if (is_finalised != 0U) { 1620*91f16700Schasinglulu memset((void *)&fcs_sha2_data_sign_param, 0, 1621*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1622*91f16700Schasinglulu } 1623*91f16700Schasinglulu 1624*91f16700Schasinglulu if (status < 0) { 1625*91f16700Schasinglulu *mbox_error = -status; 1626*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1627*91f16700Schasinglulu } 1628*91f16700Schasinglulu 1629*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1630*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1631*91f16700Schasinglulu 1632*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1633*91f16700Schasinglulu } 1634*91f16700Schasinglulu 1635*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 1636*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1637*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1638*91f16700Schasinglulu uint32_t *dst_size, uint8_t is_finalised, 1639*91f16700Schasinglulu uint32_t *mbox_error, uint32_t *send_id) 1640*91f16700Schasinglulu { 1641*91f16700Schasinglulu int status; 1642*91f16700Schasinglulu int i; 1643*91f16700Schasinglulu uint32_t flag; 1644*91f16700Schasinglulu uint32_t crypto_header; 1645*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1646*91f16700Schasinglulu uint32_t resp_len; 1647*91f16700Schasinglulu 1648*91f16700Schasinglulu /* Source data must be 8 bytes aligned */ 1649*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL || 1650*91f16700Schasinglulu !is_8_bytes_aligned(src_size))) { 1651*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1652*91f16700Schasinglulu } 1653*91f16700Schasinglulu 1654*91f16700Schasinglulu if (fcs_sha2_data_sign_param.session_id != session_id || 1655*91f16700Schasinglulu fcs_sha2_data_sign_param.context_id != context_id) { 1656*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1657*91f16700Schasinglulu } 1658*91f16700Schasinglulu 1659*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1660*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1661*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1662*91f16700Schasinglulu } 1663*91f16700Schasinglulu 1664*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1665*91f16700Schasinglulu 1666*91f16700Schasinglulu /* Prepare crypto header */ 1667*91f16700Schasinglulu flag = 0; 1668*91f16700Schasinglulu if (fcs_sha2_data_sign_param.is_updated) { 1669*91f16700Schasinglulu fcs_sha2_data_sign_param.crypto_param_size = 0; 1670*91f16700Schasinglulu } else { 1671*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1672*91f16700Schasinglulu } 1673*91f16700Schasinglulu 1674*91f16700Schasinglulu if (is_finalised != 0U) { 1675*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1676*91f16700Schasinglulu } else { 1677*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1678*91f16700Schasinglulu fcs_sha2_data_sign_param.is_updated = 1; 1679*91f16700Schasinglulu } 1680*91f16700Schasinglulu crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1681*91f16700Schasinglulu fcs_sha2_data_sign_param.crypto_param_size; 1682*91f16700Schasinglulu 1683*91f16700Schasinglulu /* Prepare command payload */ 1684*91f16700Schasinglulu i = 0; 1685*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.session_id; 1686*91f16700Schasinglulu i++; 1687*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.context_id; 1688*91f16700Schasinglulu i++; 1689*91f16700Schasinglulu payload[i] = crypto_header; 1690*91f16700Schasinglulu i++; 1691*91f16700Schasinglulu 1692*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1693*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1694*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.key_id; 1695*91f16700Schasinglulu /* Crypto parameters */ 1696*91f16700Schasinglulu i++; 1697*91f16700Schasinglulu payload[i] = fcs_sha2_data_sign_param.crypto_param 1698*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1699*91f16700Schasinglulu i++; 1700*91f16700Schasinglulu } 1701*91f16700Schasinglulu 1702*91f16700Schasinglulu /* Data source address and size */ 1703*91f16700Schasinglulu payload[i] = src_addr; 1704*91f16700Schasinglulu i++; 1705*91f16700Schasinglulu payload[i] = src_size; 1706*91f16700Schasinglulu i++; 1707*91f16700Schasinglulu 1708*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, 1709*91f16700Schasinglulu MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 1710*91f16700Schasinglulu payload, i, CMD_INDIRECT); 1711*91f16700Schasinglulu 1712*91f16700Schasinglulu if (is_finalised != 0U) { 1713*91f16700Schasinglulu memset((void *)&fcs_sha2_data_sign_param, 0, 1714*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1715*91f16700Schasinglulu } 1716*91f16700Schasinglulu 1717*91f16700Schasinglulu if (status < 0) { 1718*91f16700Schasinglulu *mbox_error = -status; 1719*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1720*91f16700Schasinglulu } 1721*91f16700Schasinglulu 1722*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1723*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1724*91f16700Schasinglulu 1725*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1726*91f16700Schasinglulu } 1727*91f16700Schasinglulu 1728*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 1729*91f16700Schasinglulu uint32_t context_id, uint32_t key_id, 1730*91f16700Schasinglulu uint32_t param_size, uint64_t param_data, 1731*91f16700Schasinglulu uint32_t *mbox_error) 1732*91f16700Schasinglulu { 1733*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 1734*91f16700Schasinglulu key_id, param_size, param_data, 1735*91f16700Schasinglulu (void *) &fcs_sha2_data_sig_verify_param, 1736*91f16700Schasinglulu mbox_error); 1737*91f16700Schasinglulu } 1738*91f16700Schasinglulu 1739*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id, 1740*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1741*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1742*91f16700Schasinglulu uint32_t *dst_size, uint32_t data_size, 1743*91f16700Schasinglulu uint8_t is_finalised, uint32_t *mbox_error) 1744*91f16700Schasinglulu { 1745*91f16700Schasinglulu int status; 1746*91f16700Schasinglulu uint32_t i; 1747*91f16700Schasinglulu uint32_t flag; 1748*91f16700Schasinglulu uint32_t crypto_header; 1749*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1750*91f16700Schasinglulu uint32_t resp_len; 1751*91f16700Schasinglulu uintptr_t sig_pubkey_offset; 1752*91f16700Schasinglulu uint32_t dst_size_check = 0; 1753*91f16700Schasinglulu 1754*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 1755*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1756*91f16700Schasinglulu } 1757*91f16700Schasinglulu 1758*91f16700Schasinglulu if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1759*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.context_id != context_id) { 1760*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1761*91f16700Schasinglulu } 1762*91f16700Schasinglulu 1763*91f16700Schasinglulu if (data_size > src_size) { 1764*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1765*91f16700Schasinglulu } 1766*91f16700Schasinglulu 1767*91f16700Schasinglulu if (!is_size_4_bytes_aligned(src_size)) { 1768*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1769*91f16700Schasinglulu } 1770*91f16700Schasinglulu 1771*91f16700Schasinglulu if (!is_8_bytes_aligned(data_size) || 1772*91f16700Schasinglulu !is_8_bytes_aligned(src_addr)) { 1773*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1774*91f16700Schasinglulu } 1775*91f16700Schasinglulu 1776*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1777*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1778*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1779*91f16700Schasinglulu } 1780*91f16700Schasinglulu 1781*91f16700Schasinglulu dst_size_check = *dst_size; 1782*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1783*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1784*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1785*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1786*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1787*91f16700Schasinglulu } 1788*91f16700Schasinglulu 1789*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1790*91f16700Schasinglulu 1791*91f16700Schasinglulu /* Prepare crypto header */ 1792*91f16700Schasinglulu flag = 0; 1793*91f16700Schasinglulu if (fcs_sha2_data_sig_verify_param.is_updated) 1794*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1795*91f16700Schasinglulu else 1796*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1797*91f16700Schasinglulu 1798*91f16700Schasinglulu if (is_finalised != 0U) 1799*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1800*91f16700Schasinglulu else { 1801*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1802*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.is_updated = 1; 1803*91f16700Schasinglulu } 1804*91f16700Schasinglulu crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1805*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.crypto_param_size; 1806*91f16700Schasinglulu 1807*91f16700Schasinglulu /* Prepare command payload */ 1808*91f16700Schasinglulu i = 0; 1809*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1810*91f16700Schasinglulu i++; 1811*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1812*91f16700Schasinglulu i++; 1813*91f16700Schasinglulu payload[i] = crypto_header; 1814*91f16700Schasinglulu i++; 1815*91f16700Schasinglulu 1816*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1817*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1818*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1819*91f16700Schasinglulu i++; 1820*91f16700Schasinglulu /* Crypto parameters */ 1821*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1822*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1823*91f16700Schasinglulu i++; 1824*91f16700Schasinglulu } 1825*91f16700Schasinglulu 1826*91f16700Schasinglulu /* Data source address and size */ 1827*91f16700Schasinglulu payload[i] = src_addr; 1828*91f16700Schasinglulu i++; 1829*91f16700Schasinglulu payload[i] = data_size; 1830*91f16700Schasinglulu i++; 1831*91f16700Schasinglulu 1832*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1833*91f16700Schasinglulu FCS_CS_FIELD_FLAG_FINALIZE) { 1834*91f16700Schasinglulu /* Signature + Public Key Data */ 1835*91f16700Schasinglulu sig_pubkey_offset = src_addr + data_size; 1836*91f16700Schasinglulu 1837*91f16700Schasinglulu if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1838*91f16700Schasinglulu FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1839*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1840*91f16700Schasinglulu } 1841*91f16700Schasinglulu 1842*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1843*91f16700Schasinglulu src_size - data_size); 1844*91f16700Schasinglulu 1845*91f16700Schasinglulu i += (src_size - data_size) / MBOX_WORD_BYTE; 1846*91f16700Schasinglulu } 1847*91f16700Schasinglulu 1848*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, 1849*91f16700Schasinglulu MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 1850*91f16700Schasinglulu CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1851*91f16700Schasinglulu 1852*91f16700Schasinglulu if (is_finalised != 0U) { 1853*91f16700Schasinglulu memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1854*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1855*91f16700Schasinglulu } 1856*91f16700Schasinglulu 1857*91f16700Schasinglulu if (status < 0) { 1858*91f16700Schasinglulu *mbox_error = -status; 1859*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1860*91f16700Schasinglulu } 1861*91f16700Schasinglulu 1862*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1863*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1864*91f16700Schasinglulu 1865*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 1866*91f16700Schasinglulu } 1867*91f16700Schasinglulu 1868*91f16700Schasinglulu int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 1869*91f16700Schasinglulu uint32_t context_id, uint32_t src_addr, 1870*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 1871*91f16700Schasinglulu uint32_t *dst_size, uint32_t data_size, 1872*91f16700Schasinglulu uint8_t is_finalised, uint32_t *mbox_error, 1873*91f16700Schasinglulu uint32_t *send_id) 1874*91f16700Schasinglulu { 1875*91f16700Schasinglulu int status; 1876*91f16700Schasinglulu uint32_t i; 1877*91f16700Schasinglulu uint32_t flag; 1878*91f16700Schasinglulu uint32_t crypto_header; 1879*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1880*91f16700Schasinglulu uint32_t resp_len; 1881*91f16700Schasinglulu uintptr_t sig_pubkey_offset; 1882*91f16700Schasinglulu uint32_t dst_size_check = 0; 1883*91f16700Schasinglulu 1884*91f16700Schasinglulu /* 1885*91f16700Schasinglulu * Source data must be 4 bytes aligned 1886*91f16700Schasinglulu * Source address must be 8 bytes aligned 1887*91f16700Schasinglulu * User data must be 8 bytes aligned 1888*91f16700Schasinglulu */ 1889*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL) || 1890*91f16700Schasinglulu !is_size_4_bytes_aligned(src_size) || 1891*91f16700Schasinglulu !is_8_bytes_aligned(src_addr) || 1892*91f16700Schasinglulu !is_8_bytes_aligned(data_size)) { 1893*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1894*91f16700Schasinglulu } 1895*91f16700Schasinglulu 1896*91f16700Schasinglulu if (fcs_sha2_data_sig_verify_param.session_id != session_id || 1897*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.context_id != context_id) { 1898*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1899*91f16700Schasinglulu } 1900*91f16700Schasinglulu 1901*91f16700Schasinglulu if (data_size > src_size) { 1902*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1903*91f16700Schasinglulu } 1904*91f16700Schasinglulu 1905*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 1906*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 1907*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1908*91f16700Schasinglulu } 1909*91f16700Schasinglulu 1910*91f16700Schasinglulu dst_size_check = *dst_size; 1911*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 1912*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 1913*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 1914*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 1915*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1916*91f16700Schasinglulu } 1917*91f16700Schasinglulu 1918*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 1919*91f16700Schasinglulu 1920*91f16700Schasinglulu /* Prepare crypto header */ 1921*91f16700Schasinglulu flag = 0; 1922*91f16700Schasinglulu if (fcs_sha2_data_sig_verify_param.is_updated) 1923*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 1924*91f16700Schasinglulu else 1925*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 1926*91f16700Schasinglulu 1927*91f16700Schasinglulu if (is_finalised != 0U) 1928*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1929*91f16700Schasinglulu else { 1930*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 1931*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.is_updated = 1; 1932*91f16700Schasinglulu } 1933*91f16700Schasinglulu crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1934*91f16700Schasinglulu fcs_sha2_data_sig_verify_param.crypto_param_size; 1935*91f16700Schasinglulu 1936*91f16700Schasinglulu /* Prepare command payload */ 1937*91f16700Schasinglulu i = 0; 1938*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.session_id; 1939*91f16700Schasinglulu i++; 1940*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.context_id; 1941*91f16700Schasinglulu i++; 1942*91f16700Schasinglulu payload[i] = crypto_header; 1943*91f16700Schasinglulu i++; 1944*91f16700Schasinglulu 1945*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1946*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 1947*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.key_id; 1948*91f16700Schasinglulu i++; 1949*91f16700Schasinglulu /* Crypto parameters */ 1950*91f16700Schasinglulu payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 1951*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1952*91f16700Schasinglulu i++; 1953*91f16700Schasinglulu } 1954*91f16700Schasinglulu 1955*91f16700Schasinglulu /* Data source address and size */ 1956*91f16700Schasinglulu payload[i] = src_addr; 1957*91f16700Schasinglulu i++; 1958*91f16700Schasinglulu payload[i] = data_size; 1959*91f16700Schasinglulu i++; 1960*91f16700Schasinglulu 1961*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1962*91f16700Schasinglulu FCS_CS_FIELD_FLAG_FINALIZE) { 1963*91f16700Schasinglulu /* Copy mac data to command 1964*91f16700Schasinglulu * Using dst_addr (physical address) to store sig_pubkey_offset 1965*91f16700Schasinglulu * sig_pubkey_offset is Signature + Public Key Data 1966*91f16700Schasinglulu */ 1967*91f16700Schasinglulu sig_pubkey_offset = dst_addr; 1968*91f16700Schasinglulu 1969*91f16700Schasinglulu if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1970*91f16700Schasinglulu FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1971*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 1972*91f16700Schasinglulu } 1973*91f16700Schasinglulu 1974*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset, 1975*91f16700Schasinglulu src_size - data_size); 1976*91f16700Schasinglulu 1977*91f16700Schasinglulu memset((void *) dst_addr, 0, *dst_size); 1978*91f16700Schasinglulu 1979*91f16700Schasinglulu i += (src_size - data_size) / MBOX_WORD_BYTE; 1980*91f16700Schasinglulu } 1981*91f16700Schasinglulu 1982*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, 1983*91f16700Schasinglulu MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 1984*91f16700Schasinglulu payload, i, CMD_INDIRECT); 1985*91f16700Schasinglulu 1986*91f16700Schasinglulu if (is_finalised != 0U) { 1987*91f16700Schasinglulu memset((void *) &fcs_sha2_data_sig_verify_param, 0, 1988*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 1989*91f16700Schasinglulu } 1990*91f16700Schasinglulu 1991*91f16700Schasinglulu if (status < 0) { 1992*91f16700Schasinglulu *mbox_error = -status; 1993*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 1994*91f16700Schasinglulu } 1995*91f16700Schasinglulu 1996*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 1997*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 1998*91f16700Schasinglulu 1999*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 2000*91f16700Schasinglulu } 2001*91f16700Schasinglulu 2002*91f16700Schasinglulu int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 2003*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 2004*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 2005*91f16700Schasinglulu { 2006*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 2007*91f16700Schasinglulu key_id, param_size, param_data, 2008*91f16700Schasinglulu (void *) &fcs_ecdsa_get_pubkey_param, 2009*91f16700Schasinglulu mbox_error); 2010*91f16700Schasinglulu } 2011*91f16700Schasinglulu 2012*91f16700Schasinglulu int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id, 2013*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 2014*91f16700Schasinglulu uint32_t *mbox_error) 2015*91f16700Schasinglulu { 2016*91f16700Schasinglulu int status; 2017*91f16700Schasinglulu int i; 2018*91f16700Schasinglulu uint32_t crypto_header; 2019*91f16700Schasinglulu uint32_t ret_size; 2020*91f16700Schasinglulu uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 2021*91f16700Schasinglulu 2022*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 2023*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2024*91f16700Schasinglulu } 2025*91f16700Schasinglulu 2026*91f16700Schasinglulu if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 2027*91f16700Schasinglulu fcs_ecdsa_get_pubkey_param.context_id != context_id) { 2028*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2029*91f16700Schasinglulu } 2030*91f16700Schasinglulu 2031*91f16700Schasinglulu ret_size = *dst_size / MBOX_WORD_BYTE; 2032*91f16700Schasinglulu 2033*91f16700Schasinglulu crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 2034*91f16700Schasinglulu FCS_CS_FIELD_FLAG_UPDATE | 2035*91f16700Schasinglulu FCS_CS_FIELD_FLAG_FINALIZE) << 2036*91f16700Schasinglulu FCS_CS_FIELD_FLAG_OFFSET) | 2037*91f16700Schasinglulu fcs_ecdsa_get_pubkey_param.crypto_param_size; 2038*91f16700Schasinglulu i = 0; 2039*91f16700Schasinglulu /* Prepare command payload */ 2040*91f16700Schasinglulu payload[i] = session_id; 2041*91f16700Schasinglulu i++; 2042*91f16700Schasinglulu payload[i] = context_id; 2043*91f16700Schasinglulu i++; 2044*91f16700Schasinglulu payload[i] = crypto_header; 2045*91f16700Schasinglulu i++; 2046*91f16700Schasinglulu payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 2047*91f16700Schasinglulu i++; 2048*91f16700Schasinglulu payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 2049*91f16700Schasinglulu INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2050*91f16700Schasinglulu i++; 2051*91f16700Schasinglulu 2052*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY, 2053*91f16700Schasinglulu payload, i, CMD_CASUAL, 2054*91f16700Schasinglulu (uint32_t *) dst_addr, &ret_size); 2055*91f16700Schasinglulu 2056*91f16700Schasinglulu memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 2057*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 2058*91f16700Schasinglulu 2059*91f16700Schasinglulu if (status < 0) { 2060*91f16700Schasinglulu *mbox_error = -status; 2061*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 2062*91f16700Schasinglulu } 2063*91f16700Schasinglulu 2064*91f16700Schasinglulu *dst_size = ret_size * MBOX_WORD_BYTE; 2065*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 2066*91f16700Schasinglulu 2067*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 2068*91f16700Schasinglulu } 2069*91f16700Schasinglulu 2070*91f16700Schasinglulu int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 2071*91f16700Schasinglulu uint32_t key_id, uint32_t param_size, 2072*91f16700Schasinglulu uint64_t param_data, uint32_t *mbox_error) 2073*91f16700Schasinglulu { 2074*91f16700Schasinglulu return intel_fcs_crypto_service_init(session_id, context_id, 2075*91f16700Schasinglulu key_id, param_size, param_data, 2076*91f16700Schasinglulu (void *) &fcs_ecdh_request_param, 2077*91f16700Schasinglulu mbox_error); 2078*91f16700Schasinglulu } 2079*91f16700Schasinglulu 2080*91f16700Schasinglulu int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id, 2081*91f16700Schasinglulu uint32_t src_addr, uint32_t src_size, 2082*91f16700Schasinglulu uint64_t dst_addr, uint32_t *dst_size, 2083*91f16700Schasinglulu uint32_t *mbox_error) 2084*91f16700Schasinglulu { 2085*91f16700Schasinglulu int status; 2086*91f16700Schasinglulu uint32_t i; 2087*91f16700Schasinglulu uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 2088*91f16700Schasinglulu uint32_t resp_len; 2089*91f16700Schasinglulu uintptr_t pubkey; 2090*91f16700Schasinglulu uint32_t dst_size_check = 0; 2091*91f16700Schasinglulu 2092*91f16700Schasinglulu if ((dst_size == NULL) || (mbox_error == NULL)) { 2093*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2094*91f16700Schasinglulu } 2095*91f16700Schasinglulu 2096*91f16700Schasinglulu 2097*91f16700Schasinglulu if (fcs_ecdh_request_param.session_id != session_id || 2098*91f16700Schasinglulu fcs_ecdh_request_param.context_id != context_id) { 2099*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2100*91f16700Schasinglulu } 2101*91f16700Schasinglulu 2102*91f16700Schasinglulu if (!is_address_in_ddr_range(src_addr, src_size) || 2103*91f16700Schasinglulu !is_address_in_ddr_range(dst_addr, *dst_size)) { 2104*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2105*91f16700Schasinglulu } 2106*91f16700Schasinglulu 2107*91f16700Schasinglulu dst_size_check = *dst_size; 2108*91f16700Schasinglulu if ((dst_size_check > FCS_MAX_DATA_SIZE || 2109*91f16700Schasinglulu dst_size_check < FCS_MIN_DATA_SIZE) || 2110*91f16700Schasinglulu (src_size > FCS_MAX_DATA_SIZE || 2111*91f16700Schasinglulu src_size < FCS_MIN_DATA_SIZE)) { 2112*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2113*91f16700Schasinglulu } 2114*91f16700Schasinglulu 2115*91f16700Schasinglulu resp_len = *dst_size / MBOX_WORD_BYTE; 2116*91f16700Schasinglulu 2117*91f16700Schasinglulu /* Prepare command payload */ 2118*91f16700Schasinglulu i = 0; 2119*91f16700Schasinglulu /* Crypto header */ 2120*91f16700Schasinglulu payload[i] = fcs_ecdh_request_param.session_id; 2121*91f16700Schasinglulu i++; 2122*91f16700Schasinglulu payload[i] = fcs_ecdh_request_param.context_id; 2123*91f16700Schasinglulu i++; 2124*91f16700Schasinglulu payload[i] = fcs_ecdh_request_param.crypto_param_size 2125*91f16700Schasinglulu & FCS_CS_FIELD_SIZE_MASK; 2126*91f16700Schasinglulu payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2127*91f16700Schasinglulu | FCS_CS_FIELD_FLAG_FINALIZE) 2128*91f16700Schasinglulu << FCS_CS_FIELD_FLAG_OFFSET; 2129*91f16700Schasinglulu i++; 2130*91f16700Schasinglulu payload[i] = fcs_ecdh_request_param.key_id; 2131*91f16700Schasinglulu i++; 2132*91f16700Schasinglulu /* Crypto parameters */ 2133*91f16700Schasinglulu payload[i] = fcs_ecdh_request_param.crypto_param 2134*91f16700Schasinglulu & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2135*91f16700Schasinglulu i++; 2136*91f16700Schasinglulu /* Public key data */ 2137*91f16700Schasinglulu pubkey = src_addr; 2138*91f16700Schasinglulu 2139*91f16700Schasinglulu if ((i + ((src_size) / MBOX_WORD_BYTE)) > 2140*91f16700Schasinglulu FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) { 2141*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2142*91f16700Schasinglulu } 2143*91f16700Schasinglulu 2144*91f16700Schasinglulu memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size); 2145*91f16700Schasinglulu i += src_size / MBOX_WORD_BYTE; 2146*91f16700Schasinglulu 2147*91f16700Schasinglulu status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2148*91f16700Schasinglulu payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2149*91f16700Schasinglulu &resp_len); 2150*91f16700Schasinglulu 2151*91f16700Schasinglulu memset((void *)&fcs_ecdh_request_param, 0, 2152*91f16700Schasinglulu sizeof(fcs_crypto_service_data)); 2153*91f16700Schasinglulu 2154*91f16700Schasinglulu if (status < 0) { 2155*91f16700Schasinglulu *mbox_error = -status; 2156*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 2157*91f16700Schasinglulu } 2158*91f16700Schasinglulu 2159*91f16700Schasinglulu *dst_size = resp_len * MBOX_WORD_BYTE; 2160*91f16700Schasinglulu flush_dcache_range(dst_addr, *dst_size); 2161*91f16700Schasinglulu 2162*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 2163*91f16700Schasinglulu } 2164*91f16700Schasinglulu 2165*91f16700Schasinglulu int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2166*91f16700Schasinglulu uint32_t key_id, uint64_t param_addr, 2167*91f16700Schasinglulu uint32_t param_size, uint32_t *mbox_error) 2168*91f16700Schasinglulu { 2169*91f16700Schasinglulu /* ptr to get param_addr value */ 2170*91f16700Schasinglulu uint64_t *param_addr_ptr; 2171*91f16700Schasinglulu 2172*91f16700Schasinglulu param_addr_ptr = (uint64_t *) param_addr; 2173*91f16700Schasinglulu 2174*91f16700Schasinglulu /* 2175*91f16700Schasinglulu * Since crypto param size vary between mode. 2176*91f16700Schasinglulu * Check ECB here and limit to size 12 bytes 2177*91f16700Schasinglulu */ 2178*91f16700Schasinglulu if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2179*91f16700Schasinglulu (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2180*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2181*91f16700Schasinglulu } 2182*91f16700Schasinglulu /* 2183*91f16700Schasinglulu * Since crypto param size vary between mode. 2184*91f16700Schasinglulu * Check CBC/CTR here and limit to size 28 bytes 2185*91f16700Schasinglulu */ 2186*91f16700Schasinglulu if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2187*91f16700Schasinglulu ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) && 2188*91f16700Schasinglulu (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2189*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2190*91f16700Schasinglulu } 2191*91f16700Schasinglulu 2192*91f16700Schasinglulu if (mbox_error == NULL) { 2193*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2194*91f16700Schasinglulu } 2195*91f16700Schasinglulu 2196*91f16700Schasinglulu memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2197*91f16700Schasinglulu 2198*91f16700Schasinglulu fcs_aes_init_payload.session_id = session_id; 2199*91f16700Schasinglulu fcs_aes_init_payload.context_id = context_id; 2200*91f16700Schasinglulu fcs_aes_init_payload.param_size = param_size; 2201*91f16700Schasinglulu fcs_aes_init_payload.key_id = key_id; 2202*91f16700Schasinglulu 2203*91f16700Schasinglulu memcpy((uint8_t *) fcs_aes_init_payload.crypto_param, 2204*91f16700Schasinglulu (uint8_t *) param_addr, param_size); 2205*91f16700Schasinglulu 2206*91f16700Schasinglulu fcs_aes_init_payload.is_updated = 0; 2207*91f16700Schasinglulu 2208*91f16700Schasinglulu *mbox_error = 0; 2209*91f16700Schasinglulu 2210*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 2211*91f16700Schasinglulu } 2212*91f16700Schasinglulu 2213*91f16700Schasinglulu int intel_fcs_aes_crypt_update_finalize(uint32_t session_id, 2214*91f16700Schasinglulu uint32_t context_id, uint64_t src_addr, 2215*91f16700Schasinglulu uint32_t src_size, uint64_t dst_addr, 2216*91f16700Schasinglulu uint32_t dst_size, uint8_t is_finalised, 2217*91f16700Schasinglulu uint32_t *send_id) 2218*91f16700Schasinglulu { 2219*91f16700Schasinglulu int status; 2220*91f16700Schasinglulu int i; 2221*91f16700Schasinglulu uint32_t flag; 2222*91f16700Schasinglulu uint32_t crypto_header; 2223*91f16700Schasinglulu uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2224*91f16700Schasinglulu 2225*91f16700Schasinglulu if (fcs_aes_init_payload.session_id != session_id || 2226*91f16700Schasinglulu fcs_aes_init_payload.context_id != context_id) { 2227*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2228*91f16700Schasinglulu } 2229*91f16700Schasinglulu 2230*91f16700Schasinglulu if ((!is_8_bytes_aligned(src_addr)) || 2231*91f16700Schasinglulu (!is_32_bytes_aligned(src_size)) || 2232*91f16700Schasinglulu (!is_address_in_ddr_range(src_addr, src_size))) { 2233*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2234*91f16700Schasinglulu } 2235*91f16700Schasinglulu 2236*91f16700Schasinglulu if ((!is_8_bytes_aligned(dst_addr)) || 2237*91f16700Schasinglulu (!is_32_bytes_aligned(dst_size))) { 2238*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2239*91f16700Schasinglulu } 2240*91f16700Schasinglulu 2241*91f16700Schasinglulu if ((dst_size > FCS_AES_MAX_DATA_SIZE || 2242*91f16700Schasinglulu dst_size < FCS_AES_MIN_DATA_SIZE) || 2243*91f16700Schasinglulu (src_size > FCS_AES_MAX_DATA_SIZE || 2244*91f16700Schasinglulu src_size < FCS_AES_MIN_DATA_SIZE)) { 2245*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2246*91f16700Schasinglulu } 2247*91f16700Schasinglulu 2248*91f16700Schasinglulu /* Prepare crypto header*/ 2249*91f16700Schasinglulu flag = 0; 2250*91f16700Schasinglulu if (fcs_aes_init_payload.is_updated) { 2251*91f16700Schasinglulu fcs_aes_init_payload.param_size = 0; 2252*91f16700Schasinglulu } else { 2253*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_INIT; 2254*91f16700Schasinglulu } 2255*91f16700Schasinglulu 2256*91f16700Schasinglulu if (is_finalised != 0U) { 2257*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2258*91f16700Schasinglulu } else { 2259*91f16700Schasinglulu flag |= FCS_CS_FIELD_FLAG_UPDATE; 2260*91f16700Schasinglulu fcs_aes_init_payload.is_updated = 1; 2261*91f16700Schasinglulu } 2262*91f16700Schasinglulu crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2263*91f16700Schasinglulu fcs_aes_init_payload.param_size; 2264*91f16700Schasinglulu 2265*91f16700Schasinglulu i = 0U; 2266*91f16700Schasinglulu fcs_aes_crypt_payload[i] = session_id; 2267*91f16700Schasinglulu i++; 2268*91f16700Schasinglulu fcs_aes_crypt_payload[i] = context_id; 2269*91f16700Schasinglulu i++; 2270*91f16700Schasinglulu fcs_aes_crypt_payload[i] = crypto_header; 2271*91f16700Schasinglulu i++; 2272*91f16700Schasinglulu 2273*91f16700Schasinglulu if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2274*91f16700Schasinglulu FCS_CS_FIELD_FLAG_INIT) { 2275*91f16700Schasinglulu fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2276*91f16700Schasinglulu i++; 2277*91f16700Schasinglulu 2278*91f16700Schasinglulu if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) > 2279*91f16700Schasinglulu FCS_AES_CMD_MAX_WORD_SIZE) { 2280*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_REJECTED; 2281*91f16700Schasinglulu } 2282*91f16700Schasinglulu 2283*91f16700Schasinglulu memcpy((uint8_t *) &fcs_aes_crypt_payload[i], 2284*91f16700Schasinglulu (uint8_t *) fcs_aes_init_payload.crypto_param, 2285*91f16700Schasinglulu fcs_aes_init_payload.param_size); 2286*91f16700Schasinglulu 2287*91f16700Schasinglulu i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2288*91f16700Schasinglulu } 2289*91f16700Schasinglulu 2290*91f16700Schasinglulu fcs_aes_crypt_payload[i] = (uint32_t) src_addr; 2291*91f16700Schasinglulu i++; 2292*91f16700Schasinglulu fcs_aes_crypt_payload[i] = src_size; 2293*91f16700Schasinglulu i++; 2294*91f16700Schasinglulu fcs_aes_crypt_payload[i] = (uint32_t) dst_addr; 2295*91f16700Schasinglulu i++; 2296*91f16700Schasinglulu fcs_aes_crypt_payload[i] = dst_size; 2297*91f16700Schasinglulu i++; 2298*91f16700Schasinglulu 2299*91f16700Schasinglulu status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2300*91f16700Schasinglulu fcs_aes_crypt_payload, i, 2301*91f16700Schasinglulu CMD_INDIRECT); 2302*91f16700Schasinglulu 2303*91f16700Schasinglulu if (is_finalised != 0U) { 2304*91f16700Schasinglulu memset((void *)&fcs_aes_init_payload, 0, 2305*91f16700Schasinglulu sizeof(fcs_aes_init_payload)); 2306*91f16700Schasinglulu } 2307*91f16700Schasinglulu 2308*91f16700Schasinglulu if (status < 0U) { 2309*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_ERROR; 2310*91f16700Schasinglulu } 2311*91f16700Schasinglulu 2312*91f16700Schasinglulu return INTEL_SIP_SMC_STATUS_OK; 2313*91f16700Schasinglulu } 2314