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