1 /* 2 * Copyright (c) 2020-2023, Intel Corporation. All rights reserved. 3 * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <arch_helpers.h> 9 #include <common/debug.h> 10 #include <lib/mmio.h> 11 12 #include "../lib/utils/alignment_utils.h" 13 #include "socfpga_plat_def.h" 14 #include "socfpga_fcs.h" 15 #include "socfpga_mailbox.h" 16 #include "socfpga_sip_svc.h" 17 18 /* FCS static variables */ 19 static fcs_crypto_service_aes_data fcs_aes_init_payload; 20 static fcs_crypto_service_data fcs_sha_get_digest_param; 21 static fcs_crypto_service_data fcs_sha_mac_verify_param; 22 static fcs_crypto_service_data fcs_ecdsa_hash_sign_param; 23 static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param; 24 static fcs_crypto_service_data fcs_sha2_data_sign_param; 25 static fcs_crypto_service_data fcs_sha2_data_sig_verify_param; 26 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param; 27 static fcs_crypto_service_data fcs_ecdh_request_param; 28 29 uint8_t fcs_send_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 30 { 31 uint8_t ret_args_len = 0U; 32 sdm_response_t *resp = (sdm_response_t *)resp_desc; 33 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 34 35 (void)cmd; 36 INFO("MBOX: %s: mailbox_err 0x%x, status_word %d\n", 37 __func__, resp->err_code, resp->resp_data[0]); 38 39 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 40 ret_args[ret_args_len++] = resp->err_code; 41 ret_args[ret_args_len++] = resp->resp_data[0]; 42 43 return ret_args_len; 44 } 45 46 uint8_t fcs_cntr_set_preauth_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 47 { 48 uint8_t ret_args_len = 0U; 49 sdm_response_t *resp = (sdm_response_t *)resp_desc; 50 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 51 52 (void)cmd; 53 INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code); 54 55 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 56 ret_args[ret_args_len++] = resp->err_code; 57 58 return ret_args_len; 59 } 60 61 uint8_t fcs_get_attest_cert_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 62 { 63 uint8_t ret_args_len = 0U; 64 sdm_response_t *resp = (sdm_response_t *)resp_desc; 65 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 66 67 INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n", 68 __func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 69 70 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 71 ret_args[ret_args_len++] = resp->err_code; 72 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 73 74 /* Flush the response data buffer. */ 75 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 76 77 return ret_args_len; 78 } 79 80 uint8_t fcs_hkdf_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 81 { 82 uint8_t ret_args_len = 0U; 83 sdm_response_t *resp = (sdm_response_t *)resp_desc; 84 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 85 86 (void)cmd; 87 88 INFO("MBOX: %s: mbox_err 0x%x, hkdf_status 0x%x\n", __func__, 89 resp->err_code, resp->resp_data[0]); 90 91 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 92 ret_args[ret_args_len++] = resp->err_code; 93 ret_args[ret_args_len++] = resp->resp_data[0]; 94 95 return ret_args_len; 96 } 97 98 uint8_t fcs_create_cert_reload_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 99 { 100 uint8_t ret_args_len = 0U; 101 sdm_response_t *resp = (sdm_response_t *)resp_desc; 102 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 103 104 (void)cmd; 105 INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code); 106 107 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 108 ret_args[ret_args_len++] = resp->err_code; 109 110 return ret_args_len; 111 } 112 113 uint8_t fcs_cs_get_digest_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 114 { 115 uint8_t ret_args_len = 0U; 116 sdm_response_t *resp = (sdm_response_t *)resp_desc; 117 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 118 119 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 120 resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 121 122 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 123 ret_args[ret_args_len++] = resp->err_code; 124 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 125 126 /* Flush the response data buffer. */ 127 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 128 129 return ret_args_len; 130 } 131 132 uint8_t fcs_cs_mac_verify_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 133 { 134 uint8_t ret_args_len = 0U; 135 sdm_response_t *resp = (sdm_response_t *)resp_desc; 136 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 137 138 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d, verify_result 0x%x\n", 139 __func__, resp->err_code, 140 resp->rcvd_resp_len * MBOX_WORD_BYTE, 141 cmd->cb_args[3]); 142 143 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 144 ret_args[ret_args_len++] = resp->err_code; 145 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 146 ret_args[ret_args_len++] = cmd->cb_args[3]; 147 148 /* Flush the response data buffer. */ 149 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 150 151 return ret_args_len; 152 } 153 154 uint8_t fcs_cs_hash_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 155 { 156 uint8_t ret_args_len = 0U; 157 sdm_response_t *resp = (sdm_response_t *)resp_desc; 158 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 159 160 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n", 161 __func__, resp->resp_data[0], resp->resp_data[1], 162 resp->resp_data[2], resp->rcvd_resp_len); 163 164 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 165 ret_args[ret_args_len++] = resp->err_code; 166 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 167 168 /* Flush the response data buffer. */ 169 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 170 171 return ret_args_len; 172 } 173 174 uint8_t fcs_cs_hash_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 175 { 176 uint8_t ret_args_len = 0U; 177 sdm_response_t *resp = (sdm_response_t *)resp_desc; 178 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 179 180 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, [3] 0x%x\n", 181 __func__, resp->resp_data[0], resp->resp_data[1], 182 resp->resp_data[2], resp->resp_data[3]); 183 184 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 185 ret_args[ret_args_len++] = resp->err_code; 186 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 187 188 /* Flush the response data buffer. */ 189 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 190 191 return ret_args_len; 192 } 193 194 uint8_t fcs_cs_aes_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 195 { 196 uint8_t ret_args_len = 0U; 197 sdm_response_t *resp = (sdm_response_t *)resp_desc; 198 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 199 200 (void)cmd; 201 202 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 203 resp->err_code, resp->resp_data[3]); 204 205 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 206 ret_args[ret_args_len++] = resp->err_code; 207 ret_args[ret_args_len++] = resp->resp_data[3]; 208 209 return ret_args_len; 210 } 211 212 uint8_t fcs_cs_data_sign_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 213 { 214 uint8_t ret_args_len = 0U; 215 sdm_response_t *resp = (sdm_response_t *)resp_desc; 216 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 217 218 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__, 219 resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE); 220 221 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 222 ret_args[ret_args_len++] = resp->err_code; 223 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 224 225 /* Flush the response data buffer. */ 226 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 227 return ret_args_len; 228 } 229 230 uint8_t fcs_sdos_crypto_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 231 { 232 uint8_t ret_args_len = 0U; 233 sdm_response_t *resp = (sdm_response_t *)resp_desc; 234 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 235 236 (void)cmd; 237 INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n", 238 __func__, resp->err_code, resp->resp_data[3]); 239 240 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 241 ret_args[ret_args_len++] = resp->err_code; 242 /* Encrypted/Decrypted data size written to the destination buffer */ 243 ret_args[ret_args_len++] = resp->resp_data[3]; 244 245 return ret_args_len; 246 } 247 248 uint8_t fcs_cs_get_public_key_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 249 { 250 uint8_t ret_args_len = 0U; 251 sdm_response_t *resp = (sdm_response_t *)resp_desc; 252 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 253 254 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %u\n", 255 __func__, resp->err_code, 256 resp->rcvd_resp_len * MBOX_WORD_BYTE); 257 258 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 259 ret_args[ret_args_len++] = resp->err_code; 260 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 261 262 /* Flush the response data buffer. */ 263 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 264 265 return ret_args_len; 266 } 267 268 uint8_t fcs_cs_data_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 269 { 270 uint8_t ret_args_len = 0U; 271 sdm_response_t *resp = (sdm_response_t *)resp_desc; 272 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 273 274 INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret 0x%x\n", 275 __func__, resp->err_code, resp->rcvd_resp_len); 276 277 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 278 ret_args[ret_args_len++] = resp->err_code; 279 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 280 281 /* Flush the response data buffer. */ 282 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 283 284 return ret_args_len; 285 } 286 287 uint8_t fcs_cs_ecdh_request_cb(void *resp_desc, void *cmd_desc, uint64_t *ret_args) 288 { 289 uint8_t ret_args_len = 0U; 290 sdm_response_t *resp = (sdm_response_t *)resp_desc; 291 sdm_command_t *cmd = (sdm_command_t *)cmd_desc; 292 293 INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n", 294 __func__, resp->resp_data[0], resp->resp_data[1], 295 resp->resp_data[2], resp->rcvd_resp_len); 296 297 ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK; 298 ret_args[ret_args_len++] = resp->err_code; 299 ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE; 300 301 /* Flush the response data buffer. */ 302 flush_dcache_range((uintptr_t)cmd->cb_args, resp->rcvd_resp_len * MBOX_WORD_BYTE); 303 304 return ret_args_len; 305 } 306 307 static int intel_fcs_crypto_service_init(uint32_t session_id, 308 uint32_t context_id, uint32_t key_id, 309 uint32_t param_size, uint64_t param_data, 310 fcs_crypto_service_data *data_addr, 311 uint32_t *mbox_error) 312 { 313 if (mbox_error == NULL) { 314 return INTEL_SIP_SMC_STATUS_REJECTED; 315 } 316 317 if (param_size != 4) { 318 return INTEL_SIP_SMC_STATUS_REJECTED; 319 } 320 321 memset(data_addr, 0, sizeof(fcs_crypto_service_data)); 322 323 data_addr->session_id = session_id; 324 data_addr->context_id = context_id; 325 data_addr->key_id = key_id; 326 data_addr->crypto_param_size = param_size; 327 data_addr->crypto_param = param_data; 328 329 data_addr->is_updated = 0; 330 331 *mbox_error = 0; 332 333 return INTEL_SIP_SMC_STATUS_OK; 334 } 335 336 uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size, 337 uint32_t *mbox_error) 338 { 339 int status; 340 unsigned int i; 341 unsigned int resp_len = FCS_RANDOM_WORD_SIZE; 342 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U}; 343 344 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) { 345 return INTEL_SIP_SMC_STATUS_REJECTED; 346 } 347 348 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U, 349 CMD_CASUAL, random_data, &resp_len); 350 351 if (status < 0) { 352 *mbox_error = -status; 353 return INTEL_SIP_SMC_STATUS_ERROR; 354 } 355 356 if (resp_len != FCS_RANDOM_WORD_SIZE) { 357 *mbox_error = GENERIC_RESPONSE_ERROR; 358 return INTEL_SIP_SMC_STATUS_ERROR; 359 } 360 361 *ret_size = FCS_RANDOM_BYTE_SIZE; 362 363 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) { 364 mmio_write_32(addr, random_data[i]); 365 addr += MBOX_WORD_BYTE; 366 } 367 368 flush_dcache_range(addr - *ret_size, *ret_size); 369 370 return INTEL_SIP_SMC_STATUS_OK; 371 } 372 373 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id, 374 uint32_t size, uint32_t *send_id) 375 { 376 int status; 377 uint32_t payload_size; 378 uint32_t crypto_header; 379 380 if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE * 381 MBOX_WORD_BYTE) || size == 0U) { 382 return INTEL_SIP_SMC_STATUS_REJECTED; 383 } 384 385 if (!is_size_4_bytes_aligned(size)) { 386 return INTEL_SIP_SMC_STATUS_REJECTED; 387 } 388 389 crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) << 390 FCS_CS_FIELD_FLAG_OFFSET; 391 392 fcs_rng_payload payload = { 393 session_id, 394 context_id, 395 crypto_header, 396 size 397 }; 398 399 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 400 401 status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN, 402 (uint32_t *) &payload, payload_size, 403 CMD_INDIRECT); 404 405 if (status < 0) { 406 return INTEL_SIP_SMC_STATUS_ERROR; 407 } 408 409 return INTEL_SIP_SMC_STATUS_OK; 410 } 411 412 uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id, 413 uint64_t addr, uint64_t size, 414 uint32_t *send_id) 415 { 416 int status; 417 418 if (!is_address_in_ddr_range(addr, size)) { 419 return INTEL_SIP_SMC_STATUS_REJECTED; 420 } 421 422 if (!is_size_4_bytes_aligned(size)) { 423 return INTEL_SIP_SMC_STATUS_REJECTED; 424 } 425 426 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE) ? 427 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 428 GET_JOB_ID(trans_id), 429 MBOX_CMD_VAB_SRC_CERT, 430 (uint32_t *) addr, 431 size / MBOX_WORD_BYTE, 432 MBOX_CMD_FLAG_CASUAL, 433 fcs_send_cert_cb, 434 NULL, 435 0U) : 436 mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT, 437 (uint32_t *)addr, size / MBOX_WORD_BYTE, 438 CMD_DIRECT); 439 440 flush_dcache_range(addr, size); 441 442 if (status < 0) { 443 return INTEL_SIP_SMC_STATUS_ERROR; 444 } 445 446 return INTEL_SIP_SMC_STATUS_OK; 447 } 448 449 uint32_t intel_fcs_get_provision_data(uint32_t *send_id) 450 { 451 int status; 452 453 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION, 454 NULL, 0U, CMD_DIRECT); 455 456 if (status < 0) { 457 return INTEL_SIP_SMC_STATUS_ERROR; 458 } 459 460 return INTEL_SIP_SMC_STATUS_OK; 461 } 462 463 uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id, 464 uint8_t counter_type, int32_t counter_value, 465 uint32_t test_bit, uint32_t *mbox_error) 466 { 467 int status; 468 uint32_t first_word; 469 uint32_t payload_size; 470 471 if ((test_bit != MBOX_TEST_BIT) && 472 (test_bit != 0)) { 473 return INTEL_SIP_SMC_STATUS_REJECTED; 474 } 475 476 if ((counter_type < FCS_BIG_CNTR_SEL) || 477 (counter_type > FCS_SVN_CNTR_3_SEL)) { 478 return INTEL_SIP_SMC_STATUS_REJECTED; 479 } 480 481 if ((counter_type == FCS_BIG_CNTR_SEL) && 482 (counter_value > FCS_BIG_CNTR_VAL_MAX)) { 483 return INTEL_SIP_SMC_STATUS_REJECTED; 484 } 485 486 if ((counter_type >= FCS_SVN_CNTR_0_SEL) && 487 (counter_type <= FCS_SVN_CNTR_3_SEL) && 488 (counter_value > FCS_SVN_CNTR_VAL_MAX)) { 489 return INTEL_SIP_SMC_STATUS_REJECTED; 490 } 491 492 first_word = test_bit | counter_type; 493 fcs_cntr_set_preauth_payload payload = { 494 first_word, 495 counter_value 496 }; 497 498 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 499 500 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH) ? 501 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 502 GET_JOB_ID(trans_id), 503 MBOX_FCS_CNTR_SET_PREAUTH, 504 (uint32_t *) &payload, 505 payload_size, 506 MBOX_CMD_FLAG_CASUAL, 507 fcs_cntr_set_preauth_cb, 508 NULL, 509 0U) : 510 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH, 511 (uint32_t *) &payload, payload_size, 512 CMD_CASUAL, NULL, NULL); 513 514 if (status < 0) { 515 *mbox_error = -status; 516 return INTEL_SIP_SMC_STATUS_ERROR; 517 } 518 519 return INTEL_SIP_SMC_STATUS_OK; 520 } 521 522 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size, 523 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 524 { 525 int status; 526 uint32_t load_size; 527 528 if (!is_address_in_ddr_range(src_addr, src_size) || 529 !is_address_in_ddr_range(dst_addr, dst_size)) { 530 return INTEL_SIP_SMC_STATUS_REJECTED; 531 } 532 533 if (!is_size_4_bytes_aligned(src_size)) { 534 return INTEL_SIP_SMC_STATUS_REJECTED; 535 } 536 537 fcs_encrypt_payload payload = { 538 FCS_ENCRYPTION_DATA_0, 539 src_addr, 540 src_size, 541 dst_addr, 542 dst_size }; 543 load_size = sizeof(payload) / MBOX_WORD_BYTE; 544 545 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ, 546 (uint32_t *) &payload, load_size, 547 CMD_INDIRECT); 548 inv_dcache_range(dst_addr, dst_size); 549 550 if (status < 0) { 551 return INTEL_SIP_SMC_STATUS_REJECTED; 552 } 553 554 return INTEL_SIP_SMC_STATUS_OK; 555 } 556 557 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size, 558 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id) 559 { 560 int status; 561 uint32_t load_size; 562 uintptr_t id_offset; 563 564 if (!is_address_in_ddr_range(src_addr, src_size) || 565 !is_address_in_ddr_range(dst_addr, dst_size)) { 566 return INTEL_SIP_SMC_STATUS_REJECTED; 567 } 568 569 if (!is_size_4_bytes_aligned(src_size)) { 570 return INTEL_SIP_SMC_STATUS_REJECTED; 571 } 572 573 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 574 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 575 fcs_decrypt_payload payload = { 576 FCS_DECRYPTION_DATA_0, 577 {mmio_read_32(id_offset), 578 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 579 src_addr, 580 src_size, 581 dst_addr, 582 dst_size }; 583 load_size = sizeof(payload) / MBOX_WORD_BYTE; 584 585 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ, 586 (uint32_t *) &payload, load_size, 587 CMD_INDIRECT); 588 inv_dcache_range(dst_addr, dst_size); 589 590 if (status < 0) { 591 return INTEL_SIP_SMC_STATUS_REJECTED; 592 } 593 594 return INTEL_SIP_SMC_STATUS_OK; 595 } 596 597 int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id, 598 uint32_t session_id, uint32_t context_id, 599 uint32_t src_addr, uint32_t src_size, 600 uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error, 601 uint32_t smmu_src_addr, uint32_t smmu_dst_addr) 602 { 603 int status; 604 uint32_t payload_size; 605 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 606 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 607 uint32_t src_addr_sdm = src_addr; 608 uint32_t dst_addr_sdm = dst_addr; 609 610 if ((dst_size == NULL) || (mbox_error == NULL)) { 611 return INTEL_SIP_SMC_STATUS_REJECTED; 612 } 613 614 if (!is_address_in_ddr_range(src_addr, src_size) || 615 !is_address_in_ddr_range(dst_addr, *dst_size)) { 616 return INTEL_SIP_SMC_STATUS_REJECTED; 617 } 618 619 if (!is_size_4_bytes_aligned(src_size)) { 620 return INTEL_SIP_SMC_STATUS_REJECTED; 621 } 622 623 /* On the Agilex5 platform, we will use the SMMU payload address */ 624 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 625 src_addr_sdm = smmu_src_addr; 626 dst_addr_sdm = smmu_dst_addr; 627 #endif 628 629 fcs_encrypt_ext_payload payload = { 630 session_id, 631 context_id, 632 FCS_CRYPTION_CRYPTO_HEADER, 633 src_addr_sdm, 634 src_size, 635 dst_addr_sdm, 636 *dst_size 637 }; 638 639 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 640 641 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ? 642 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 643 GET_JOB_ID(trans_id), 644 MBOX_FCS_ENCRYPT_REQ, 645 (uint32_t *) &payload, 646 payload_size, 647 MBOX_CMD_FLAG_INDIRECT, 648 fcs_sdos_crypto_request_cb, 649 NULL, 650 0U) : 651 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ, 652 (uint32_t *) &payload, payload_size, 653 CMD_CASUAL, resp_data, &resp_len); 654 655 if (status < 0) { 656 *mbox_error = -status; 657 return INTEL_SIP_SMC_STATUS_ERROR; 658 } 659 660 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 661 *mbox_error = MBOX_RET_ERROR; 662 return INTEL_SIP_SMC_STATUS_ERROR; 663 } 664 665 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 666 inv_dcache_range(dst_addr, *dst_size); 667 668 return INTEL_SIP_SMC_STATUS_OK; 669 } 670 671 int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id, 672 uint32_t session_id, uint32_t context_id, 673 uint32_t src_addr, uint32_t src_size, 674 uint32_t dst_addr, uint32_t *dst_size, 675 uint32_t *mbox_error, uint64_t owner_id, 676 uint32_t smmu_src_addr, uint32_t smmu_dst_addr) 677 { 678 int status; 679 uintptr_t id_offset; 680 uint32_t payload_size; 681 uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE; 682 uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U}; 683 uint32_t src_addr_sdm = src_addr; 684 uint32_t dst_addr_sdm = dst_addr; 685 686 if ((dst_size == NULL) || (mbox_error == NULL)) { 687 return INTEL_SIP_SMC_STATUS_REJECTED; 688 } 689 690 if (!is_address_in_ddr_range(src_addr, src_size) || 691 !is_address_in_ddr_range(dst_addr, *dst_size)) { 692 return INTEL_SIP_SMC_STATUS_REJECTED; 693 } 694 695 if (!is_size_4_bytes_aligned(src_size)) { 696 return INTEL_SIP_SMC_STATUS_REJECTED; 697 } 698 699 /* On the Agilex5 platform, we will use the SMMU payload address */ 700 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 701 src_addr_sdm = smmu_src_addr; 702 dst_addr_sdm = smmu_dst_addr; 703 #endif 704 705 inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */ 706 id_offset = src_addr + FCS_OWNER_ID_OFFSET; 707 fcs_decrypt_ext_payload payload = { 708 session_id, 709 context_id, 710 FCS_CRYPTION_CRYPTO_HEADER, 711 {mmio_read_32(id_offset), 712 mmio_read_32(id_offset + MBOX_WORD_BYTE)}, 713 src_addr_sdm, 714 src_size, 715 dst_addr_sdm, 716 *dst_size 717 }; 718 719 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 720 721 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ? 722 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 723 GET_JOB_ID(trans_id), 724 MBOX_FCS_DECRYPT_REQ, 725 (uint32_t *) &payload, 726 payload_size, 727 MBOX_CMD_FLAG_INDIRECT, 728 fcs_sdos_crypto_request_cb, 729 NULL, 730 0U) : 731 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ, 732 (uint32_t *) &payload, payload_size, 733 CMD_CASUAL, resp_data, &resp_len); 734 735 if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 || 736 status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) { 737 *mbox_error = -status; 738 } else if (status < 0) { 739 *mbox_error = -status; 740 return INTEL_SIP_SMC_STATUS_ERROR; 741 } 742 743 if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) { 744 *mbox_error = MBOX_RET_ERROR; 745 return INTEL_SIP_SMC_STATUS_ERROR; 746 } 747 748 *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET]; 749 inv_dcache_range(dst_addr, *dst_size); 750 751 return INTEL_SIP_SMC_STATUS_OK; 752 } 753 754 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error) 755 { 756 int status; 757 758 if ((session_id != PSGSIGMA_SESSION_ID_ONE) && 759 (session_id != PSGSIGMA_UNKNOWN_SESSION)) { 760 return INTEL_SIP_SMC_STATUS_REJECTED; 761 } 762 763 psgsigma_teardown_msg message = { 764 RESERVED_AS_ZERO, 765 PSGSIGMA_TEARDOWN_MAGIC, 766 session_id 767 }; 768 769 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN, 770 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE, 771 CMD_CASUAL, NULL, NULL); 772 773 if (status < 0) { 774 *mbox_error = -status; 775 return INTEL_SIP_SMC_STATUS_ERROR; 776 } 777 778 return INTEL_SIP_SMC_STATUS_OK; 779 } 780 781 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error) 782 { 783 int status; 784 uint32_t load_size; 785 uint32_t chip_id[2]; 786 787 load_size = sizeof(chip_id) / MBOX_WORD_BYTE; 788 789 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL, 790 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size); 791 792 if (status < 0) { 793 *mbox_error = -status; 794 return INTEL_SIP_SMC_STATUS_ERROR; 795 } 796 797 *id_low = chip_id[0]; 798 *id_high = chip_id[1]; 799 800 return INTEL_SIP_SMC_STATUS_OK; 801 } 802 803 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size, 804 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 805 { 806 int status; 807 uint32_t send_size = src_size / MBOX_WORD_BYTE; 808 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 809 810 811 if (!is_address_in_ddr_range(src_addr, src_size) || 812 !is_address_in_ddr_range(dst_addr, *dst_size)) { 813 return INTEL_SIP_SMC_STATUS_REJECTED; 814 } 815 816 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY, 817 (uint32_t *) src_addr, send_size, CMD_CASUAL, 818 (uint32_t *) dst_addr, &ret_size); 819 820 if (status < 0) { 821 *mbox_error = -status; 822 return INTEL_SIP_SMC_STATUS_ERROR; 823 } 824 825 *dst_size = ret_size * MBOX_WORD_BYTE; 826 flush_dcache_range(dst_addr, *dst_size); 827 828 return INTEL_SIP_SMC_STATUS_OK; 829 } 830 831 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size, 832 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error) 833 { 834 int status; 835 uint32_t send_size = src_size / MBOX_WORD_BYTE; 836 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 837 838 if (!is_address_in_ddr_range(src_addr, src_size) || 839 !is_address_in_ddr_range(dst_addr, *dst_size)) { 840 return INTEL_SIP_SMC_STATUS_REJECTED; 841 } 842 843 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT, 844 (uint32_t *) src_addr, send_size, CMD_CASUAL, 845 (uint32_t *) dst_addr, &ret_size); 846 847 if (status < 0) { 848 *mbox_error = -status; 849 return INTEL_SIP_SMC_STATUS_ERROR; 850 } 851 852 *dst_size = ret_size * MBOX_WORD_BYTE; 853 flush_dcache_range(dst_addr, *dst_size); 854 855 return INTEL_SIP_SMC_STATUS_OK; 856 } 857 858 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size, 859 uint32_t *mbox_error) 860 { 861 int status; 862 unsigned int resp_len = FCS_SHA384_WORD_SIZE; 863 864 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) { 865 return INTEL_SIP_SMC_STATUS_REJECTED; 866 } 867 868 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U, 869 CMD_CASUAL, (uint32_t *) addr, &resp_len); 870 871 if (status < 0) { 872 *mbox_error = -status; 873 return INTEL_SIP_SMC_STATUS_ERROR; 874 } 875 876 if (resp_len != FCS_SHA384_WORD_SIZE) { 877 *mbox_error = GENERIC_RESPONSE_ERROR; 878 return INTEL_SIP_SMC_STATUS_ERROR; 879 } 880 881 *ret_size = FCS_SHA384_BYTE_SIZE; 882 883 flush_dcache_range(addr, *ret_size); 884 885 return INTEL_SIP_SMC_STATUS_OK; 886 } 887 888 int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id, 889 uint32_t cert_request, uint64_t dst_addr, 890 uint32_t *dst_size, uint32_t *mbox_error) 891 { 892 int status; 893 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE; 894 895 if (mbox_error == NULL) { 896 return INTEL_SIP_SMC_STATUS_REJECTED; 897 } 898 899 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 900 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 901 return INTEL_SIP_SMC_STATUS_REJECTED; 902 } 903 904 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 905 return INTEL_SIP_SMC_STATUS_REJECTED; 906 } 907 908 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT) ? 909 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 910 GET_JOB_ID(trans_id), 911 MBOX_GET_ATTESTATION_CERT, 912 (uint32_t *) &cert_request, 913 1U, 914 MBOX_CMD_FLAG_CASUAL, 915 fcs_get_attest_cert_cb, 916 (uint32_t *)dst_addr, 917 2U) : 918 mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT, 919 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 920 (uint32_t *) dst_addr, &ret_size); 921 922 if (status < 0) { 923 *mbox_error = -status; 924 return INTEL_SIP_SMC_STATUS_ERROR; 925 } 926 927 *dst_size = ret_size * MBOX_WORD_BYTE; 928 flush_dcache_range(dst_addr, *dst_size); 929 930 return INTEL_SIP_SMC_STATUS_OK; 931 } 932 933 int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id, 934 uint32_t cert_request, uint32_t *mbox_error) 935 { 936 int status; 937 938 if (mbox_error == NULL) { 939 return INTEL_SIP_SMC_STATUS_REJECTED; 940 } 941 942 if (cert_request < FCS_ATTEST_FIRMWARE_CERT || 943 cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) { 944 return INTEL_SIP_SMC_STATUS_REJECTED; 945 } 946 947 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD) ? 948 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 949 GET_JOB_ID(trans_id), 950 MBOX_CREATE_CERT_ON_RELOAD, 951 (uint32_t *) &cert_request, 952 1U, 953 MBOX_CMD_FLAG_CASUAL, 954 fcs_create_cert_reload_cb, 955 NULL, 956 0U) : 957 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD, 958 (uint32_t *) &cert_request, 1U, CMD_CASUAL, 959 NULL, NULL); 960 961 if (status < 0) { 962 *mbox_error = -status; 963 return INTEL_SIP_SMC_STATUS_ERROR; 964 } 965 966 return INTEL_SIP_SMC_STATUS_OK; 967 } 968 969 int intel_fcs_open_crypto_service_session(uint32_t *session_id, 970 uint32_t *mbox_error) 971 { 972 int status; 973 uint32_t resp_len = 1U; 974 975 if ((session_id == NULL) || (mbox_error == NULL)) { 976 return INTEL_SIP_SMC_STATUS_REJECTED; 977 } 978 979 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION, 980 NULL, 0U, CMD_CASUAL, session_id, &resp_len); 981 982 if (status < 0) { 983 *mbox_error = -status; 984 return INTEL_SIP_SMC_STATUS_ERROR; 985 } 986 987 return INTEL_SIP_SMC_STATUS_OK; 988 } 989 990 int intel_fcs_close_crypto_service_session(uint32_t session_id, 991 uint32_t *mbox_error) 992 { 993 int status; 994 995 if (mbox_error == NULL) { 996 return INTEL_SIP_SMC_STATUS_REJECTED; 997 } 998 999 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION, 1000 &session_id, 1U, CMD_CASUAL, NULL, NULL); 1001 1002 if (status < 0) { 1003 *mbox_error = -status; 1004 return INTEL_SIP_SMC_STATUS_ERROR; 1005 } 1006 1007 return INTEL_SIP_SMC_STATUS_OK; 1008 } 1009 1010 int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size, 1011 uint32_t *send_id) 1012 { 1013 int status; 1014 1015 if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE * 1016 MBOX_WORD_BYTE)) { 1017 return INTEL_SIP_SMC_STATUS_REJECTED; 1018 } 1019 1020 if (!is_address_in_ddr_range(src_addr, src_size)) { 1021 return INTEL_SIP_SMC_STATUS_REJECTED; 1022 } 1023 1024 status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY, 1025 (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE, 1026 CMD_INDIRECT); 1027 1028 if (status < 0) { 1029 return INTEL_SIP_SMC_STATUS_ERROR; 1030 } 1031 1032 return INTEL_SIP_SMC_STATUS_OK; 1033 } 1034 1035 int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id, 1036 uint64_t dst_addr, uint32_t *dst_size, 1037 uint32_t *mbox_error) 1038 { 1039 int status; 1040 uint32_t i; 1041 uint32_t payload_size; 1042 uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE; 1043 uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U}; 1044 uint32_t op_status = 0U; 1045 1046 if ((dst_size == NULL) || (mbox_error == NULL)) { 1047 return INTEL_SIP_SMC_STATUS_REJECTED; 1048 } 1049 1050 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 1051 return INTEL_SIP_SMC_STATUS_REJECTED; 1052 } 1053 1054 fcs_cs_key_payload payload = { 1055 session_id, 1056 RESERVED_AS_ZERO, 1057 RESERVED_AS_ZERO, 1058 key_id 1059 }; 1060 1061 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1062 1063 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY, 1064 (uint32_t *) &payload, payload_size, 1065 CMD_CASUAL, resp_data, &resp_len); 1066 1067 if (resp_len > 0) { 1068 op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK; 1069 } 1070 1071 if (status < 0) { 1072 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1073 return INTEL_SIP_SMC_STATUS_ERROR; 1074 } 1075 1076 if (resp_len > 1) { 1077 1078 /* Export key object is start at second response data */ 1079 *dst_size = (resp_len - 1) * MBOX_WORD_BYTE; 1080 1081 for (i = 1U; i < resp_len; i++) { 1082 mmio_write_32(dst_addr, resp_data[i]); 1083 dst_addr += MBOX_WORD_BYTE; 1084 } 1085 1086 flush_dcache_range(dst_addr - *dst_size, *dst_size); 1087 1088 } else { 1089 1090 /* Unexpected response, missing key object in response */ 1091 *mbox_error = MBOX_RET_ERROR; 1092 return INTEL_SIP_SMC_STATUS_ERROR; 1093 } 1094 1095 return INTEL_SIP_SMC_STATUS_OK; 1096 } 1097 1098 int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id, 1099 uint32_t *mbox_error) 1100 { 1101 int status; 1102 uint32_t payload_size; 1103 uint32_t resp_len = 1U; 1104 uint32_t resp_data = 0U; 1105 uint32_t op_status = 0U; 1106 1107 if (mbox_error == NULL) { 1108 return INTEL_SIP_SMC_STATUS_REJECTED; 1109 } 1110 1111 fcs_cs_key_payload payload = { 1112 session_id, 1113 RESERVED_AS_ZERO, 1114 RESERVED_AS_ZERO, 1115 key_id 1116 }; 1117 1118 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1119 1120 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY, 1121 (uint32_t *) &payload, payload_size, 1122 CMD_CASUAL, &resp_data, &resp_len); 1123 1124 if (resp_len > 0) { 1125 op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK; 1126 } 1127 1128 if (status < 0) { 1129 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1130 return INTEL_SIP_SMC_STATUS_ERROR; 1131 } 1132 1133 return INTEL_SIP_SMC_STATUS_OK; 1134 } 1135 1136 int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id, 1137 uint64_t dst_addr, uint32_t *dst_size, 1138 uint32_t *mbox_error) 1139 { 1140 int status; 1141 uint32_t payload_size; 1142 uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE; 1143 uint32_t op_status = 0U; 1144 1145 if ((dst_size == NULL) || (mbox_error == NULL)) { 1146 return INTEL_SIP_SMC_STATUS_REJECTED; 1147 } 1148 1149 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 1150 return INTEL_SIP_SMC_STATUS_REJECTED; 1151 } 1152 1153 fcs_cs_key_payload payload = { 1154 session_id, 1155 RESERVED_AS_ZERO, 1156 RESERVED_AS_ZERO, 1157 key_id 1158 }; 1159 1160 payload_size = sizeof(payload) / MBOX_WORD_BYTE; 1161 1162 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO, 1163 (uint32_t *) &payload, payload_size, 1164 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 1165 1166 if (resp_len > 0) { 1167 inv_dcache_range(dst_addr, (resp_len * MBOX_WORD_BYTE)); /* flush cache before mmio read to avoid reading old values */ 1168 op_status = mmio_read_32(dst_addr) & 1169 FCS_CS_KEY_RESP_STATUS_MASK; 1170 } 1171 1172 if (status < 0) { 1173 *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET); 1174 return INTEL_SIP_SMC_STATUS_ERROR; 1175 } 1176 1177 *dst_size = resp_len * MBOX_WORD_BYTE; 1178 flush_dcache_range(dst_addr, *dst_size); 1179 1180 return INTEL_SIP_SMC_STATUS_OK; 1181 } 1182 1183 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id, 1184 uint32_t key_id, uint32_t param_size, 1185 uint64_t param_data, uint32_t *mbox_error) 1186 { 1187 return intel_fcs_crypto_service_init(session_id, context_id, 1188 key_id, param_size, param_data, 1189 (void *) &fcs_sha_get_digest_param, 1190 mbox_error); 1191 } 1192 1193 int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1194 uint32_t session_id, uint32_t context_id, 1195 uint32_t src_addr, uint32_t src_size, 1196 uint64_t dst_addr, uint32_t *dst_size, 1197 uint8_t is_finalised, uint32_t *mbox_error, 1198 uint32_t smmu_src_addr) 1199 { 1200 int status; 1201 uint32_t i; 1202 uint32_t flag; 1203 uint32_t crypto_header; 1204 uint32_t resp_len; 1205 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 1206 1207 if (dst_size == NULL || mbox_error == NULL) { 1208 return INTEL_SIP_SMC_STATUS_REJECTED; 1209 } 1210 1211 if (fcs_sha_get_digest_param.session_id != session_id || 1212 fcs_sha_get_digest_param.context_id != context_id) { 1213 return INTEL_SIP_SMC_STATUS_REJECTED; 1214 } 1215 1216 /* Source data must be 8 bytes aligned */ 1217 if (!is_8_bytes_aligned(src_size)) { 1218 return INTEL_SIP_SMC_STATUS_REJECTED; 1219 } 1220 1221 if (!is_address_in_ddr_range(src_addr, src_size) || 1222 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1223 return INTEL_SIP_SMC_STATUS_REJECTED; 1224 } 1225 1226 resp_len = *dst_size / MBOX_WORD_BYTE; 1227 1228 /* Prepare crypto header */ 1229 flag = 0; 1230 1231 if (fcs_sha_get_digest_param.is_updated) { 1232 fcs_sha_get_digest_param.crypto_param_size = 0; 1233 } else { 1234 flag |= FCS_CS_FIELD_FLAG_INIT; 1235 } 1236 1237 if (is_finalised != 0U) { 1238 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1239 } else { 1240 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1241 fcs_sha_get_digest_param.is_updated = 1; 1242 } 1243 1244 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1245 (fcs_sha_get_digest_param.crypto_param_size & 1246 FCS_CS_FIELD_SIZE_MASK)); 1247 1248 /* Prepare command payload */ 1249 i = 0; 1250 payload[i] = fcs_sha_get_digest_param.session_id; 1251 i++; 1252 payload[i] = fcs_sha_get_digest_param.context_id; 1253 i++; 1254 payload[i] = crypto_header; 1255 i++; 1256 1257 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1258 FCS_CS_FIELD_FLAG_INIT) { 1259 payload[i] = fcs_sha_get_digest_param.key_id; 1260 i++; 1261 /* Crypto parameters */ 1262 payload[i] = fcs_sha_get_digest_param.crypto_param 1263 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1264 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1265 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1266 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1267 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1268 i++; 1269 } 1270 /* Data source address and size */ 1271 1272 /* On the Agilex5 platform, we will use the SMMU payload address */ 1273 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 1274 payload[i] = smmu_src_addr; 1275 #else 1276 payload[i] = src_addr; 1277 #endif 1278 i++; 1279 payload[i] = src_size; 1280 i++; 1281 1282 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE) || 1283 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE)) ? 1284 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1285 GET_JOB_ID(trans_id), 1286 MBOX_FCS_GET_DIGEST_REQ, 1287 payload, 1288 i, 1289 MBOX_CMD_FLAG_CASUAL, 1290 fcs_cs_get_digest_cb, 1291 (uint32_t *)dst_addr, 1292 2U) : 1293 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ, 1294 payload, i, CMD_CASUAL, 1295 (uint32_t *) dst_addr, &resp_len); 1296 1297 if (is_finalised != 0U) { 1298 memset((void *)&fcs_sha_get_digest_param, 0, 1299 sizeof(fcs_crypto_service_data)); 1300 } 1301 1302 if (status < 0) { 1303 *mbox_error = -status; 1304 return INTEL_SIP_SMC_STATUS_ERROR; 1305 } 1306 1307 *dst_size = resp_len * MBOX_WORD_BYTE; 1308 flush_dcache_range(dst_addr, *dst_size); 1309 1310 return INTEL_SIP_SMC_STATUS_OK; 1311 } 1312 1313 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, 1314 uint32_t context_id, uint32_t src_addr, 1315 uint32_t src_size, uint64_t dst_addr, 1316 uint32_t *dst_size, uint8_t is_finalised, 1317 uint32_t *mbox_error, uint32_t *send_id) 1318 { 1319 int status; 1320 uint32_t i; 1321 uint32_t flag; 1322 uint32_t crypto_header; 1323 uint32_t resp_len; 1324 uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U}; 1325 1326 /* Source data must be 8 bytes aligned */ 1327 if (dst_size == NULL || mbox_error == NULL || 1328 !is_8_bytes_aligned(src_size)) { 1329 return INTEL_SIP_SMC_STATUS_REJECTED; 1330 } 1331 1332 if (fcs_sha_get_digest_param.session_id != session_id || 1333 fcs_sha_get_digest_param.context_id != context_id) { 1334 return INTEL_SIP_SMC_STATUS_REJECTED; 1335 } 1336 1337 if (!is_address_in_ddr_range(src_addr, src_size) || 1338 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1339 return INTEL_SIP_SMC_STATUS_REJECTED; 1340 } 1341 1342 resp_len = *dst_size / MBOX_WORD_BYTE; 1343 1344 /* Prepare crypto header */ 1345 flag = 0; 1346 1347 if (fcs_sha_get_digest_param.is_updated) { 1348 fcs_sha_get_digest_param.crypto_param_size = 0; 1349 } else { 1350 flag |= FCS_CS_FIELD_FLAG_INIT; 1351 } 1352 1353 if (is_finalised != 0U) { 1354 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1355 } else { 1356 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1357 fcs_sha_get_digest_param.is_updated = 1; 1358 } 1359 1360 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1361 (fcs_sha_get_digest_param.crypto_param_size & 1362 FCS_CS_FIELD_SIZE_MASK)); 1363 1364 /* Prepare command payload */ 1365 i = 0; 1366 payload[i] = fcs_sha_get_digest_param.session_id; 1367 i++; 1368 payload[i] = fcs_sha_get_digest_param.context_id; 1369 i++; 1370 payload[i] = crypto_header; 1371 i++; 1372 1373 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1374 FCS_CS_FIELD_FLAG_INIT) { 1375 payload[i] = fcs_sha_get_digest_param.key_id; 1376 i++; 1377 /* Crypto parameters */ 1378 payload[i] = fcs_sha_get_digest_param.crypto_param 1379 & INTEL_SIP_SMC_FCS_SHA_MODE_MASK; 1380 payload[i] |= ((fcs_sha_get_digest_param.crypto_param 1381 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1382 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1383 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1384 i++; 1385 } 1386 /* Data source address and size */ 1387 payload[i] = src_addr; 1388 i++; 1389 payload[i] = src_size; 1390 i++; 1391 1392 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ, 1393 payload, i, CMD_INDIRECT); 1394 1395 if (is_finalised != 0U) { 1396 memset((void *)&fcs_sha_get_digest_param, 0, 1397 sizeof(fcs_crypto_service_data)); 1398 } 1399 1400 if (status < 0) { 1401 *mbox_error = -status; 1402 return INTEL_SIP_SMC_STATUS_ERROR; 1403 } 1404 1405 *dst_size = resp_len * MBOX_WORD_BYTE; 1406 flush_dcache_range(dst_addr, *dst_size); 1407 1408 return INTEL_SIP_SMC_STATUS_OK; 1409 } 1410 1411 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id, 1412 uint32_t key_id, uint32_t param_size, 1413 uint64_t param_data, uint32_t *mbox_error) 1414 { 1415 return intel_fcs_crypto_service_init(session_id, context_id, 1416 key_id, param_size, param_data, 1417 (void *) &fcs_sha_mac_verify_param, 1418 mbox_error); 1419 } 1420 1421 int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1422 uint32_t session_id, uint32_t context_id, 1423 uint32_t src_addr, uint32_t src_size, 1424 uint64_t dst_addr, uint32_t *dst_size, 1425 uint32_t data_size, uint8_t is_finalised, 1426 uint32_t *mbox_error, uint64_t smmu_src_addr) 1427 { 1428 int status; 1429 uint32_t i; 1430 uint32_t flag; 1431 uint32_t crypto_header; 1432 uint32_t resp_len; 1433 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1434 uintptr_t mac_offset; 1435 uint32_t dst_size_check = 0; 1436 1437 if (dst_size == NULL || mbox_error == NULL) { 1438 return INTEL_SIP_SMC_STATUS_REJECTED; 1439 } 1440 1441 if (fcs_sha_mac_verify_param.session_id != session_id || 1442 fcs_sha_mac_verify_param.context_id != context_id) { 1443 return INTEL_SIP_SMC_STATUS_REJECTED; 1444 } 1445 1446 if (data_size > src_size) { 1447 return INTEL_SIP_SMC_STATUS_REJECTED; 1448 } 1449 1450 if (!is_size_4_bytes_aligned(src_size) || 1451 !is_8_bytes_aligned(data_size)) { 1452 return INTEL_SIP_SMC_STATUS_REJECTED; 1453 } 1454 1455 if (!is_address_in_ddr_range(src_addr, src_size) || 1456 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1457 return INTEL_SIP_SMC_STATUS_REJECTED; 1458 } 1459 1460 dst_size_check = *dst_size; 1461 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1462 dst_size_check < FCS_MIN_DATA_SIZE) || 1463 (src_size > FCS_MAX_DATA_SIZE || 1464 src_size < FCS_MIN_DATA_SIZE)) { 1465 return INTEL_SIP_SMC_STATUS_REJECTED; 1466 } 1467 1468 resp_len = *dst_size / MBOX_WORD_BYTE; 1469 1470 /* Prepare crypto header */ 1471 flag = 0; 1472 1473 if (fcs_sha_mac_verify_param.is_updated) { 1474 fcs_sha_mac_verify_param.crypto_param_size = 0; 1475 } else { 1476 flag |= FCS_CS_FIELD_FLAG_INIT; 1477 } 1478 1479 if (is_finalised) { 1480 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1481 } else { 1482 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1483 fcs_sha_mac_verify_param.is_updated = 1; 1484 } 1485 1486 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1487 (fcs_sha_mac_verify_param.crypto_param_size & 1488 FCS_CS_FIELD_SIZE_MASK)); 1489 1490 /* Prepare command payload */ 1491 i = 0; 1492 payload[i] = fcs_sha_mac_verify_param.session_id; 1493 i++; 1494 payload[i] = fcs_sha_mac_verify_param.context_id; 1495 i++; 1496 payload[i] = crypto_header; 1497 i++; 1498 1499 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1500 FCS_CS_FIELD_FLAG_INIT) { 1501 payload[i] = fcs_sha_mac_verify_param.key_id; 1502 i++; 1503 /* Crypto parameters */ 1504 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1505 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1506 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1507 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1508 i++; 1509 } 1510 1511 /* Data source address and size */ 1512 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 1513 payload[i] = (uint32_t)smmu_src_addr; 1514 #else 1515 payload[i] = src_addr; 1516 #endif 1517 i++; 1518 payload[i] = data_size; 1519 i++; 1520 1521 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1522 FCS_CS_FIELD_FLAG_FINALIZE) { 1523 /* Copy mac data to command */ 1524 mac_offset = src_addr + data_size; 1525 1526 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1527 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1528 return INTEL_SIP_SMC_STATUS_REJECTED; 1529 } 1530 1531 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 1532 (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE); 1533 1534 i += (src_size - data_size) / MBOX_WORD_BYTE; 1535 } 1536 1537 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE) || 1538 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE)) ? 1539 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1540 GET_JOB_ID(trans_id), 1541 MBOX_FCS_MAC_VERIFY_REQ, 1542 payload, 1543 i, 1544 MBOX_CMD_FLAG_CASUAL, 1545 fcs_cs_mac_verify_cb, 1546 (uint32_t *)dst_addr, 1547 2U) : 1548 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ, 1549 payload, i, CMD_CASUAL, 1550 (uint32_t *) dst_addr, &resp_len); 1551 1552 if (is_finalised) { 1553 memset((void *)&fcs_sha_mac_verify_param, 0, 1554 sizeof(fcs_crypto_service_data)); 1555 } 1556 1557 if (status < 0) { 1558 *mbox_error = -status; 1559 return INTEL_SIP_SMC_STATUS_ERROR; 1560 } 1561 1562 *dst_size = resp_len * MBOX_WORD_BYTE; 1563 flush_dcache_range(dst_addr, *dst_size); 1564 1565 return INTEL_SIP_SMC_STATUS_OK; 1566 } 1567 1568 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, 1569 uint32_t context_id, uint32_t src_addr, 1570 uint32_t src_size, uint64_t dst_addr, 1571 uint32_t *dst_size, uint32_t data_size, 1572 uint8_t is_finalised, uint32_t *mbox_error, 1573 uint32_t *send_id) 1574 { 1575 int status; 1576 uint32_t i; 1577 uint32_t flag; 1578 uint32_t crypto_header; 1579 uint32_t resp_len; 1580 uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1581 uintptr_t mac_offset; 1582 uint32_t dst_size_check = 0; 1583 /* 1584 * Source data must be 4 bytes aligned 1585 * User data must be 8 bytes aligned 1586 */ 1587 if (dst_size == NULL || mbox_error == NULL || 1588 !is_size_4_bytes_aligned(src_size) || 1589 !is_8_bytes_aligned(data_size)) { 1590 return INTEL_SIP_SMC_STATUS_REJECTED; 1591 } 1592 1593 if (data_size > src_size) { 1594 return INTEL_SIP_SMC_STATUS_REJECTED; 1595 } 1596 1597 if (fcs_sha_mac_verify_param.session_id != session_id || 1598 fcs_sha_mac_verify_param.context_id != context_id) { 1599 return INTEL_SIP_SMC_STATUS_REJECTED; 1600 } 1601 1602 if (!is_address_in_ddr_range(src_addr, src_size) || 1603 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1604 return INTEL_SIP_SMC_STATUS_REJECTED; 1605 } 1606 1607 dst_size_check = *dst_size; 1608 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1609 dst_size_check < FCS_MIN_DATA_SIZE) || 1610 (src_size > FCS_MAX_DATA_SIZE || 1611 src_size < FCS_MIN_DATA_SIZE)) { 1612 return INTEL_SIP_SMC_STATUS_REJECTED; 1613 } 1614 1615 resp_len = *dst_size / MBOX_WORD_BYTE; 1616 1617 /* Prepare crypto header */ 1618 flag = 0; 1619 1620 if (fcs_sha_mac_verify_param.is_updated) { 1621 fcs_sha_mac_verify_param.crypto_param_size = 0; 1622 } else { 1623 flag |= FCS_CS_FIELD_FLAG_INIT; 1624 } 1625 1626 if (is_finalised) { 1627 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1628 } else { 1629 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1630 fcs_sha_mac_verify_param.is_updated = 1; 1631 } 1632 1633 crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) | 1634 (fcs_sha_mac_verify_param.crypto_param_size & 1635 FCS_CS_FIELD_SIZE_MASK)); 1636 1637 /* Prepare command payload */ 1638 i = 0; 1639 payload[i] = fcs_sha_mac_verify_param.session_id; 1640 i++; 1641 payload[i] = fcs_sha_mac_verify_param.context_id; 1642 i++; 1643 payload[i] = crypto_header; 1644 i++; 1645 1646 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1647 FCS_CS_FIELD_FLAG_INIT) { 1648 payload[i] = fcs_sha_mac_verify_param.key_id; 1649 i++; 1650 /* Crypto parameters */ 1651 payload[i] = ((fcs_sha_mac_verify_param.crypto_param 1652 >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET) 1653 & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK) 1654 << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET; 1655 i++; 1656 } 1657 /* Data source address and size */ 1658 payload[i] = src_addr; 1659 i++; 1660 payload[i] = data_size; 1661 i++; 1662 1663 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1664 FCS_CS_FIELD_FLAG_FINALIZE) { 1665 /* Copy mac data to command 1666 * Using dst_addr (physical address) to store mac_offset 1667 * mac_offset = MAC data 1668 */ 1669 mac_offset = dst_addr; 1670 1671 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 1672 FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE) { 1673 return INTEL_SIP_SMC_STATUS_REJECTED; 1674 } 1675 1676 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 1677 (void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE); 1678 1679 memset((void *) dst_addr, 0, *dst_size); 1680 1681 i += (src_size - data_size) / MBOX_WORD_BYTE; 1682 } 1683 1684 status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ, 1685 payload, i, CMD_INDIRECT); 1686 1687 if (is_finalised) { 1688 memset((void *)&fcs_sha_mac_verify_param, 0, 1689 sizeof(fcs_crypto_service_data)); 1690 } 1691 1692 if (status < 0) { 1693 *mbox_error = -status; 1694 return INTEL_SIP_SMC_STATUS_ERROR; 1695 } 1696 1697 *dst_size = resp_len * MBOX_WORD_BYTE; 1698 flush_dcache_range(dst_addr, *dst_size); 1699 1700 return INTEL_SIP_SMC_STATUS_OK; 1701 } 1702 1703 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id, 1704 uint32_t key_id, uint32_t param_size, 1705 uint64_t param_data, uint32_t *mbox_error) 1706 { 1707 return intel_fcs_crypto_service_init(session_id, context_id, 1708 key_id, param_size, param_data, 1709 (void *) &fcs_ecdsa_hash_sign_param, 1710 mbox_error); 1711 } 1712 1713 int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id, 1714 uint32_t session_id, uint32_t context_id, 1715 uint32_t src_addr, uint32_t src_size, 1716 uint64_t dst_addr, uint32_t *dst_size, 1717 uint32_t *mbox_error) 1718 { 1719 int status; 1720 uint32_t i; 1721 uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1722 uint32_t resp_len; 1723 uintptr_t hash_data_addr; 1724 uint32_t dst_size_check = 0; 1725 1726 if ((dst_size == NULL) || (mbox_error == NULL)) { 1727 return INTEL_SIP_SMC_STATUS_REJECTED; 1728 } 1729 1730 if (fcs_ecdsa_hash_sign_param.session_id != session_id || 1731 fcs_ecdsa_hash_sign_param.context_id != context_id) { 1732 return INTEL_SIP_SMC_STATUS_REJECTED; 1733 } 1734 1735 if (!is_address_in_ddr_range(src_addr, src_size) || 1736 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1737 return INTEL_SIP_SMC_STATUS_REJECTED; 1738 } 1739 1740 dst_size_check = *dst_size; 1741 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1742 dst_size_check < FCS_MIN_DATA_SIZE) || 1743 (src_size > FCS_MAX_DATA_SIZE || 1744 src_size < FCS_MIN_DATA_SIZE)) { 1745 return INTEL_SIP_SMC_STATUS_REJECTED; 1746 } 1747 1748 resp_len = *dst_size / MBOX_WORD_BYTE; 1749 1750 /* Prepare command payload */ 1751 /* Crypto header */ 1752 i = 0; 1753 payload[i] = fcs_ecdsa_hash_sign_param.session_id; 1754 i++; 1755 payload[i] = fcs_ecdsa_hash_sign_param.context_id; 1756 1757 i++; 1758 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size 1759 & FCS_CS_FIELD_SIZE_MASK; 1760 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1761 | FCS_CS_FIELD_FLAG_FINALIZE) 1762 << FCS_CS_FIELD_FLAG_OFFSET; 1763 i++; 1764 payload[i] = fcs_ecdsa_hash_sign_param.key_id; 1765 1766 /* Crypto parameters */ 1767 i++; 1768 payload[i] = fcs_ecdsa_hash_sign_param.crypto_param 1769 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1770 1771 /* Hash Data */ 1772 i++; 1773 hash_data_addr = src_addr; 1774 1775 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1776 FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE) { 1777 return INTEL_SIP_SMC_STATUS_REJECTED; 1778 } 1779 1780 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 1781 (void *) hash_data_addr, src_size / MBOX_WORD_BYTE); 1782 1783 i += src_size / MBOX_WORD_BYTE; 1784 1785 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE) ? 1786 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1787 GET_JOB_ID(trans_id), 1788 MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1789 payload, 1790 i, 1791 MBOX_CMD_FLAG_CASUAL, 1792 fcs_cs_hash_sign_req_cb, 1793 (uint32_t *)dst_addr, 1794 2U) : 1795 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ, 1796 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1797 &resp_len); 1798 1799 memset((void *) &fcs_ecdsa_hash_sign_param, 1800 0, sizeof(fcs_crypto_service_data)); 1801 1802 if (status < 0) { 1803 *mbox_error = -status; 1804 return INTEL_SIP_SMC_STATUS_ERROR; 1805 } 1806 1807 *dst_size = resp_len * MBOX_WORD_BYTE; 1808 flush_dcache_range(dst_addr, *dst_size); 1809 1810 return INTEL_SIP_SMC_STATUS_OK; 1811 } 1812 1813 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id, 1814 uint32_t key_id, uint32_t param_size, 1815 uint64_t param_data, uint32_t *mbox_error) 1816 { 1817 return intel_fcs_crypto_service_init(session_id, context_id, 1818 key_id, param_size, param_data, 1819 (void *) &fcs_ecdsa_hash_sig_verify_param, 1820 mbox_error); 1821 } 1822 1823 int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id, 1824 uint32_t session_id, uint32_t context_id, 1825 uint32_t src_addr, uint32_t src_size, 1826 uint64_t dst_addr, uint32_t *dst_size, 1827 uint32_t *mbox_error) 1828 { 1829 int status; 1830 uint32_t i = 0; 1831 uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 1832 uint32_t resp_len; 1833 uintptr_t hash_sig_pubkey_addr; 1834 uint32_t dst_size_check = 0; 1835 1836 if ((dst_size == NULL) || (mbox_error == NULL)) { 1837 return INTEL_SIP_SMC_STATUS_REJECTED; 1838 } 1839 1840 if ((fcs_ecdsa_hash_sig_verify_param.session_id != session_id) || 1841 (fcs_ecdsa_hash_sig_verify_param.context_id != context_id)) { 1842 return INTEL_SIP_SMC_STATUS_REJECTED; 1843 } 1844 1845 if (!is_address_in_ddr_range(src_addr, src_size) || 1846 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1847 return INTEL_SIP_SMC_STATUS_REJECTED; 1848 } 1849 1850 dst_size_check = *dst_size; 1851 if ((dst_size_check > FCS_MAX_DATA_SIZE || 1852 dst_size_check < FCS_MIN_DATA_SIZE) || 1853 (src_size > FCS_MAX_DATA_SIZE || 1854 src_size < FCS_MIN_DATA_SIZE)) { 1855 return INTEL_SIP_SMC_STATUS_REJECTED; 1856 } 1857 1858 resp_len = *dst_size / MBOX_WORD_BYTE; 1859 1860 /* Prepare command payload */ 1861 /* Crypto header */ 1862 i = 0; 1863 payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id; 1864 1865 i++; 1866 payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id; 1867 1868 i++; 1869 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size 1870 & FCS_CS_FIELD_SIZE_MASK; 1871 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 1872 | FCS_CS_FIELD_FLAG_FINALIZE) 1873 << FCS_CS_FIELD_FLAG_OFFSET; 1874 1875 i++; 1876 payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id; 1877 1878 /* Crypto parameters */ 1879 i++; 1880 payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param 1881 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 1882 1883 /* Hash Data Word, Signature Data Word and Public Key Data word */ 1884 i++; 1885 hash_sig_pubkey_addr = src_addr; 1886 1887 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 1888 FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 1889 return INTEL_SIP_SMC_STATUS_REJECTED; 1890 } 1891 1892 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 1893 (void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE); 1894 1895 i += (src_size / MBOX_WORD_BYTE); 1896 1897 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE) ? 1898 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 1899 GET_JOB_ID(trans_id), 1900 MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1901 payload, 1902 i, 1903 MBOX_CMD_FLAG_CASUAL, 1904 fcs_cs_hash_sig_verify_req_cb, 1905 (uint32_t *)dst_addr, 1906 2U) : 1907 1908 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY, 1909 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 1910 &resp_len); 1911 1912 memset((void *)&fcs_ecdsa_hash_sig_verify_param, 1913 0, sizeof(fcs_crypto_service_data)); 1914 1915 if (status < 0) { 1916 *mbox_error = -status; 1917 return INTEL_SIP_SMC_STATUS_ERROR; 1918 } 1919 1920 *dst_size = resp_len * MBOX_WORD_BYTE; 1921 flush_dcache_range(dst_addr, *dst_size); 1922 1923 return INTEL_SIP_SMC_STATUS_OK; 1924 } 1925 1926 int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id, 1927 uint32_t context_id, uint32_t key_id, 1928 uint32_t param_size, uint64_t param_data, 1929 uint32_t *mbox_error) 1930 { 1931 return intel_fcs_crypto_service_init(session_id, context_id, 1932 key_id, param_size, param_data, 1933 (void *) &fcs_sha2_data_sign_param, 1934 mbox_error); 1935 } 1936 1937 int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id, 1938 uint32_t session_id, uint32_t context_id, 1939 uint32_t src_addr, uint32_t src_size, 1940 uint64_t dst_addr, uint32_t *dst_size, 1941 uint8_t is_finalised, uint32_t *mbox_error, 1942 uint64_t smmu_src_addr) 1943 { 1944 int status; 1945 int i; 1946 uint32_t flag; 1947 uint32_t crypto_header; 1948 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 1949 uint32_t resp_len; 1950 1951 if ((dst_size == NULL) || (mbox_error == NULL)) { 1952 return INTEL_SIP_SMC_STATUS_REJECTED; 1953 } 1954 1955 if (fcs_sha2_data_sign_param.session_id != session_id || 1956 fcs_sha2_data_sign_param.context_id != context_id) { 1957 return INTEL_SIP_SMC_STATUS_REJECTED; 1958 } 1959 1960 /* Source data must be 8 bytes aligned */ 1961 if (!is_8_bytes_aligned(src_size)) { 1962 return INTEL_SIP_SMC_STATUS_REJECTED; 1963 } 1964 1965 if (!is_address_in_ddr_range(src_addr, src_size) || 1966 !is_address_in_ddr_range(dst_addr, *dst_size)) { 1967 return INTEL_SIP_SMC_STATUS_REJECTED; 1968 } 1969 1970 resp_len = *dst_size / MBOX_WORD_BYTE; 1971 1972 /* Prepare crypto header */ 1973 flag = 0; 1974 if (fcs_sha2_data_sign_param.is_updated) { 1975 fcs_sha2_data_sign_param.crypto_param_size = 0; 1976 } else { 1977 flag |= FCS_CS_FIELD_FLAG_INIT; 1978 } 1979 1980 if (is_finalised != 0U) { 1981 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 1982 } else { 1983 flag |= FCS_CS_FIELD_FLAG_UPDATE; 1984 fcs_sha2_data_sign_param.is_updated = 1; 1985 } 1986 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 1987 fcs_sha2_data_sign_param.crypto_param_size; 1988 1989 /* Prepare command payload */ 1990 i = 0; 1991 payload[i] = fcs_sha2_data_sign_param.session_id; 1992 i++; 1993 payload[i] = fcs_sha2_data_sign_param.context_id; 1994 i++; 1995 payload[i] = crypto_header; 1996 i++; 1997 1998 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 1999 FCS_CS_FIELD_FLAG_INIT) { 2000 payload[i] = fcs_sha2_data_sign_param.key_id; 2001 /* Crypto parameters */ 2002 i++; 2003 payload[i] = fcs_sha2_data_sign_param.crypto_param 2004 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2005 i++; 2006 } 2007 2008 /* Data source address and size */ 2009 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2010 payload[i] = (uint32_t)smmu_src_addr; 2011 #else 2012 payload[i] = src_addr; 2013 #endif 2014 i++; 2015 payload[i] = src_size; 2016 i++; 2017 2018 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE) || 2019 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)) ? 2020 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2021 GET_JOB_ID(trans_id), 2022 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 2023 payload, 2024 i, 2025 MBOX_CMD_FLAG_CASUAL, 2026 fcs_cs_data_sign_req_cb, 2027 (uint32_t *)dst_addr, 2028 2U) : 2029 mailbox_send_cmd(MBOX_JOB_ID, 2030 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload, 2031 i, CMD_CASUAL, (uint32_t *) dst_addr, 2032 &resp_len); 2033 2034 if (is_finalised != 0U) { 2035 memset((void *)&fcs_sha2_data_sign_param, 0, 2036 sizeof(fcs_crypto_service_data)); 2037 } 2038 2039 if (status < 0) { 2040 *mbox_error = -status; 2041 return INTEL_SIP_SMC_STATUS_ERROR; 2042 } 2043 2044 *dst_size = resp_len * MBOX_WORD_BYTE; 2045 flush_dcache_range(dst_addr, *dst_size); 2046 2047 return INTEL_SIP_SMC_STATUS_OK; 2048 } 2049 2050 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id, 2051 uint32_t context_id, uint32_t src_addr, 2052 uint32_t src_size, uint64_t dst_addr, 2053 uint32_t *dst_size, uint8_t is_finalised, 2054 uint32_t *mbox_error, uint32_t *send_id) 2055 { 2056 int status; 2057 int i; 2058 uint32_t flag; 2059 uint32_t crypto_header; 2060 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U}; 2061 uint32_t resp_len; 2062 2063 /* Source data must be 8 bytes aligned */ 2064 if ((dst_size == NULL) || (mbox_error == NULL || 2065 !is_8_bytes_aligned(src_size))) { 2066 return INTEL_SIP_SMC_STATUS_REJECTED; 2067 } 2068 2069 if (fcs_sha2_data_sign_param.session_id != session_id || 2070 fcs_sha2_data_sign_param.context_id != context_id) { 2071 return INTEL_SIP_SMC_STATUS_REJECTED; 2072 } 2073 2074 if (!is_address_in_ddr_range(src_addr, src_size) || 2075 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2076 return INTEL_SIP_SMC_STATUS_REJECTED; 2077 } 2078 2079 resp_len = *dst_size / MBOX_WORD_BYTE; 2080 2081 /* Prepare crypto header */ 2082 flag = 0; 2083 if (fcs_sha2_data_sign_param.is_updated) { 2084 fcs_sha2_data_sign_param.crypto_param_size = 0; 2085 } else { 2086 flag |= FCS_CS_FIELD_FLAG_INIT; 2087 } 2088 2089 if (is_finalised != 0U) { 2090 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2091 } else { 2092 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2093 fcs_sha2_data_sign_param.is_updated = 1; 2094 } 2095 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2096 fcs_sha2_data_sign_param.crypto_param_size; 2097 2098 /* Prepare command payload */ 2099 i = 0; 2100 payload[i] = fcs_sha2_data_sign_param.session_id; 2101 i++; 2102 payload[i] = fcs_sha2_data_sign_param.context_id; 2103 i++; 2104 payload[i] = crypto_header; 2105 i++; 2106 2107 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2108 FCS_CS_FIELD_FLAG_INIT) { 2109 payload[i] = fcs_sha2_data_sign_param.key_id; 2110 /* Crypto parameters */ 2111 i++; 2112 payload[i] = fcs_sha2_data_sign_param.crypto_param 2113 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2114 i++; 2115 } 2116 2117 /* Data source address and size */ 2118 payload[i] = src_addr; 2119 i++; 2120 payload[i] = src_size; 2121 i++; 2122 2123 status = mailbox_send_cmd_async(send_id, 2124 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, 2125 payload, i, CMD_INDIRECT); 2126 2127 if (is_finalised != 0U) { 2128 memset((void *)&fcs_sha2_data_sign_param, 0, 2129 sizeof(fcs_crypto_service_data)); 2130 } 2131 2132 if (status < 0) { 2133 *mbox_error = -status; 2134 return INTEL_SIP_SMC_STATUS_ERROR; 2135 } 2136 2137 *dst_size = resp_len * MBOX_WORD_BYTE; 2138 flush_dcache_range(dst_addr, *dst_size); 2139 2140 return INTEL_SIP_SMC_STATUS_OK; 2141 } 2142 2143 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id, 2144 uint32_t context_id, uint32_t key_id, 2145 uint32_t param_size, uint64_t param_data, 2146 uint32_t *mbox_error) 2147 { 2148 return intel_fcs_crypto_service_init(session_id, context_id, 2149 key_id, param_size, param_data, 2150 (void *) &fcs_sha2_data_sig_verify_param, 2151 mbox_error); 2152 } 2153 2154 int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id, 2155 uint32_t session_id, uint32_t context_id, 2156 uint32_t src_addr, uint32_t src_size, 2157 uint64_t dst_addr, uint32_t *dst_size, 2158 uint32_t data_size, uint8_t is_finalised, 2159 uint32_t *mbox_error, uint64_t smmu_src_addr) 2160 { 2161 int status; 2162 uint32_t i; 2163 uint32_t flag; 2164 uint32_t crypto_header; 2165 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 2166 uint32_t resp_len; 2167 uintptr_t sig_pubkey_offset; 2168 uint32_t dst_size_check = 0; 2169 2170 if ((dst_size == NULL) || (mbox_error == NULL)) { 2171 return INTEL_SIP_SMC_STATUS_REJECTED; 2172 } 2173 2174 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 2175 fcs_sha2_data_sig_verify_param.context_id != context_id) { 2176 return INTEL_SIP_SMC_STATUS_REJECTED; 2177 } 2178 2179 if (data_size > src_size) { 2180 return INTEL_SIP_SMC_STATUS_REJECTED; 2181 } 2182 2183 if (!is_size_4_bytes_aligned(src_size)) { 2184 return INTEL_SIP_SMC_STATUS_REJECTED; 2185 } 2186 2187 if (!is_8_bytes_aligned(data_size) || 2188 !is_8_bytes_aligned(src_addr)) { 2189 return INTEL_SIP_SMC_STATUS_REJECTED; 2190 } 2191 2192 if (!is_address_in_ddr_range(src_addr, src_size) || 2193 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2194 return INTEL_SIP_SMC_STATUS_REJECTED; 2195 } 2196 2197 dst_size_check = *dst_size; 2198 if ((dst_size_check > FCS_MAX_DATA_SIZE || 2199 dst_size_check < FCS_MIN_DATA_SIZE) || 2200 (src_size > FCS_MAX_DATA_SIZE || 2201 src_size < FCS_MIN_DATA_SIZE)) { 2202 return INTEL_SIP_SMC_STATUS_REJECTED; 2203 } 2204 2205 resp_len = *dst_size / MBOX_WORD_BYTE; 2206 2207 /* Prepare crypto header */ 2208 flag = 0; 2209 if (fcs_sha2_data_sig_verify_param.is_updated) 2210 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 2211 else 2212 flag |= FCS_CS_FIELD_FLAG_INIT; 2213 2214 if (is_finalised != 0U) 2215 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2216 else { 2217 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2218 fcs_sha2_data_sig_verify_param.is_updated = 1; 2219 } 2220 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2221 fcs_sha2_data_sig_verify_param.crypto_param_size; 2222 2223 /* Prepare command payload */ 2224 i = 0; 2225 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 2226 i++; 2227 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 2228 i++; 2229 payload[i] = crypto_header; 2230 i++; 2231 2232 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2233 FCS_CS_FIELD_FLAG_INIT) { 2234 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 2235 i++; 2236 /* Crypto parameters */ 2237 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 2238 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2239 i++; 2240 } 2241 2242 /* Data source address and size */ 2243 /* On the Agilex5 platform, the SMMU remapped address is used */ 2244 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2245 payload[i] = smmu_src_addr; 2246 #else 2247 payload[i] = src_addr; 2248 #endif 2249 i++; 2250 payload[i] = data_size; 2251 i++; 2252 2253 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2254 FCS_CS_FIELD_FLAG_FINALIZE) { 2255 /* Signature + Public Key Data */ 2256 sig_pubkey_offset = src_addr + data_size; 2257 2258 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 2259 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 2260 return INTEL_SIP_SMC_STATUS_REJECTED; 2261 } 2262 2263 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 2264 (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE); 2265 2266 i += (src_size - data_size) / MBOX_WORD_BYTE; 2267 } 2268 2269 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE) || 2270 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE)) ? 2271 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2272 GET_JOB_ID(trans_id), 2273 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 2274 payload, 2275 i, 2276 MBOX_CMD_FLAG_CASUAL, 2277 fcs_cs_data_sig_verify_req_cb, 2278 (uint32_t *)dst_addr, 2279 2U) : 2280 mailbox_send_cmd(MBOX_JOB_ID, 2281 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i, 2282 CMD_CASUAL, (uint32_t *) dst_addr, &resp_len); 2283 2284 if (is_finalised != 0U) { 2285 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 2286 sizeof(fcs_crypto_service_data)); 2287 } 2288 2289 if (status < 0) { 2290 *mbox_error = -status; 2291 return INTEL_SIP_SMC_STATUS_ERROR; 2292 } 2293 2294 *dst_size = resp_len * MBOX_WORD_BYTE; 2295 flush_dcache_range(dst_addr, *dst_size); 2296 2297 return INTEL_SIP_SMC_STATUS_OK; 2298 } 2299 2300 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id, 2301 uint32_t context_id, uint32_t src_addr, 2302 uint32_t src_size, uint64_t dst_addr, 2303 uint32_t *dst_size, uint32_t data_size, 2304 uint8_t is_finalised, uint32_t *mbox_error, 2305 uint32_t *send_id) 2306 { 2307 int status; 2308 uint32_t i; 2309 uint32_t flag; 2310 uint32_t crypto_header; 2311 uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U}; 2312 uint32_t resp_len; 2313 uintptr_t sig_pubkey_offset; 2314 uint32_t dst_size_check = 0; 2315 2316 /* 2317 * Source data must be 4 bytes aligned 2318 * Source address must be 8 bytes aligned 2319 * User data must be 8 bytes aligned 2320 */ 2321 if ((dst_size == NULL) || (mbox_error == NULL) || 2322 !is_size_4_bytes_aligned(src_size) || 2323 !is_8_bytes_aligned(src_addr) || 2324 !is_8_bytes_aligned(data_size)) { 2325 return INTEL_SIP_SMC_STATUS_REJECTED; 2326 } 2327 2328 if (fcs_sha2_data_sig_verify_param.session_id != session_id || 2329 fcs_sha2_data_sig_verify_param.context_id != context_id) { 2330 return INTEL_SIP_SMC_STATUS_REJECTED; 2331 } 2332 2333 if (data_size > src_size) { 2334 return INTEL_SIP_SMC_STATUS_REJECTED; 2335 } 2336 2337 if (!is_address_in_ddr_range(src_addr, src_size) || 2338 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2339 return INTEL_SIP_SMC_STATUS_REJECTED; 2340 } 2341 2342 dst_size_check = *dst_size; 2343 if ((dst_size_check > FCS_MAX_DATA_SIZE || 2344 dst_size_check < FCS_MIN_DATA_SIZE) || 2345 (src_size > FCS_MAX_DATA_SIZE || 2346 src_size < FCS_MIN_DATA_SIZE)) { 2347 return INTEL_SIP_SMC_STATUS_REJECTED; 2348 } 2349 2350 resp_len = *dst_size / MBOX_WORD_BYTE; 2351 2352 /* Prepare crypto header */ 2353 flag = 0; 2354 if (fcs_sha2_data_sig_verify_param.is_updated) 2355 fcs_sha2_data_sig_verify_param.crypto_param_size = 0; 2356 else 2357 flag |= FCS_CS_FIELD_FLAG_INIT; 2358 2359 if (is_finalised != 0U) 2360 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2361 else { 2362 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2363 fcs_sha2_data_sig_verify_param.is_updated = 1; 2364 } 2365 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2366 fcs_sha2_data_sig_verify_param.crypto_param_size; 2367 2368 /* Prepare command payload */ 2369 i = 0; 2370 payload[i] = fcs_sha2_data_sig_verify_param.session_id; 2371 i++; 2372 payload[i] = fcs_sha2_data_sig_verify_param.context_id; 2373 i++; 2374 payload[i] = crypto_header; 2375 i++; 2376 2377 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2378 FCS_CS_FIELD_FLAG_INIT) { 2379 payload[i] = fcs_sha2_data_sig_verify_param.key_id; 2380 i++; 2381 /* Crypto parameters */ 2382 payload[i] = fcs_sha2_data_sig_verify_param.crypto_param 2383 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2384 i++; 2385 } 2386 2387 /* Data source address and size */ 2388 payload[i] = src_addr; 2389 i++; 2390 payload[i] = data_size; 2391 i++; 2392 2393 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2394 FCS_CS_FIELD_FLAG_FINALIZE) { 2395 /* Copy mac data to command 2396 * Using dst_addr (physical address) to store sig_pubkey_offset 2397 * sig_pubkey_offset is Signature + Public Key Data 2398 */ 2399 sig_pubkey_offset = dst_addr; 2400 2401 if ((i + ((src_size - data_size) / MBOX_WORD_BYTE)) > 2402 FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE) { 2403 return INTEL_SIP_SMC_STATUS_REJECTED; 2404 } 2405 2406 memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE, 2407 (void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE); 2408 2409 memset((void *) dst_addr, 0, *dst_size); 2410 2411 i += (src_size - data_size) / MBOX_WORD_BYTE; 2412 } 2413 2414 status = mailbox_send_cmd_async(send_id, 2415 MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, 2416 payload, i, CMD_INDIRECT); 2417 2418 if (is_finalised != 0U) { 2419 memset((void *) &fcs_sha2_data_sig_verify_param, 0, 2420 sizeof(fcs_crypto_service_data)); 2421 } 2422 2423 if (status < 0) { 2424 *mbox_error = -status; 2425 return INTEL_SIP_SMC_STATUS_ERROR; 2426 } 2427 2428 *dst_size = resp_len * MBOX_WORD_BYTE; 2429 flush_dcache_range(dst_addr, *dst_size); 2430 2431 return INTEL_SIP_SMC_STATUS_OK; 2432 } 2433 2434 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id, 2435 uint32_t key_id, uint32_t param_size, 2436 uint64_t param_data, uint32_t *mbox_error) 2437 { 2438 return intel_fcs_crypto_service_init(session_id, context_id, 2439 key_id, param_size, param_data, 2440 (void *) &fcs_ecdsa_get_pubkey_param, 2441 mbox_error); 2442 } 2443 2444 int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id, 2445 uint32_t session_id, uint32_t context_id, 2446 uint64_t dst_addr, uint32_t *dst_size, 2447 uint32_t *mbox_error) 2448 { 2449 int status; 2450 int i; 2451 uint32_t crypto_header; 2452 uint32_t ret_size; 2453 uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U}; 2454 2455 if ((dst_size == NULL) || (mbox_error == NULL)) { 2456 return INTEL_SIP_SMC_STATUS_REJECTED; 2457 } 2458 2459 if (!is_address_in_ddr_range(dst_addr, *dst_size)) { 2460 return INTEL_SIP_SMC_STATUS_REJECTED; 2461 } 2462 2463 if (fcs_ecdsa_get_pubkey_param.session_id != session_id || 2464 fcs_ecdsa_get_pubkey_param.context_id != context_id) { 2465 return INTEL_SIP_SMC_STATUS_REJECTED; 2466 } 2467 2468 ret_size = *dst_size / MBOX_WORD_BYTE; 2469 2470 crypto_header = ((FCS_CS_FIELD_FLAG_INIT | 2471 FCS_CS_FIELD_FLAG_UPDATE | 2472 FCS_CS_FIELD_FLAG_FINALIZE) << 2473 FCS_CS_FIELD_FLAG_OFFSET) | 2474 fcs_ecdsa_get_pubkey_param.crypto_param_size; 2475 i = 0; 2476 /* Prepare command payload */ 2477 payload[i] = session_id; 2478 i++; 2479 payload[i] = context_id; 2480 i++; 2481 payload[i] = crypto_header; 2482 i++; 2483 payload[i] = fcs_ecdsa_get_pubkey_param.key_id; 2484 i++; 2485 payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param & 2486 INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2487 i++; 2488 2489 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE) ? 2490 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2491 GET_JOB_ID(trans_id), 2492 MBOX_FCS_ECDSA_GET_PUBKEY, 2493 payload, 2494 i, 2495 MBOX_CMD_FLAG_CASUAL, 2496 fcs_cs_get_public_key_cb, 2497 (uint32_t *)dst_addr, 2498 2U) : 2499 mailbox_send_cmd(MBOX_JOB_ID, 2500 MBOX_FCS_ECDSA_GET_PUBKEY, 2501 payload, i, CMD_CASUAL, 2502 (uint32_t *) dst_addr, &ret_size); 2503 2504 memset((void *) &fcs_ecdsa_get_pubkey_param, 0, 2505 sizeof(fcs_crypto_service_data)); 2506 2507 if (status < 0) { 2508 *mbox_error = -status; 2509 return INTEL_SIP_SMC_STATUS_ERROR; 2510 } 2511 2512 *dst_size = ret_size * MBOX_WORD_BYTE; 2513 flush_dcache_range(dst_addr, *dst_size); 2514 2515 return INTEL_SIP_SMC_STATUS_OK; 2516 } 2517 2518 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id, 2519 uint32_t key_id, uint32_t param_size, 2520 uint64_t param_data, uint32_t *mbox_error) 2521 { 2522 return intel_fcs_crypto_service_init(session_id, context_id, 2523 key_id, param_size, param_data, 2524 (void *) &fcs_ecdh_request_param, 2525 mbox_error); 2526 } 2527 2528 int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id, 2529 uint32_t session_id, uint32_t context_id, 2530 uint32_t src_addr, uint32_t src_size, 2531 uint64_t dst_addr, uint32_t *dst_size, 2532 uint32_t *mbox_error) 2533 { 2534 int status; 2535 uint32_t i; 2536 uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U}; 2537 uint32_t resp_len; 2538 uintptr_t pubkey; 2539 uint32_t dst_size_check = 0; 2540 2541 if ((dst_size == NULL) || (mbox_error == NULL)) { 2542 return INTEL_SIP_SMC_STATUS_REJECTED; 2543 } 2544 2545 if (fcs_ecdh_request_param.session_id != session_id || 2546 fcs_ecdh_request_param.context_id != context_id) { 2547 return INTEL_SIP_SMC_STATUS_REJECTED; 2548 } 2549 2550 if (!is_address_in_ddr_range(src_addr, src_size) || 2551 !is_address_in_ddr_range(dst_addr, *dst_size)) { 2552 return INTEL_SIP_SMC_STATUS_REJECTED; 2553 } 2554 2555 dst_size_check = *dst_size; 2556 2557 if ((dst_size_check > FCS_MAX_DATA_SIZE || dst_size_check < FCS_MIN_DATA_SIZE) || 2558 (src_size > FCS_MAX_DATA_SIZE || src_size < FCS_MIN_DATA_SIZE)) { 2559 return INTEL_SIP_SMC_STATUS_REJECTED; 2560 } 2561 2562 resp_len = *dst_size / MBOX_WORD_BYTE; 2563 2564 /* Prepare command payload */ 2565 i = 0; 2566 /* Crypto header */ 2567 payload[i] = fcs_ecdh_request_param.session_id; 2568 i++; 2569 payload[i] = fcs_ecdh_request_param.context_id; 2570 i++; 2571 payload[i] = fcs_ecdh_request_param.crypto_param_size 2572 & FCS_CS_FIELD_SIZE_MASK; 2573 payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE 2574 | FCS_CS_FIELD_FLAG_FINALIZE) 2575 << FCS_CS_FIELD_FLAG_OFFSET; 2576 i++; 2577 payload[i] = fcs_ecdh_request_param.key_id; 2578 i++; 2579 /* Crypto parameters */ 2580 payload[i] = fcs_ecdh_request_param.crypto_param 2581 & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK; 2582 i++; 2583 /* Public key data */ 2584 pubkey = src_addr; 2585 2586 if ((i + ((src_size) / MBOX_WORD_BYTE)) > 2587 FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE) { 2588 return INTEL_SIP_SMC_STATUS_REJECTED; 2589 } 2590 2591 memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE, 2592 (void *) pubkey, src_size / MBOX_WORD_BYTE); 2593 i += src_size / MBOX_WORD_BYTE; 2594 2595 status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE) ? 2596 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2597 GET_JOB_ID(trans_id), 2598 MBOX_FCS_ECDH_REQUEST, 2599 payload, 2600 i, 2601 MBOX_CMD_FLAG_CASUAL, 2602 fcs_cs_ecdh_request_cb, 2603 (uint32_t *)dst_addr, 2604 2U) : 2605 mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST, 2606 payload, i, CMD_CASUAL, (uint32_t *) dst_addr, 2607 &resp_len); 2608 2609 memset((void *)&fcs_ecdh_request_param, 0, 2610 sizeof(fcs_crypto_service_data)); 2611 2612 if (status < 0) { 2613 *mbox_error = -status; 2614 return INTEL_SIP_SMC_STATUS_ERROR; 2615 } 2616 2617 *dst_size = resp_len * MBOX_WORD_BYTE; 2618 flush_dcache_range(dst_addr, *dst_size); 2619 2620 return INTEL_SIP_SMC_STATUS_OK; 2621 } 2622 2623 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id, 2624 uint32_t key_id, uint64_t param_addr, 2625 uint32_t param_size, uint32_t *mbox_error) 2626 { 2627 /* ptr to get param_addr value */ 2628 uint64_t *param_addr_ptr; 2629 2630 param_addr_ptr = (uint64_t *) param_addr; 2631 2632 /* Check if mbox_error is not NULL or 0xF or 0x3FF */ 2633 if (mbox_error == NULL || *mbox_error > 0xF || 2634 (*mbox_error != 0 && *mbox_error != 0x3FF)) { 2635 return INTEL_SIP_SMC_STATUS_REJECTED; 2636 } 2637 2638 /* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */ 2639 if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) { 2640 return INTEL_SIP_SMC_STATUS_REJECTED; 2641 } 2642 2643 /* 2644 * Check if not ECB, CBC and CTR, GCM and GCM-GHASH mode (only for Agilex5), 2645 * addr ptr is NULL. Return "Reject" status 2646 */ 2647 if ((param_addr_ptr == NULL) || 2648 (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) && 2649 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) && 2650 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE) 2651 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2652 && 2653 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_MODE) && 2654 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_GHASH_MODE) 2655 #endif 2656 )){ 2657 return INTEL_SIP_SMC_STATUS_REJECTED; 2658 } 2659 2660 /* 2661 * Since crypto param size vary between mode. 2662 * Check CBC/CTR here and limit to size 28 bytes 2663 */ 2664 if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) || 2665 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE) || 2666 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_MODE) || 2667 ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_GHASH_MODE)) && 2668 (param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) { 2669 return INTEL_SIP_SMC_STATUS_REJECTED; 2670 } 2671 2672 /* 2673 * Since crypto param size vary between mode. 2674 * Check ECB here and limit to size 12 bytes 2675 */ 2676 if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) && 2677 (param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) { 2678 return INTEL_SIP_SMC_STATUS_REJECTED; 2679 } 2680 2681 memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload)); 2682 2683 fcs_aes_init_payload.session_id = session_id; 2684 fcs_aes_init_payload.context_id = context_id; 2685 fcs_aes_init_payload.param_size = param_size; 2686 fcs_aes_init_payload.key_id = key_id; 2687 2688 memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE, 2689 (void *) param_addr, param_size / MBOX_WORD_BYTE); 2690 2691 fcs_aes_init_payload.is_updated = 0; 2692 2693 *mbox_error = 0; 2694 2695 return INTEL_SIP_SMC_STATUS_OK; 2696 } 2697 2698 int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id, 2699 uint32_t session_id, uint32_t context_id, 2700 uint64_t src_addr, uint32_t src_size, 2701 uint64_t dst_addr, uint32_t dst_size, 2702 uint32_t padding_size, uint8_t is_finalised, 2703 uint32_t *send_id, uint64_t smmu_src_addr, 2704 uint64_t smmu_dst_addr) 2705 { 2706 int status; 2707 int i; 2708 uint32_t flag; 2709 uint32_t crypto_header; 2710 uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE]; 2711 uint32_t src_addr_sdm = (uint32_t)src_addr; 2712 uint32_t dst_addr_sdm = (uint32_t)dst_addr; 2713 bool is_src_size_aligned; 2714 bool is_dst_size_aligned; 2715 bool is_src_size_valid; 2716 bool is_dst_size_valid; 2717 2718 if (fcs_aes_init_payload.session_id != session_id || 2719 fcs_aes_init_payload.context_id != context_id) { 2720 return INTEL_SIP_SMC_STATUS_REJECTED; 2721 } 2722 2723 /* Default source and destination size align check, 32 bytes alignment. */ 2724 is_src_size_aligned = is_32_bytes_aligned(src_size); 2725 is_dst_size_aligned = is_32_bytes_aligned(dst_size); 2726 is_src_size_valid = FCS_AES_DATA_SIZE_CHECK(src_size); 2727 is_dst_size_valid = FCS_AES_DATA_SIZE_CHECK(dst_size); 2728 2729 /* 2730 * Get the requested block mode. 2731 * On the Agilex5 platform with GCM and GCM-GHASH modes, the source and destination size 2732 * should be in multiples of 16 bytes. For other platforms and other modes, it should be 2733 * in multiples of 32 bytes. 2734 */ 2735 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2736 uint32_t block_mode = fcs_aes_init_payload.crypto_param[0] & FCS_CRYPTO_BLOCK_MODE_MASK; 2737 2738 if ((block_mode == FCS_CRYPTO_GCM_MODE) || 2739 (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) { 2740 is_src_size_aligned = is_16_bytes_aligned(src_size); 2741 is_dst_size_aligned = is_16_bytes_aligned(dst_size); 2742 /* The size validity here is, should be 0 or multiples of 16 bytes. */ 2743 is_src_size_valid = is_16_bytes_aligned(src_size); 2744 is_dst_size_valid = is_16_bytes_aligned(dst_size); 2745 } 2746 #endif 2747 2748 if ((!is_8_bytes_aligned(src_addr)) || 2749 (!is_src_size_aligned) || 2750 (!is_address_in_ddr_range(src_addr, src_size))) { 2751 return INTEL_SIP_SMC_STATUS_REJECTED; 2752 } 2753 2754 if ((!is_8_bytes_aligned(dst_addr)) || 2755 (!is_dst_size_aligned) || 2756 (!is_address_in_ddr_range(dst_addr, dst_size))) { 2757 return INTEL_SIP_SMC_STATUS_REJECTED; 2758 } 2759 2760 if (!is_src_size_valid || !is_dst_size_valid) 2761 return INTEL_SIP_SMC_STATUS_REJECTED; 2762 2763 /* Prepare crypto header*/ 2764 flag = 0; 2765 if (fcs_aes_init_payload.is_updated) { 2766 fcs_aes_init_payload.param_size = 0; 2767 } else { 2768 flag |= FCS_CS_FIELD_FLAG_INIT; 2769 } 2770 2771 if (is_finalised != 0U) { 2772 flag |= FCS_CS_FIELD_FLAG_FINALIZE; 2773 } else { 2774 flag |= FCS_CS_FIELD_FLAG_UPDATE; 2775 fcs_aes_init_payload.is_updated = 1; 2776 } 2777 crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) | 2778 fcs_aes_init_payload.param_size; 2779 2780 i = 0U; 2781 fcs_aes_crypt_payload[i] = session_id; 2782 i++; 2783 fcs_aes_crypt_payload[i] = context_id; 2784 i++; 2785 fcs_aes_crypt_payload[i] = crypto_header; 2786 i++; 2787 2788 if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) & 2789 (FCS_CS_FIELD_FLAG_INIT)) { 2790 fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id; 2791 i++; 2792 2793 if ((i + ((fcs_aes_init_payload.param_size) / MBOX_WORD_BYTE)) > 2794 FCS_AES_CMD_MAX_WORD_SIZE) { 2795 return INTEL_SIP_SMC_STATUS_REJECTED; 2796 } 2797 2798 memcpy_s(&fcs_aes_crypt_payload[i], 2799 fcs_aes_init_payload.param_size / MBOX_WORD_BYTE, 2800 (void *) fcs_aes_init_payload.crypto_param, 2801 fcs_aes_init_payload.param_size / MBOX_WORD_BYTE); 2802 2803 i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE; 2804 } 2805 2806 /* On the Agilex5 platform, we will use the SMMU payload address */ 2807 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2808 src_addr_sdm = (uint32_t)smmu_src_addr; 2809 dst_addr_sdm = (uint32_t)smmu_dst_addr; 2810 #endif 2811 2812 fcs_aes_crypt_payload[i] = src_addr_sdm; 2813 i++; 2814 fcs_aes_crypt_payload[i] = src_size; 2815 i++; 2816 fcs_aes_crypt_payload[i] = dst_addr_sdm; 2817 i++; 2818 fcs_aes_crypt_payload[i] = dst_size; 2819 i++; 2820 2821 /* Padding data size, only on Agilex5 with GCM and GCM-GHASH modes. */ 2822 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 2823 if ((block_mode == FCS_CRYPTO_GCM_MODE) || 2824 (block_mode == FCS_CRYPTO_GCM_GHASH_MODE)) { 2825 fcs_aes_crypt_payload[i] = padding_size; 2826 i++; 2827 } 2828 #endif 2829 2830 status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) || 2831 (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ? 2832 mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2833 GET_JOB_ID(trans_id), 2834 MBOX_FCS_AES_CRYPT_REQ, 2835 fcs_aes_crypt_payload, 2836 i, 2837 MBOX_CMD_FLAG_INDIRECT, 2838 fcs_cs_aes_cb, 2839 NULL, 2840 0U) : 2841 mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ, 2842 fcs_aes_crypt_payload, i, CMD_INDIRECT); 2843 2844 2845 if (is_finalised != 0U) { 2846 memset((void *)&fcs_aes_init_payload, 0, 2847 sizeof(fcs_aes_init_payload)); 2848 } 2849 2850 if (status < 0) { 2851 return INTEL_SIP_SMC_STATUS_ERROR; 2852 } 2853 2854 return INTEL_SIP_SMC_STATUS_OK; 2855 } 2856 2857 int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id, 2858 uint32_t session_id, uint32_t step_type, 2859 uint32_t mac_mode, uint32_t src_addr, 2860 uint32_t key_uid, uint32_t op_key_size) 2861 { 2862 int status; 2863 uint32_t i = 0; 2864 uintptr_t inputdata; 2865 uint32_t payload[FCS_HKDF_REQUEST_DATA_SIZE] = {0U}; 2866 2867 if (!is_address_in_ddr_range(src_addr, FCS_HKDF_REQUEST_DATA_SIZE)) { 2868 ERROR("MBOX: %s: source addr not in the DDR range\n", __func__); 2869 return INTEL_SIP_SMC_STATUS_REJECTED; 2870 } 2871 2872 /* Prepare command payload */ 2873 2874 /* Session ID */ 2875 payload[i] = session_id; 2876 i++; 2877 2878 /* Reserved, 8 bytes */ 2879 payload[i] = 0; 2880 i++; 2881 2882 payload[i] = 0; 2883 i++; 2884 2885 /* HKDF step type */ 2886 payload[i] = step_type; 2887 i++; 2888 2889 /* MAC mode/PRF */ 2890 payload[i] = mac_mode; 2891 i++; 2892 2893 /* Complete input data, 1st input data len + its data + 2nd input data len + its data. */ 2894 inputdata = src_addr; 2895 memcpy_s((uint8_t *)&payload[i], FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t), 2896 (uint8_t *)inputdata, FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t)); 2897 2898 i += FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t); 2899 2900 /* Key UID */ 2901 payload[i] = key_uid; 2902 i++; 2903 2904 /* Pointer to size of output key object */ 2905 inputdata = inputdata + FCS_HKDF_KEY_DATA_SIZE; 2906 2907 /* Output Key object */ 2908 memcpy_s(&payload[i], op_key_size / sizeof(uint32_t), (void *)inputdata, 2909 op_key_size / sizeof(uint32_t)); 2910 2911 i += op_key_size / sizeof(uint32_t); 2912 2913 status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id), 2914 GET_JOB_ID(trans_id), 2915 MBOX_FCS_HKDF_REQUEST, 2916 payload, 2917 i, 2918 MBOX_CMD_FLAG_CASUAL, 2919 fcs_hkdf_request_cb, 2920 NULL, 2921 0U); 2922 2923 if (status < 0) { 2924 ERROR("MBOX: %s: status %d\n", __func__, status); 2925 return INTEL_SIP_SMC_STATUS_ERROR; 2926 } 2927 2928 return INTEL_SIP_SMC_STATUS_OK; 2929 } 2930