blob: 4b06fa60c4ad3b7799ad7d326f1e7842d8ea0856 [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 Tang128d2a72022-05-11 09:49:25 +080098uint32_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)
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800100{
101 int status;
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800102 uint32_t load_size;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800103
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800104 fcs_encrypt_payload payload = {
105 FCS_ENCRYPTION_DATA_0,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800106 src_addr,
107 src_size,
108 dst_addr,
109 dst_size };
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800110 load_size = sizeof(payload) / MBOX_WORD_BYTE;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800111
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800112 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
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800117 if (!is_size_4_bytes_aligned(src_size)) {
Sieu Mun Tangdb79fa52022-03-20 00:49:57 +0800118 return INTEL_SIP_SMC_STATUS_REJECTED;
119 }
120
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800121 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
133uint32_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;
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800158 }
159
Sieu Mun Tang128d2a72022-05-11 09:49:25 +0800160 status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
161 (uint32_t *) &payload, load_size,
Sieu Mun Tang9f22cbf2022-03-02 11:04:09 +0800162 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}
Sieu Mun Tanga34b8812022-03-17 03:11:55 +0800171
172uint32_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}
Sieu Mun Tang2a820b92022-05-11 09:59:55 +0800201
202int 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
229int 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
251int 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
279int 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}