xref: /rk3399_ARM-atf/plat/intel/soc/common/sip/socfpga_sip_fcs.c (revision d17408316db10db611e23716e8a5b9b9f53ad509)
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_encryption(uint32_t src_addr, uint32_t src_size,
99 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
100 {
101 	int status;
102 	uint32_t load_size;
103 
104 	fcs_encrypt_payload payload = {
105 		FCS_ENCRYPTION_DATA_0,
106 		src_addr,
107 		src_size,
108 		dst_addr,
109 		dst_size };
110 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
111 
112 	if (!is_address_in_ddr_range(src_addr, src_size) ||
113 		!is_address_in_ddr_range(dst_addr, dst_size)) {
114 		return INTEL_SIP_SMC_STATUS_REJECTED;
115 	}
116 
117 	if (!is_size_4_bytes_aligned(src_size)) {
118 		return INTEL_SIP_SMC_STATUS_REJECTED;
119 	}
120 
121 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
122 				(uint32_t *) &payload, load_size,
123 				CMD_INDIRECT);
124 	inv_dcache_range(dst_addr, dst_size);
125 
126 	if (status < 0) {
127 		return INTEL_SIP_SMC_STATUS_REJECTED;
128 	}
129 
130 	return INTEL_SIP_SMC_STATUS_OK;
131 }
132 
133 uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
134 		uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
135 {
136 	int status;
137 	uint32_t load_size;
138 	uintptr_t id_offset;
139 
140 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
141 	fcs_decrypt_payload payload = {
142 		FCS_DECRYPTION_DATA_0,
143 		{mmio_read_32(id_offset),
144 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
145 		src_addr,
146 		src_size,
147 		dst_addr,
148 		dst_size };
149 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
150 
151 	if (!is_address_in_ddr_range(src_addr, src_size) ||
152 		!is_address_in_ddr_range(dst_addr, dst_size)) {
153 		return INTEL_SIP_SMC_STATUS_REJECTED;
154 	}
155 
156 	if (!is_size_4_bytes_aligned(src_size)) {
157 		return INTEL_SIP_SMC_STATUS_REJECTED;
158 	}
159 
160 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
161 				(uint32_t *) &payload, load_size,
162 				CMD_INDIRECT);
163 	inv_dcache_range(dst_addr, dst_size);
164 
165 	if (status < 0) {
166 		return INTEL_SIP_SMC_STATUS_REJECTED;
167 	}
168 
169 	return INTEL_SIP_SMC_STATUS_OK;
170 }
171 
172 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
173 					uint32_t *mbox_error)
174 {
175 	int status;
176 	unsigned int resp_len = FCS_SHA384_WORD_SIZE;
177 
178 	if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
179 		return INTEL_SIP_SMC_STATUS_REJECTED;
180 	}
181 
182 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
183 			CMD_CASUAL, (uint32_t *) addr, &resp_len);
184 
185 	if (status < 0) {
186 		*mbox_error = -status;
187 		return INTEL_SIP_SMC_STATUS_ERROR;
188 	}
189 
190 	if (resp_len != FCS_SHA384_WORD_SIZE) {
191 		*mbox_error = GENERIC_RESPONSE_ERROR;
192 		return INTEL_SIP_SMC_STATUS_ERROR;
193 	}
194 
195 	*ret_size = FCS_SHA384_BYTE_SIZE;
196 
197 	flush_dcache_range(addr, *ret_size);
198 
199 	return INTEL_SIP_SMC_STATUS_OK;
200 }
201 
202 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
203 {
204 	int status;
205 
206 	if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
207 		(session_id != PSGSIGMA_UNKNOWN_SESSION)) {
208 		return INTEL_SIP_SMC_STATUS_REJECTED;
209 	}
210 
211 	psgsigma_teardown_msg message = {
212 		RESERVED_AS_ZERO,
213 		PSGSIGMA_TEARDOWN_MAGIC,
214 		session_id
215 	};
216 
217 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
218 			(uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
219 			CMD_CASUAL, NULL, NULL);
220 
221 	if (status < 0) {
222 		*mbox_error = -status;
223 		return INTEL_SIP_SMC_STATUS_ERROR;
224 	}
225 
226 	return INTEL_SIP_SMC_STATUS_OK;
227 }
228 
229 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
230 {
231 	int status;
232 	uint32_t load_size;
233 	uint32_t chip_id[2];
234 
235 	load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
236 
237 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
238 			0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
239 
240 	if (status < 0) {
241 		*mbox_error = -status;
242 		return INTEL_SIP_SMC_STATUS_ERROR;
243 	}
244 
245 	*id_low = chip_id[0];
246 	*id_high = chip_id[1];
247 
248 	return INTEL_SIP_SMC_STATUS_OK;
249 }
250 
251 int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
252 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
253 {
254 	int status;
255 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
256 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
257 
258 
259 	if (!is_address_in_ddr_range(src_addr, src_size) ||
260 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
261 		return INTEL_SIP_SMC_STATUS_REJECTED;
262 	}
263 
264 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
265 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
266 			(uint32_t *) dst_addr, &ret_size);
267 
268 	if (status < 0) {
269 		*mbox_error = -status;
270 		return INTEL_SIP_SMC_STATUS_ERROR;
271 	}
272 
273 	*dst_size = ret_size * MBOX_WORD_BYTE;
274 	flush_dcache_range(dst_addr, *dst_size);
275 
276 	return INTEL_SIP_SMC_STATUS_OK;
277 }
278 
279 int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
280 		uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
281 {
282 	int status;
283 	uint32_t send_size = src_size / MBOX_WORD_BYTE;
284 	uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
285 
286 	if (!is_address_in_ddr_range(src_addr, src_size) ||
287 		!is_address_in_ddr_range(dst_addr, *dst_size)) {
288 		return INTEL_SIP_SMC_STATUS_REJECTED;
289 	}
290 
291 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
292 			(uint32_t *) src_addr, send_size, CMD_CASUAL,
293 			(uint32_t *) dst_addr, &ret_size);
294 
295 	if (status < 0) {
296 		*mbox_error = -status;
297 		return INTEL_SIP_SMC_STATUS_ERROR;
298 	}
299 
300 	*dst_size = ret_size * MBOX_WORD_BYTE;
301 	flush_dcache_range(dst_addr, *dst_size);
302 
303 	return INTEL_SIP_SMC_STATUS_OK;
304 }
305