xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 7facacec6328e505b243a4974d045d45fe068afd)
1 /*
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 
14 bool is_size_4_bytes_aligned(uint32_t size)
15 {
16 	if ((size % MBOX_WORD_BYTE) != 0U) {
17 		return false;
18 	} else {
19 		return true;
20 	}
21 }
22 
23 uint32_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 
60 uint32_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 
69 	if (!is_size_4_bytes_aligned(size)) {
70 		return INTEL_SIP_SMC_STATUS_REJECTED;
71 	}
72 
73 	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
74 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
75 				CMD_DIRECT);
76 
77 	if (status < 0) {
78 		return INTEL_SIP_SMC_STATUS_ERROR;
79 	}
80 
81 	return INTEL_SIP_SMC_STATUS_OK;
82 }
83 
84 uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
85 {
86 	int status;
87 
88 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
89 				NULL, 0U, CMD_DIRECT);
90 
91 	if (status < 0) {
92 		return INTEL_SIP_SMC_STATUS_ERROR;
93 	}
94 
95 	return INTEL_SIP_SMC_STATUS_OK;
96 }
97 
98 uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
99 					uint32_t test_bit, uint32_t *mbox_error)
100 {
101 	int status;
102 	uint32_t first_word;
103 	uint32_t payload_size;
104 
105 	if ((test_bit != MBOX_TEST_BIT) &&
106 		(test_bit != 0)) {
107 		return INTEL_SIP_SMC_STATUS_REJECTED;
108 	}
109 
110 	if ((counter_type < FCS_BIG_CNTR_SEL) ||
111 		(counter_type > FCS_SVN_CNTR_3_SEL)) {
112 		return INTEL_SIP_SMC_STATUS_REJECTED;
113 	}
114 
115 	if ((counter_type == FCS_BIG_CNTR_SEL) &&
116 		(counter_value > FCS_BIG_CNTR_VAL_MAX)) {
117 		return INTEL_SIP_SMC_STATUS_REJECTED;
118 	}
119 
120 	if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
121 		(counter_type <= FCS_SVN_CNTR_3_SEL) &&
122 		(counter_value > FCS_SVN_CNTR_VAL_MAX)) {
123 		return INTEL_SIP_SMC_STATUS_REJECTED;
124 	}
125 
126 	first_word = test_bit | counter_type;
127 	fcs_cntr_set_preauth_payload payload = {
128 		first_word,
129 		counter_value
130 	};
131 
132 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
133 	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
134 				  (uint32_t *) &payload, payload_size,
135 				  CMD_CASUAL, NULL, NULL);
136 
137 	if (status < 0) {
138 		*mbox_error = -status;
139 		return INTEL_SIP_SMC_STATUS_ERROR;
140 	}
141 
142 	return INTEL_SIP_SMC_STATUS_OK;
143 }
144 
145 uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
146 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
147 {
148 	int status;
149 	uint32_t load_size;
150 
151 	fcs_encrypt_payload payload = {
152 		FCS_ENCRYPTION_DATA_0,
153 		src_addr,
154 		src_size,
155 		dst_addr,
156 		dst_size };
157 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
158 
159 	if (!is_address_in_ddr_range(src_addr, src_size) ||
160 		!is_address_in_ddr_range(dst_addr, dst_size)) {
161 		return INTEL_SIP_SMC_STATUS_REJECTED;
162 	}
163 
164 	if (!is_size_4_bytes_aligned(src_size)) {
165 		return INTEL_SIP_SMC_STATUS_REJECTED;
166 	}
167 
168 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
169 				(uint32_t *) &payload, load_size,
170 				CMD_INDIRECT);
171 	inv_dcache_range(dst_addr, dst_size);
172 
173 	if (status < 0) {
174 		return INTEL_SIP_SMC_STATUS_REJECTED;
175 	}
176 
177 	return INTEL_SIP_SMC_STATUS_OK;
178 }
179 
180 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
181 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
182 {
183 	int status;
184 	uint32_t load_size;
185 	uintptr_t id_offset;
186 
187 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
188 	fcs_decrypt_payload payload = {
189 		FCS_DECRYPTION_DATA_0,
190 		{mmio_read_32(id_offset),
191 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
192 		src_addr,
193 		src_size,
194 		dst_addr,
195 		dst_size };
196 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
197 
198 	if (!is_address_in_ddr_range(src_addr, src_size) ||
199 		!is_address_in_ddr_range(dst_addr, dst_size)) {
200 		return INTEL_SIP_SMC_STATUS_REJECTED;
201 	}
202 
203 	if (!is_size_4_bytes_aligned(src_size)) {
204 		return INTEL_SIP_SMC_STATUS_REJECTED;
205 	}
206 
207 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
208 				(uint32_t *) &payload, load_size,
209 				CMD_INDIRECT);
210 	inv_dcache_range(dst_addr, dst_size);
211 
212 	if (status < 0) {
213 		return INTEL_SIP_SMC_STATUS_REJECTED;
214 	}
215 
216 	return INTEL_SIP_SMC_STATUS_OK;
217 }
218 
219 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
220 					uint32_t *mbox_error)
221 {
222 	int status;
223 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
224 
225 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
226 		return INTEL_SIP_SMC_STATUS_REJECTED;
227 	}
228 
229 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
230 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
231 
232 	if (status < 0) {
233 		*mbox_error = -status;
234 		return INTEL_SIP_SMC_STATUS_ERROR;
235 	}
236 
237 	if (resp_len != FCS_SHA384_WORD_SIZE) {
238 		*mbox_error = GENERIC_RESPONSE_ERROR;
239 		return INTEL_SIP_SMC_STATUS_ERROR;
240 	}
241 
242 	*ret_size = FCS_SHA384_BYTE_SIZE;
243 
244 	flush_dcache_range(addr, *ret_size);
245 
246 	return INTEL_SIP_SMC_STATUS_OK;
247 }
248 
249 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
250 {
251 	int status;
252 
253 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
254 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
255 		return INTEL_SIP_SMC_STATUS_REJECTED;
256 	}
257 
258 	psgsigma_teardown_msg message = {
259 		RESERVED_AS_ZERO,
260 		PSGSIGMA_TEARDOWN_MAGIC,
261 		session_id
262 	};
263 
264 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
265 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
266 			CMD_CASUAL, NULL, NULL);
267 
268 	if (status < 0) {
269 		*mbox_error = -status;
270 		return INTEL_SIP_SMC_STATUS_ERROR;
271 	}
272 
273 	return INTEL_SIP_SMC_STATUS_OK;
274 }
275 
276 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
277 {
278 	int status;
279 	uint32_t load_size;
280 	uint32_t chip_id[2];
281 
282 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
283 
284 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
285 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
286 
287 	if (status < 0) {
288 		*mbox_error = -status;
289 		return INTEL_SIP_SMC_STATUS_ERROR;
290 	}
291 
292 	*id_low = chip_id[0];
293 	*id_high = chip_id[1];
294 
295 	return INTEL_SIP_SMC_STATUS_OK;
296 }
297 
298 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
299 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
300 {
301 	int status;
302 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
303 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
304 
305 
306 	if (!is_address_in_ddr_range(src_addr, src_size) ||
307 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
308 		return INTEL_SIP_SMC_STATUS_REJECTED;
309 	}
310 
311 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
312 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
313 			(uint32_t *) dst_addr, &ret_size);
314 
315 	if (status < 0) {
316 		*mbox_error = -status;
317 		return INTEL_SIP_SMC_STATUS_ERROR;
318 	}
319 
320 	*dst_size = ret_size * MBOX_WORD_BYTE;
321 	flush_dcache_range(dst_addr, *dst_size);
322 
323 	return INTEL_SIP_SMC_STATUS_OK;
324 }
325 
326 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
327 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
328 {
329 	int status;
330 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
331 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
332 
333 	if (!is_address_in_ddr_range(src_addr, src_size) ||
334 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
335 		return INTEL_SIP_SMC_STATUS_REJECTED;
336 	}
337 
338 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
339 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
340 			(uint32_t *) dst_addr, &ret_size);
341 
342 	if (status < 0) {
343 		*mbox_error = -status;
344 		return INTEL_SIP_SMC_STATUS_ERROR;
345 	}
346 
347 	*dst_size = ret_size * MBOX_WORD_BYTE;
348 	flush_dcache_range(dst_addr, *dst_size);
349 
350 	return INTEL_SIP_SMC_STATUS_OK;
351 }
352