blob: 5c92af94e557fc3aa7c27790c26b00de822a1355 [file] [log] [blame]
Arunachalam Ganapathyc58e4692025-01-28 12:28:59 +00001/*
2 * Copyright (c) 2025, Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include <assert.h>
7#include <stdlib.h>
8
9#include <realm_da_helpers.h>
10#include <realm_rsi.h>
11
12#include <arch.h>
13#include <arch_features.h>
14#include <arch_helpers.h>
15#include <debug.h>
16#include <host_shared_data.h>
17#include <sync.h>
18
19/*
20 * Currently assigning one device is supported, for more than one device the VMM
21 * view of vdev_id and Realm view of device_id must match
22 */
23#define RDEV_ID (0x0UL)
24
25#define RDEV_TDISP_VERSION_MAX (0x10)
26
27struct rdev {
28 unsigned long id;
29 unsigned long inst_id;
30};
31
32static struct rdev gbl_rdev;
33
34/* Measurement parameters */
35static struct rsi_dev_measure_params gbl_rdev_meas_params
36__aligned(GRANULE_SIZE);
37
38/* RDEV info. decice type and attestation evidence digest */
39static struct rsi_dev_info gbl_rdev_info __aligned(GRANULE_SIZE);
40
41/* Get inst id for a known Realm device id RDEV_ID */
42static unsigned long realm_rdev_init(struct rdev *rdev, unsigned long rdev_id)
43{
44 u_register_t rsi_rc;
45 u_register_t rdev_inst_id;
46
47 memset(rdev, 0, sizeof(struct rdev));
48 realm_printf("In test_realm_da_rsi_calls\n");
49
50 rsi_rc = rsi_rdev_get_instance_id(rdev_id, &rdev_inst_id);
51 if (rsi_rc != RSI_SUCCESS) {
52 realm_printf("RSI_RDEV_GET_INSTANCE_ID failed: rdev_id: 0x%lx"
53 " rsi_rc: 0x%lx\n", rdev_id, rsi_rc);
54 return rsi_rc;
55 }
56
57 rdev->id = rdev_id;
58 rdev->inst_id = rdev_inst_id;
59
60 realm_printf("RSI_RDEV_GET_INSTANCE_ID: rdev_id: 0x%lx, "
61 "inst_id: 0x%lx\n", rdev_id, rdev_inst_id);
62
63 return RSI_SUCCESS;
64}
65
66static unsigned long realm_rsi_rdev_get_state(struct rdev *rdev)
67{
68 u_register_t rdev_rsi_state;
69 unsigned long rsi_rc;
70
71 rsi_rc = rsi_rdev_get_state(rdev->id, rdev->inst_id, &rdev_rsi_state);
72 if (rsi_rc != RSI_SUCCESS) {
73 ERROR("RSI_RDEV_GET_STATE failed 0x%lx\n", rsi_rc);
74 return rsi_rc;
75 }
76
77 INFO("Realm: RSI_RDEV_GET_STATE completed. RDEV state: 0x%lx\n",
78 rdev_rsi_state);
79
80 return RSI_SUCCESS;
81}
82
83static int realm_verify_device_attestation(struct rdev *rdev,
84 struct rsi_dev_info *rdev_info)
85{
86 /*
87 * todo: Implement RHI call to get cached device certificate,
88 * measurement from host and verify the digest against RMM
89 */
90 return 0;
91}
92
93static unsigned long realm_rsi_rdev_get_info(struct rdev *rdev,
94 struct rsi_dev_info *rdev_info)
95{
96 unsigned long rsi_rc;
97
98 memset(rdev_info, 0, sizeof(struct rsi_dev_info));
99 rsi_rc = rsi_rdev_get_info(rdev->id, rdev->inst_id,
100 (u_register_t)rdev_info);
101 if (rsi_rc != RSI_SUCCESS) {
102 ERROR("RSI_RDEV_GET_INFO failed 0x%lx\n", rsi_rc);
103 return rsi_rc;
104 }
105
106 /* Print RDEV info */
107 INFO("RSI_RDEV_GET_INFO:\n");
108 INFO("\tflags: 0x%lx\n", rdev_info->flags);
109 INFO("\tattest_type: 0x%lx\n", rdev_info->attest_type);
110 INFO("\tcert_id: 0x%lx\n", rdev_info->cert_id);
111 INFO("\thash_algo: 0x%lx\n", rdev_info->hash_algo);
112
113 return RSI_SUCCESS;
114}
115
116static unsigned long
117realm_rsi_rdev_get_measurements(struct rdev *rdev,
118 struct rsi_dev_measure_params *mparams)
119{
120 unsigned long rsi_rc;
121
122 INFO("Realm: Call RSI_RDEV_GET_MEASUREMENTS\n");
123
124 /* Set measurement parameters */
125 memset(mparams, 0, sizeof(struct rsi_dev_measure_params));
126 mparams->flags = (INPLACE(RSI_DEV_MEASURE_FLAGS_ALL,
127 RSI_DEV_MEASURE_ALL) |
128 INPLACE(RSI_DEV_MEASURE_FLAGS_SIGNED,
129 RSI_DEV_MEASURE_NOT_SIGNED) |
130 INPLACE(RSI_DEV_MEASURE_FLAGS_RAW,
131 RSI_DEV_MEASURE_NOT_RAW));
132
133
134 rsi_rc = rsi_rdev_get_measurements(rdev->id, rdev->inst_id,
135 (u_register_t)mparams);
136 if (rsi_rc != RSI_SUCCESS) {
137 ERROR("RSI_RDEV_GET_MEASUREMENTS failed\n");
138 return RSI_ERROR_STATE;
139 }
140
141 INFO("Host Realm: RDEV state after submitting meas request\n");
142 (void)realm_rsi_rdev_get_state(rdev);
143
144 /* Do RSI RDEV continue call */
145 do {
146 rsi_rc = rsi_rdev_continue(rdev->id, rdev->inst_id);
147 } while (rsi_rc == RSI_INCOMPLETE);
148
149 INFO("Host Realm: RDEV state after host completing meas request\n");
150 (void)realm_rsi_rdev_get_state(rdev);
151
152 return rsi_rc;
153}
154
155static unsigned long realm_rsi_rdev_lock(struct rdev *rdev)
156{
157 unsigned long rsi_rc;
158
159 INFO("Realm: Call RSI_RDEV_LOCK\n");
160
161 rsi_rc = rsi_rdev_lock(rdev->id, rdev->inst_id);
162 if (rsi_rc != RSI_SUCCESS) {
163 ERROR("RSI_RDEV_LOCK failed\n");
164 return RSI_ERROR_STATE;
165 }
166
167 INFO("Realm: RDEV state after submitting lock request\n");
168 (void)realm_rsi_rdev_get_state(rdev);
169
170 /* Do RSI RDEV continue call */
171 do {
172 rsi_rc = rsi_rdev_continue(rdev->id, rdev->inst_id);
173 } while (rsi_rc == RSI_INCOMPLETE);
174
175 INFO("Realm: RDEV state after host completing lock request\n");
176 (void)realm_rsi_rdev_get_state(rdev);
177
178 return rsi_rc;
179}
180
181static unsigned long realm_rsi_rdev_get_interface_report(struct rdev *rdev)
182{
183 unsigned long rsi_rc;
184
185 INFO("Realm: Call RSI_RDEV_GET_IFC_REPORT\n");
186
187 rsi_rc = rsi_rdev_get_interface_report(rdev->id, rdev->inst_id,
188 RDEV_TDISP_VERSION_MAX);
189 if (rsi_rc != RSI_SUCCESS) {
190 ERROR("RSI_RDEV_GET_IFC_REPORT failed\n");
191 return RSI_ERROR_STATE;
192 }
193
194 INFO("Realm: RDEV state after submitting IFC_REPORT request\n");
195 (void)realm_rsi_rdev_get_state(rdev);
196
197 /* Do RSI RDEV continue call */
198 do {
199 rsi_rc = rsi_rdev_continue(rdev->id, rdev->inst_id);
200 } while (rsi_rc == RSI_INCOMPLETE);
201
202 INFO("Realm: RDEV state after host completing IFC_REPORT request\n");
203 (void)realm_rsi_rdev_get_state(rdev);
204
205 return rsi_rc;
206}
207
208static unsigned long realm_rsi_rdev_start(struct rdev *rdev)
209{
210 unsigned long rsi_rc;
211
212 INFO("Realm: Call RSI_RDEV_start\n");
213
214 rsi_rc = rsi_rdev_start(rdev->id, rdev->inst_id);
215 if (rsi_rc != RSI_SUCCESS) {
216 ERROR("RSI_RDEV_START failed\n");
217 return RSI_ERROR_STATE;
218 }
219
220 INFO("Realm: RDEV state after submitting start request\n");
221 (void)realm_rsi_rdev_get_state(rdev);
222
223 /* Do RSI RDEV continue call */
224 do {
225 rsi_rc = rsi_rdev_continue(rdev->id, rdev->inst_id);
226 } while (rsi_rc == RSI_INCOMPLETE);
227
228 INFO("Realm: RDEV state after host completing start request\n");
229 (void)realm_rsi_rdev_get_state(rdev);
230
231 return rsi_rc;
232}
233
234static unsigned long realm_rsi_rdev_stop(struct rdev *rdev)
235{
236 unsigned long rsi_rc;
237
238 INFO("Realm: Call RSI_RDEV_STOP\n");
239
240 rsi_rc = rsi_rdev_stop(rdev->id, rdev->inst_id);
241 if (rsi_rc != RSI_SUCCESS) {
242 ERROR("RSI_RDEV_STOP failed\n");
243 return RSI_ERROR_STATE;
244 }
245
246 INFO("Realm: RDEV state after submitting stop request\n");
247 (void)realm_rsi_rdev_get_state(rdev);
248
249 /* Do RSI RDEV continue call */
250 do {
251 rsi_rc = rsi_rdev_continue(rdev->id, rdev->inst_id);
252 } while (rsi_rc == RSI_INCOMPLETE);
253
254 INFO("Realm: RDEV state after host completing stop request\n");
255 (void)realm_rsi_rdev_get_state(rdev);
256
257 return rsi_rc;
258}
259
260/*
261 * If the Realm supports DA feature, this function calls series of RSI RDEV
262 * on the assigned device.
263 *
264 * Returns 'false' on success.
265 */
266bool test_realm_da_rsi_calls(void)
267{
268 struct rdev *rdev;
269 unsigned long rsi_rc;
270 u_register_t rsi_feature_reg0;
271 struct rsi_dev_measure_params *rdev_meas_params;
272 struct rsi_dev_info *rdev_info;
273
274 /* Check if RSI_FEATURES support DA */
275 rsi_rc = rsi_features(RSI_FEATURE_REGISTER_0_INDEX, &rsi_feature_reg0);
276 if (rsi_rc != RSI_SUCCESS) {
277 return false;
278 }
279
280 if (EXTRACT(RSI_FEATURE_REGISTER_0_DA, rsi_feature_reg0) !=
281 RSI_FEATURE_TRUE) {
282 realm_printf("RSI feature DA not supported for current Realm\n");
283 return false;
284 }
285
286 /* Get the global RDEV. Currently only one RDEV is supported */
287 rdev = &gbl_rdev;
288 rdev_meas_params = &gbl_rdev_meas_params;
289 rdev_info = &gbl_rdev_info;
290
291 rsi_rc = realm_rdev_init(rdev, RDEV_ID);
292 if (rdev == NULL) {
293 realm_printf("realm_rdev_init failed\n");
294 return false;
295 }
296
297 rsi_rc = realm_rsi_rdev_get_state(rdev);
298 if (rsi_rc != RSI_SUCCESS) {
299 return false;
300 }
301
302 /* Before lock get_measurement */
303 rsi_rc = realm_rsi_rdev_get_measurements(rdev, rdev_meas_params);
304 if (rsi_rc != RSI_SUCCESS) {
305 return false;
306 }
307
308 rsi_rc = realm_rsi_rdev_lock(rdev);
309 if (rsi_rc != RSI_SUCCESS) {
310 return false;
311 }
312
313 /* After lock get_measurement */
314 rsi_rc = realm_rsi_rdev_get_measurements(rdev, rdev_meas_params);
315 if (rsi_rc != RSI_SUCCESS) {
316 return false;
317 }
318
319 rsi_rc = realm_rsi_rdev_get_interface_report(rdev);
320 if (rsi_rc != RSI_SUCCESS) {
321 return false;
322 }
323
324 /* After meas and ifc_report, get device info */
325 rsi_rc = realm_rsi_rdev_get_info(rdev, rdev_info);
326 if (rsi_rc != RSI_SUCCESS) {
327 return false;
328 }
329
330 /*
331 * Get cached device attestation from Host and verify it with device
332 * attestation digest
333 */
334 (void)realm_verify_device_attestation(rdev, rdev_info);
335
336 rsi_rc = realm_rsi_rdev_start(rdev);
337 if (rsi_rc != RSI_SUCCESS) {
338 return false;
339 }
340
341 rsi_rc = realm_rsi_rdev_stop(rdev);
342 if (rsi_rc != RSI_SUCCESS) {
343 return false;
344 }
345
346 return true;
347}