blob: 26da55efc4bbf855e96382fe0a0e845af0c4eca4 [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
77 if (status < 0) {
78 return INTEL_SIP_SMC_STATUS_ERROR;
79 }
80
81 return INTEL_SIP_SMC_STATUS_OK;
82}
83
84uint32_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
Sieu Mun Tanga068fdf2022-05-11 10:01:54 +080098uint32_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
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800145uint32_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)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800147{
148 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800149 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800150
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800151 fcs_encrypt_payload payload = {
152 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800153 src_addr,
154 src_size,
155 dst_addr,
156 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800157 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800158
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800159 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
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800164 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800165 return INTEL_SIP_SMC_STATUS_REJECTED;
166 }
167
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800168 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
180uint32_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;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800205 }
206
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800207 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
208 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800209 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}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800218
219uint32_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}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800248
249int 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
276int 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
298int 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
326int 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}