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