blob: 37dc77259a0048d4781f701158ccf633abc4975d [file] [log] [blame]
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +08001/*
2 * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <lib/mmio.h>
9
10#include "socfpga_fcs.h"
11#include "socfpga_mailbox.h"
12#include "socfpga_sip_svc.h"
13
Sieu Mun Tang128d2a72022-05-11 09:49:25 +080014bool is_size_4_bytes_aligned(uint32_t size)
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080015{
16 if ((size % MBOX_WORD_BYTE) != 0U) {
17 return false;
18 } else {
19 return true;
20 }
21}
22
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080023uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
24 uint32_t *mbox_error)
25{
26 int status;
27 unsigned int i;
28 unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
29 uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
30
31 if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
32 return INTEL_SIP_SMC_STATUS_REJECTED;
33 }
34
35 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
36 CMD_CASUAL, random_data, &resp_len);
37
38 if (status < 0) {
39 *mbox_error = -status;
40 return INTEL_SIP_SMC_STATUS_ERROR;
41 }
42
43 if (resp_len != FCS_RANDOM_WORD_SIZE) {
44 *mbox_error = GENERIC_RESPONSE_ERROR;
45 return INTEL_SIP_SMC_STATUS_ERROR;
46 }
47
48 *ret_size = FCS_RANDOM_BYTE_SIZE;
49
50 for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
51 mmio_write_32(addr, random_data[i]);
52 addr += MBOX_WORD_BYTE;
53 }
54
55 flush_dcache_range(addr - *ret_size, *ret_size);
56
57 return INTEL_SIP_SMC_STATUS_OK;
58}
59
60uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
61 uint32_t *send_id)
62{
63 int status;
64
65 if (!is_address_in_ddr_range(addr, size)) {
66 return INTEL_SIP_SMC_STATUS_REJECTED;
67 }
68
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +080069 if (!is_size_4_bytes_aligned(size)) {
70 return INTEL_SIP_SMC_STATUS_REJECTED;
71 }
72
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080073 status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
74 (uint32_t *)addr, size / MBOX_WORD_BYTE,
75 CMD_DIRECT);
76
Boon Khai Ngcac786d2021-05-26 01:50:34 +080077 flush_dcache_range(addr, size);
78
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +080079 if (status < 0) {
80 return INTEL_SIP_SMC_STATUS_ERROR;
81 }
82
83 return INTEL_SIP_SMC_STATUS_OK;
84}
85
86uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
87{
88 int status;
89
90 status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
91 NULL, 0U, CMD_DIRECT);
92
93 if (status < 0) {
94 return INTEL_SIP_SMC_STATUS_ERROR;
95 }
96
97 return INTEL_SIP_SMC_STATUS_OK;
98}
99
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +0800100uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
101 uint32_t test_bit, uint32_t *mbox_error)
102{
103 int status;
104 uint32_t first_word;
105 uint32_t payload_size;
106
107 if ((test_bit != MBOX_TEST_BIT) &&
108 (test_bit != 0)) {
109 return INTEL_SIP_SMC_STATUS_REJECTED;
110 }
111
112 if ((counter_type < FCS_BIG_CNTR_SEL) ||
113 (counter_type > FCS_SVN_CNTR_3_SEL)) {
114 return INTEL_SIP_SMC_STATUS_REJECTED;
115 }
116
117 if ((counter_type == FCS_BIG_CNTR_SEL) &&
118 (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
119 return INTEL_SIP_SMC_STATUS_REJECTED;
120 }
121
122 if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
123 (counter_type <= FCS_SVN_CNTR_3_SEL) &&
124 (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
125 return INTEL_SIP_SMC_STATUS_REJECTED;
126 }
127
128 first_word = test_bit | counter_type;
129 fcs_cntr_set_preauth_payload payload = {
130 first_word,
131 counter_value
132 };
133
134 payload_size = sizeof(payload) / MBOX_WORD_BYTE;
135 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
136 (uint32_t *) &payload, payload_size,
137 CMD_CASUAL, NULL, NULL);
138
139 if (status < 0) {
140 *mbox_error = -status;
141 return INTEL_SIP_SMC_STATUS_ERROR;
142 }
143
144 return INTEL_SIP_SMC_STATUS_OK;
145}
146
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800147uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
148 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800149{
150 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800151 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800152
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800153 fcs_encrypt_payload payload = {
154 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800155 src_addr,
156 src_size,
157 dst_addr,
158 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800159 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800160
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800161 if (!is_address_in_ddr_range(src_addr, src_size) ||
162 !is_address_in_ddr_range(dst_addr, dst_size)) {
163 return INTEL_SIP_SMC_STATUS_REJECTED;
164 }
165
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800166 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800167 return INTEL_SIP_SMC_STATUS_REJECTED;
168 }
169
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800170 status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
171 (uint32_t *) &payload, load_size,
172 CMD_INDIRECT);
173 inv_dcache_range(dst_addr, dst_size);
174
175 if (status < 0) {
176 return INTEL_SIP_SMC_STATUS_REJECTED;
177 }
178
179 return INTEL_SIP_SMC_STATUS_OK;
180}
181
182uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
183 uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
184{
185 int status;
186 uint32_t load_size;
187 uintptr_t id_offset;
188
189 id_offset = src_addr + FCS_OWNER_ID_OFFSET;
190 fcs_decrypt_payload payload = {
191 FCS_DECRYPTION_DATA_0,
192 {mmio_read_32(id_offset),
193 mmio_read_32(id_offset + MBOX_WORD_BYTE)},
194 src_addr,
195 src_size,
196 dst_addr,
197 dst_size };
198 load_size = sizeof(payload) / MBOX_WORD_BYTE;
199
200 if (!is_address_in_ddr_range(src_addr, src_size) ||
201 !is_address_in_ddr_range(dst_addr, dst_size)) {
202 return INTEL_SIP_SMC_STATUS_REJECTED;
203 }
204
205 if (!is_size_4_bytes_aligned(src_size)) {
206 return INTEL_SIP_SMC_STATUS_REJECTED;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800207 }
208
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800209 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
210 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800211 CMD_INDIRECT);
212 inv_dcache_range(dst_addr, dst_size);
213
214 if (status < 0) {
215 return INTEL_SIP_SMC_STATUS_REJECTED;
216 }
217
218 return INTEL_SIP_SMC_STATUS_OK;
219}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800220
221uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
222 uint32_t *mbox_error)
223{
224 int status;
225 unsigned int resp_len = FCS_SHA384_WORD_SIZE;
226
227 if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
228 return INTEL_SIP_SMC_STATUS_REJECTED;
229 }
230
231 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
232 CMD_CASUAL, (uint32_t *) addr, &resp_len);
233
234 if (status < 0) {
235 *mbox_error = -status;
236 return INTEL_SIP_SMC_STATUS_ERROR;
237 }
238
239 if (resp_len != FCS_SHA384_WORD_SIZE) {
240 *mbox_error = GENERIC_RESPONSE_ERROR;
241 return INTEL_SIP_SMC_STATUS_ERROR;
242 }
243
244 *ret_size = FCS_SHA384_BYTE_SIZE;
245
246 flush_dcache_range(addr, *ret_size);
247
248 return INTEL_SIP_SMC_STATUS_OK;
249}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800250
251int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
252{
253 int status;
254
255 if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
256 (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
257 return INTEL_SIP_SMC_STATUS_REJECTED;
258 }
259
260 psgsigma_teardown_msg message = {
261 RESERVED_AS_ZERO,
262 PSGSIGMA_TEARDOWN_MAGIC,
263 session_id
264 };
265
266 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
267 (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
268 CMD_CASUAL, NULL, NULL);
269
270 if (status < 0) {
271 *mbox_error = -status;
272 return INTEL_SIP_SMC_STATUS_ERROR;
273 }
274
275 return INTEL_SIP_SMC_STATUS_OK;
276}
277
278int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
279{
280 int status;
281 uint32_t load_size;
282 uint32_t chip_id[2];
283
284 load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
285
286 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
287 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
288
289 if (status < 0) {
290 *mbox_error = -status;
291 return INTEL_SIP_SMC_STATUS_ERROR;
292 }
293
294 *id_low = chip_id[0];
295 *id_high = chip_id[1];
296
297 return INTEL_SIP_SMC_STATUS_OK;
298}
299
300int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
301 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
302{
303 int status;
304 uint32_t send_size = src_size / MBOX_WORD_BYTE;
305 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
306
307
308 if (!is_address_in_ddr_range(src_addr, src_size) ||
309 !is_address_in_ddr_range(dst_addr, *dst_size)) {
310 return INTEL_SIP_SMC_STATUS_REJECTED;
311 }
312
313 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
314 (uint32_t *) src_addr, send_size, CMD_CASUAL,
315 (uint32_t *) dst_addr, &ret_size);
316
317 if (status < 0) {
318 *mbox_error = -status;
319 return INTEL_SIP_SMC_STATUS_ERROR;
320 }
321
322 *dst_size = ret_size * MBOX_WORD_BYTE;
323 flush_dcache_range(dst_addr, *dst_size);
324
325 return INTEL_SIP_SMC_STATUS_OK;
326}
327
328int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
329 uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
330{
331 int status;
332 uint32_t send_size = src_size / MBOX_WORD_BYTE;
333 uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
334
335 if (!is_address_in_ddr_range(src_addr, src_size) ||
336 !is_address_in_ddr_range(dst_addr, *dst_size)) {
337 return INTEL_SIP_SMC_STATUS_REJECTED;
338 }
339
340 status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
341 (uint32_t *) src_addr, send_size, CMD_CASUAL,
342 (uint32_t *) dst_addr, &ret_size);
343
344 if (status < 0) {
345 *mbox_error = -status;
346 return INTEL_SIP_SMC_STATUS_ERROR;
347 }
348
349 *dst_size = ret_size * MBOX_WORD_BYTE;
350 flush_dcache_range(dst_addr, *dst_size);
351
352 return INTEL_SIP_SMC_STATUS_OK;
353}