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