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