xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision 49d44ec5f357b1bcf8eae9e91fbd72aef09e00dd)
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 	flush_dcache_range(addr, size);
78 
79 	if (status < 0) {
80 		return INTEL_SIP_SMC_STATUS_ERROR;
81 	}
82 
83 	return INTEL_SIP_SMC_STATUS_OK;
84 }
85 
86 uint32_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 
100 uint32_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 
147 uint32_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)
149 {
150 	int status;
151 	uint32_t load_size;
152 
153 	fcs_encrypt_payload payload = {
154 		FCS_ENCRYPTION_DATA_0,
155 		src_addr,
156 		src_size,
157 		dst_addr,
158 		dst_size };
159 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
160 
161 	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 
166 	if (!is_size_4_bytes_aligned(src_size)) {
167 		return INTEL_SIP_SMC_STATUS_REJECTED;
168 	}
169 
170 	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 
182 uint32_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;
207 	}
208 
209 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
210 				(uint32_t *) &payload, load_size,
211 				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 }
220 
221 uint32_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 }
250 
251 int 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 
278 int 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 
300 int 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 
328 int 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 }
354