blob: 29df074e8407a355c1ba964a9754052e26b743ae [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <attestation.h>
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +00007#include <buffer.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +00008#include <debug.h>
9#include <granule.h>
10#include <measurement.h>
11#include <realm.h>
AlexeiFedorov5b186ad2023-04-26 14:43:18 +010012#include <rsi-handler.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000013#include <smc-rsi.h>
14#include <smc.h>
15#include <string.h>
16#include <utils_def.h>
17
AlexeiFedorovefe2aec2023-06-08 16:17:00 +010018#define MAX_EXTENDED_SIZE (64U)
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010019#define MAX_MEASUREMENT_WORDS (MAX_MEASUREMENT_SIZE / sizeof(unsigned long))
Soby Mathewb4c6df42022-11-09 11:13:29 +000020/*
21 * Return the Realm Personalization Value.
22 *
23 * Arguments:
24 * rd - The Realm descriptor.
Mate Toth-Pal071aa562023-07-04 09:09:26 +020025 * claim_ptr - The start address of the Realm Personalization Value claim
26 * claim_len - The length of the Realm Personalization Value claim
Soby Mathewb4c6df42022-11-09 11:13:29 +000027 */
Mate Toth-Pal071aa562023-07-04 09:09:26 +020028static void get_rpv(struct rd *rd, void **claim_ptr, size_t *claim_len)
Soby Mathewb4c6df42022-11-09 11:13:29 +000029{
Mate Toth-Pal071aa562023-07-04 09:09:26 +020030 *claim_ptr = (uint8_t *)&(rd->rpv[0]);
31 *claim_len = RPV_SIZE;
Soby Mathewb4c6df42022-11-09 11:13:29 +000032}
33
34/*
AlexeiFedorov97844202023-04-27 15:17:35 +010035 * Function to continue with the sign operation
Soby Mathewb4c6df42022-11-09 11:13:29 +000036 */
AlexeiFedorovec35c542023-04-27 17:52:02 +010037static void attest_token_continue_sign_state(
38 struct rec_attest_data *attest_data,
39 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000040{
41 /*
42 * Sign and finish creating the token.
43 */
44 enum attest_token_err_t ret =
AlexeiFedorovec35c542023-04-27 17:52:02 +010045 attest_realm_token_sign(&(attest_data->token_sign_ctx.ctx),
46 &(attest_data->rmm_realm_token_len));
Soby Mathewb4c6df42022-11-09 11:13:29 +000047 if ((ret == ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS) ||
48 (ret == ATTEST_TOKEN_ERR_SUCCESS)) {
49 /*
50 * Return to RSI handler function after each iteration
51 * to check is there anything else to do (pending IRQ)
52 * or next signing iteration can be executed.
53 */
Soby Mathewb4c6df42022-11-09 11:13:29 +000054 res->smc_res.x[0] = RSI_INCOMPLETE;
55
56 /* If this was the last signing cycle */
57 if (ret == ATTEST_TOKEN_ERR_SUCCESS) {
AlexeiFedorovec35c542023-04-27 17:52:02 +010058 attest_data->token_sign_ctx.state =
Soby Mathewb4c6df42022-11-09 11:13:29 +000059 ATTEST_SIGN_TOKEN_WRITE_IN_PROGRESS;
60 }
61 } else {
62 /* Accessible only in case of failure during token signing */
63 ERROR("FATAL_ERROR: Realm token creation failed\n");
64 panic();
65 }
66}
67
68/*
AlexeiFedorov97844202023-04-27 15:17:35 +010069 * Function to continue with the token write operation
Soby Mathewb4c6df42022-11-09 11:13:29 +000070 */
71static void attest_token_continue_write_state(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +010072 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000073{
Soby Mathewb4c6df42022-11-09 11:13:29 +000074 struct granule *gr;
AlexeiFedorovea68b552023-10-03 11:11:47 +010075 uintptr_t realm_att_token;
Soby Mathewb4c6df42022-11-09 11:13:29 +000076 unsigned long realm_att_token_ipa = rec->regs[1];
AlexeiFedorovea68b552023-10-03 11:11:47 +010077 unsigned long offset = rec->regs[2];
78 unsigned long size = rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000079 enum s2_walk_status walk_status;
80 struct s2_walk_result walk_res = { 0UL };
AlexeiFedorovea68b552023-10-03 11:11:47 +010081 size_t attest_token_len, length;
AlexeiFedorovec35c542023-04-27 17:52:02 +010082 struct rec_attest_data *attest_data = rec->aux_data.attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +010083 uintptr_t cca_token_buf = rec->aux_data.cca_token_buf;
Soby Mathewb4c6df42022-11-09 11:13:29 +000084
85 /*
Soby Mathewb4c6df42022-11-09 11:13:29 +000086 * Translate realm granule IPA to PA. If returns with
87 * WALK_SUCCESS then the last level page table (llt),
88 * which holds the realm_att_token_buf mapping, is locked.
89 */
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010090 walk_status = realm_ipa_to_pa(rec, realm_att_token_ipa, &walk_res);
Soby Mathewb4c6df42022-11-09 11:13:29 +000091
92 /* Walk parameter validity was checked by RSI_ATTESTATION_TOKEN_INIT */
93 assert(walk_status != WALK_INVALID_PARAMS);
94
95 if (walk_status == WALK_FAIL) {
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010096 if (walk_res.ripas_val == RIPAS_EMPTY) {
Soby Mathewb4c6df42022-11-09 11:13:29 +000097 res->smc_res.x[0] = RSI_ERROR_INPUT;
98 } else {
99 /*
AlexeiFedorov97844202023-04-27 15:17:35 +0100100 * Translation failed, IPA is not mapped.
101 * Return to NS host to fix the issue.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102 */
AlexeiFedorov97844202023-04-27 15:17:35 +0100103 res->action = STAGE_2_TRANSLATION_FAULT;
104 res->rtt_level = walk_res.rtt_level;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000105 }
106 return;
107 }
108
Soby Mathew19eb4332023-11-20 14:03:23 +0000109 /* If size of buffer is 0, then return early. */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100110 if (size == 0UL) {
Soby Mathew19eb4332023-11-20 14:03:23 +0000111 res->smc_res.x[0] = RSI_INCOMPLETE;
112 goto out_unlock;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100113 }
114
Soby Mathewb4c6df42022-11-09 11:13:29 +0000115 /* Map realm data granule to RMM address space */
116 gr = find_granule(walk_res.pa);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000117 realm_att_token = (uintptr_t)buffer_granule_map(gr, SLOT_RSI_CALL);
AlexeiFedorovea68b552023-10-03 11:11:47 +0100118 assert(realm_att_token != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000119
AlexeiFedorovea68b552023-10-03 11:11:47 +0100120 if (attest_data->token_sign_ctx.copied_len == 0UL) {
121 attest_token_len = attest_cca_token_create(
122 (void *)cca_token_buf,
123 REC_ATTEST_TOKEN_BUF_SIZE,
124 &attest_data->rmm_realm_token_buf,
125 attest_data->rmm_realm_token_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000126
AlexeiFedorovea68b552023-10-03 11:11:47 +0100127 if (attest_token_len == 0UL) {
128 res->smc_res.x[0] = RSI_ERROR_INPUT;
129
130 /* The signing has failed. Reset the state. */
131 attest_data->token_sign_ctx.state =
132 ATTEST_SIGN_NOT_STARTED;
133 goto out_unmap;
134 }
135
136 attest_data->token_sign_ctx.cca_token_len = attest_token_len;
137 } else {
138 attest_token_len = attest_data->token_sign_ctx.cca_token_len;
139 }
140
141 length = (size < attest_token_len) ? size : attest_token_len;
142
143 /* Copy attestation token */
144 (void)memcpy((void *)(realm_att_token + offset),
145 (void *)(cca_token_buf +
146 attest_data->token_sign_ctx.copied_len),
147 length);
148
149 attest_token_len -= length;
150
151 if (attest_token_len != 0UL) {
152 attest_data->token_sign_ctx.cca_token_len = attest_token_len;
153 attest_data->token_sign_ctx.copied_len += length;
154
155 res->smc_res.x[0] = RSI_INCOMPLETE;
156 } else {
157
158 /* The signing has succeeded. Reset the state. */
159 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
160 res->smc_res.x[0] = RSI_SUCCESS;
161 }
162
163 res->smc_res.x[1] = length;
164
165out_unmap:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166 /* Unmap realm granule */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100167 buffer_unmap((void *)realm_att_token);
Soby Mathew19eb4332023-11-20 14:03:23 +0000168out_unlock:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000169 /* Unlock last level page table (walk_res.g_llt) */
170 granule_unlock(walk_res.llt);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000171}
172
AlexeiFedorov97844202023-04-27 15:17:35 +0100173void handle_rsi_attest_token_init(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000174{
AlexeiFedorovea68b552023-10-03 11:11:47 +0100175 struct rd *rd;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100176 struct rec_attest_data *attest_data;
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200177 void *rpv_ptr;
178 size_t rpv_len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000179 int att_ret;
180
181 assert(rec != NULL);
182
AlexeiFedorovec35c542023-04-27 17:52:02 +0100183 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100184 res->action = UPDATE_REC_RETURN_TO_REALM;
185
Soby Mathewb4c6df42022-11-09 11:13:29 +0000186 /*
187 * Calling RSI_ATTESTATION_TOKEN_INIT any time aborts any ongoing
188 * operation.
189 * TODO: This can be moved to attestation lib
190 */
AlexeiFedorovec35c542023-04-27 17:52:02 +0100191 if (attest_data->token_sign_ctx.state != ATTEST_SIGN_NOT_STARTED) {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000192 int restart;
193
AlexeiFedorovec35c542023-04-27 17:52:02 +0100194 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000195 restart = attestation_heap_reinit_pe(rec->aux_data.attest_heap_buf,
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000196 REC_HEAP_SIZE);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000197 if (restart != 0) {
198 /* There is no provision for this failure so panic */
199 panic();
200 }
201 }
202
AlexeiFedorov2dcd79f2023-10-17 10:04:11 +0100203 /* Clear context for signing an attestation token */
204 (void)memset(&attest_data->token_sign_ctx, 0,
205 sizeof(struct token_sign_cntxt));
206
207 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
208
Soby Mathewb4c6df42022-11-09 11:13:29 +0000209 /*
210 * rd lock is acquired so that measurement cannot be updated
211 * simultaneously by another rec
212 */
213 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000214 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100215 assert(rd != NULL);
216
AlexeiFedorovea68b552023-10-03 11:11:47 +0100217 /* Save challenge value in the context */
218 (void)memcpy((void *)attest_data->token_sign_ctx.challenge,
219 (const void *)&rec->regs[1],
220 ATTEST_CHALLENGE_SIZE);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000221
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200222 get_rpv(rd, &rpv_ptr, &rpv_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000223 att_ret = attest_realm_token_create(rd->algorithm, rd->measurement,
224 MEASUREMENT_SLOT_NR,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200225 rpv_ptr,
226 rpv_len,
AlexeiFedorovec35c542023-04-27 17:52:02 +0100227 &attest_data->token_sign_ctx,
228 attest_data->rmm_realm_token_buf,
229 sizeof(attest_data->rmm_realm_token_buf));
AlexeiFedorovea68b552023-10-03 11:11:47 +0100230 buffer_unmap(rd);
231 granule_unlock(rec->realm_info.g_rd);
232
Soby Mathewb4c6df42022-11-09 11:13:29 +0000233 if (att_ret != 0) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100234 ERROR("FATAL_ERROR: Realm token creation failed\n");
Soby Mathewb4c6df42022-11-09 11:13:29 +0000235 panic();
236 }
237
AlexeiFedorovec35c542023-04-27 17:52:02 +0100238 attest_data->token_sign_ctx.state = ATTEST_SIGN_IN_PROGRESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000239
AlexeiFedorovea68b552023-10-03 11:11:47 +0100240 res->smc_res.x[0] = RSI_SUCCESS;
AlexeiFedorov755a70b2023-10-12 12:31:45 +0100241 res->smc_res.x[1] = REC_ATTEST_TOKEN_BUF_SIZE;
AlexeiFedorov97844202023-04-27 15:17:35 +0100242}
243
244/*
245 * Return 'false' if no IRQ is pending,
246 * return 'true' if there is an IRQ pending, and need to return to Host.
247 */
248static bool check_pending_irq(void)
249{
250 return (read_isr_el1() != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000251}
252
Soby Mathewb4c6df42022-11-09 11:13:29 +0000253void handle_rsi_attest_token_continue(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +0100254 struct rmi_rec_exit *rec_exit,
255 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000256{
AlexeiFedorovec35c542023-04-27 17:52:02 +0100257 struct rec_attest_data *attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100258 unsigned long realm_buf_ipa, offset, size;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100259
Soby Mathewb4c6df42022-11-09 11:13:29 +0000260 assert(rec != NULL);
AlexeiFedorov97844202023-04-27 15:17:35 +0100261 assert(rec_exit != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000262
AlexeiFedorovec35c542023-04-27 17:52:02 +0100263 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100264 res->action = UPDATE_REC_RETURN_TO_REALM;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000265
AlexeiFedorovea68b552023-10-03 11:11:47 +0100266 realm_buf_ipa = rec->regs[1];
267 offset = rec->regs[2];
268 size = rec->regs[3];
269
270 if (!GRANULE_ALIGNED(realm_buf_ipa) ||
271 (offset >= GRANULE_SIZE) ||
272 ((offset + size) > GRANULE_SIZE) ||
273 ((offset + size) < offset)) {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000274 res->smc_res.x[0] = RSI_ERROR_INPUT;
275 return;
276 }
277
AlexeiFedorovea68b552023-10-03 11:11:47 +0100278 if (!addr_in_rec_par(rec, realm_buf_ipa)) {
279 res->smc_res.x[0] = RSI_ERROR_INPUT;
280 return;
281 }
AlexeiFedorov97844202023-04-27 15:17:35 +0100282
AlexeiFedorovea68b552023-10-03 11:11:47 +0100283 if (attest_data->token_sign_ctx.state == ATTEST_SIGN_NOT_STARTED) {
284 /*
285 * Before this call the initial attestation token call
286 * (SMC_RSI_ATTEST_TOKEN_INIT) must have been executed
287 * successfully.
288 */
289 res->smc_res.x[0] = RSI_ERROR_STATE;
290 return;
291 }
292
293 while (attest_data->token_sign_ctx.state == ATTEST_SIGN_IN_PROGRESS) {
294 attest_token_continue_sign_state(attest_data, res);
295 if (check_pending_irq()) {
296 res->action = UPDATE_REC_EXIT_TO_HOST;
297 rec_exit->exit_reason = RMI_EXIT_IRQ;
298 return;
AlexeiFedorov97844202023-04-27 15:17:35 +0100299 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000300 }
AlexeiFedorovea68b552023-10-03 11:11:47 +0100301
302 /* Any other state is considered an error */
303 assert(attest_data->token_sign_ctx.state ==
304 ATTEST_SIGN_TOKEN_WRITE_IN_PROGRESS);
305
306 attest_token_continue_write_state(rec, res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000307}
308
AlexeiFedorov97844202023-04-27 15:17:35 +0100309void handle_rsi_measurement_extend(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000310{
311 struct granule *g_rd;
312 struct rd *rd;
313 unsigned long index;
314 unsigned long rd_addr;
315 size_t size;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000316 void *extend_measurement;
317 unsigned char *current_measurement;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000318
AlexeiFedorov97844202023-04-27 15:17:35 +0100319 assert(rec != NULL);
320
321 res->action = UPDATE_REC_RETURN_TO_REALM;
322
Soby Mathewb4c6df42022-11-09 11:13:29 +0000323 /*
324 * rd lock is acquired so that measurement cannot be updated
325 * simultaneously by another rec
326 */
327 rd_addr = granule_addr(rec->realm_info.g_rd);
328 g_rd = find_lock_granule(rd_addr, GRANULE_STATE_RD);
329
330 assert(g_rd != NULL);
331
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000332 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100333 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000334
335 /*
336 * X1: index
337 * X2: size
338 * X3-X10: measurement value
339 */
340 index = rec->regs[1];
341
342 if ((index == RIM_MEASUREMENT_SLOT) ||
343 (index >= MEASUREMENT_SLOT_NR)) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100344 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000345 goto out_unmap_rd;
346 }
347
348 size = rec->regs[2];
349
350 if (size > MAX_EXTENDED_SIZE) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100351 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000352 goto out_unmap_rd;
353 }
354
355 extend_measurement = &rec->regs[3];
356 current_measurement = rd->measurement[index];
357
358 measurement_extend(rd->algorithm,
359 current_measurement,
360 extend_measurement,
361 size,
362 current_measurement);
363
AlexeiFedorov97844202023-04-27 15:17:35 +0100364 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000365
366out_unmap_rd:
367 buffer_unmap(rd);
368 granule_unlock(g_rd);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000369}
370
AlexeiFedorov97844202023-04-27 15:17:35 +0100371void handle_rsi_measurement_read(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000372{
373 struct rd *rd;
374 unsigned long idx;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100375 unsigned int i, cnt;
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200376 unsigned long *measurement_value_part;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000377
378 assert(rec != NULL);
379
AlexeiFedorov97844202023-04-27 15:17:35 +0100380 res->action = UPDATE_REC_RETURN_TO_REALM;
381
Soby Mathewb4c6df42022-11-09 11:13:29 +0000382 /* X1: Index */
383 idx = rec->regs[1];
384
385 if (idx >= MEASUREMENT_SLOT_NR) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100386 res->smc_res.x[0] = RSI_ERROR_INPUT;
387 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000388 }
389
390 /*
391 * rd lock is acquired so that measurement cannot be updated
392 * simultaneously by another rec
393 */
394 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000395 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100396 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000397
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100398 /* Number of 8-bytes words in measurement */
AlexeiFedorov4faab852023-08-30 15:06:49 +0100399 cnt = (unsigned int)(measurement_get_size(rd->algorithm) /
400 sizeof(unsigned long));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000401
AlexeiFedorovea68b552023-10-03 11:11:47 +0100402 assert(cnt >= (SMC_RESULT_REGS - 1U));
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200403 assert(cnt < ARRAY_LEN(rec->regs));
404
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100405 /* Copy the part of the measurement to res->smc_res.x[] */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100406 for (i = 0U; i < (SMC_RESULT_REGS - 1U); i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200407 measurement_value_part = (unsigned long *)
408 &(rd->measurement[idx][i * sizeof(unsigned long)]);
409 res->smc_res.x[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100410 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000411
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100412 /* Copy the rest of the measurement to the rec->regs[] */
413 for (; i < cnt; i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200414 measurement_value_part = (unsigned long *)
415 &(rd->measurement[idx][i * sizeof(unsigned long)]);
416 rec->regs[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100417 }
418
419 /* Zero-initialize unused area */
420 for (; i < MAX_MEASUREMENT_WORDS; i++) {
421 rec->regs[i + 1U] = 0UL;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000422 }
423
424 buffer_unmap(rd);
425 granule_unlock(rec->realm_info.g_rd);
426
AlexeiFedorov97844202023-04-27 15:17:35 +0100427 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000428}