blob: 14907639fda529978abd7d34f1a11b4aee7797f6 [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>
Soby Mathewb4c6df42022-11-09 11:13:29 +00007#include <debug.h>
8#include <granule.h>
9#include <measurement.h>
10#include <realm.h>
AlexeiFedorov5b186ad2023-04-26 14:43:18 +010011#include <rsi-handler.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000012#include <smc-rsi.h>
13#include <smc.h>
14#include <string.h>
15#include <utils_def.h>
16
AlexeiFedorovefe2aec2023-06-08 16:17:00 +010017#define MAX_EXTENDED_SIZE (64U)
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010018#define MAX_MEASUREMENT_WORDS (MAX_MEASUREMENT_SIZE / sizeof(unsigned long))
Soby Mathewb4c6df42022-11-09 11:13:29 +000019/*
20 * Return the Realm Personalization Value.
21 *
22 * Arguments:
23 * rd - The Realm descriptor.
Mate Toth-Pal071aa562023-07-04 09:09:26 +020024 * claim_ptr - The start address of the Realm Personalization Value claim
25 * claim_len - The length of the Realm Personalization Value claim
Soby Mathewb4c6df42022-11-09 11:13:29 +000026 */
Mate Toth-Pal071aa562023-07-04 09:09:26 +020027static void get_rpv(struct rd *rd, void **claim_ptr, size_t *claim_len)
Soby Mathewb4c6df42022-11-09 11:13:29 +000028{
Mate Toth-Pal071aa562023-07-04 09:09:26 +020029 *claim_ptr = (uint8_t *)&(rd->rpv[0]);
30 *claim_len = RPV_SIZE;
Soby Mathewb4c6df42022-11-09 11:13:29 +000031}
32
33/*
AlexeiFedorov97844202023-04-27 15:17:35 +010034 * Function to continue with the sign operation
Soby Mathewb4c6df42022-11-09 11:13:29 +000035 */
AlexeiFedorovec35c542023-04-27 17:52:02 +010036static void attest_token_continue_sign_state(
37 struct rec_attest_data *attest_data,
38 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000039{
40 /*
41 * Sign and finish creating the token.
42 */
43 enum attest_token_err_t ret =
AlexeiFedorovec35c542023-04-27 17:52:02 +010044 attest_realm_token_sign(&(attest_data->token_sign_ctx.ctx),
45 &(attest_data->rmm_realm_token_len));
Soby Mathewb4c6df42022-11-09 11:13:29 +000046 if ((ret == ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS) ||
47 (ret == ATTEST_TOKEN_ERR_SUCCESS)) {
48 /*
49 * Return to RSI handler function after each iteration
50 * to check is there anything else to do (pending IRQ)
51 * or next signing iteration can be executed.
52 */
Soby Mathewb4c6df42022-11-09 11:13:29 +000053 res->smc_res.x[0] = RSI_INCOMPLETE;
54
55 /* If this was the last signing cycle */
56 if (ret == ATTEST_TOKEN_ERR_SUCCESS) {
AlexeiFedorovec35c542023-04-27 17:52:02 +010057 attest_data->token_sign_ctx.state =
Soby Mathewb4c6df42022-11-09 11:13:29 +000058 ATTEST_SIGN_TOKEN_WRITE_IN_PROGRESS;
59 }
60 } else {
61 /* Accessible only in case of failure during token signing */
62 ERROR("FATAL_ERROR: Realm token creation failed\n");
63 panic();
64 }
65}
66
67/*
AlexeiFedorov97844202023-04-27 15:17:35 +010068 * Function to continue with the token write operation
Soby Mathewb4c6df42022-11-09 11:13:29 +000069 */
70static void attest_token_continue_write_state(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +010071 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000072{
Soby Mathewb4c6df42022-11-09 11:13:29 +000073 struct granule *gr;
AlexeiFedorovea68b552023-10-03 11:11:47 +010074 uintptr_t realm_att_token;
Soby Mathewb4c6df42022-11-09 11:13:29 +000075 unsigned long realm_att_token_ipa = rec->regs[1];
AlexeiFedorovea68b552023-10-03 11:11:47 +010076 unsigned long offset = rec->regs[2];
77 unsigned long size = rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000078 enum s2_walk_status walk_status;
79 struct s2_walk_result walk_res = { 0UL };
AlexeiFedorovea68b552023-10-03 11:11:47 +010080 size_t attest_token_len, length;
AlexeiFedorovec35c542023-04-27 17:52:02 +010081 struct rec_attest_data *attest_data = rec->aux_data.attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +010082 uintptr_t cca_token_buf = rec->aux_data.cca_token_buf;
Soby Mathewb4c6df42022-11-09 11:13:29 +000083
84 /*
Soby Mathewb4c6df42022-11-09 11:13:29 +000085 * Translate realm granule IPA to PA. If returns with
86 * WALK_SUCCESS then the last level page table (llt),
87 * which holds the realm_att_token_buf mapping, is locked.
88 */
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010089 walk_status = realm_ipa_to_pa(rec, realm_att_token_ipa, &walk_res);
Soby Mathewb4c6df42022-11-09 11:13:29 +000090
91 /* Walk parameter validity was checked by RSI_ATTESTATION_TOKEN_INIT */
92 assert(walk_status != WALK_INVALID_PARAMS);
93
94 if (walk_status == WALK_FAIL) {
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010095 if (walk_res.ripas_val == RIPAS_EMPTY) {
Soby Mathewb4c6df42022-11-09 11:13:29 +000096 res->smc_res.x[0] = RSI_ERROR_INPUT;
97 } else {
98 /*
AlexeiFedorov97844202023-04-27 15:17:35 +010099 * Translation failed, IPA is not mapped.
100 * Return to NS host to fix the issue.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000101 */
AlexeiFedorov97844202023-04-27 15:17:35 +0100102 res->action = STAGE_2_TRANSLATION_FAULT;
103 res->rtt_level = walk_res.rtt_level;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000104 }
105 return;
106 }
107
AlexeiFedorovea68b552023-10-03 11:11:47 +0100108 if (size == 0UL) {
109 res->smc_res.x[0] = RSI_SUCCESS;
110 return;
111 }
112
Soby Mathewb4c6df42022-11-09 11:13:29 +0000113 /* Map realm data granule to RMM address space */
114 gr = find_granule(walk_res.pa);
AlexeiFedorovea68b552023-10-03 11:11:47 +0100115 realm_att_token = (uintptr_t)granule_map(gr, SLOT_RSI_CALL);
116 assert(realm_att_token != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000117
AlexeiFedorovea68b552023-10-03 11:11:47 +0100118 if (attest_data->token_sign_ctx.copied_len == 0UL) {
119 attest_token_len = attest_cca_token_create(
120 (void *)cca_token_buf,
121 REC_ATTEST_TOKEN_BUF_SIZE,
122 &attest_data->rmm_realm_token_buf,
123 attest_data->rmm_realm_token_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000124
AlexeiFedorovea68b552023-10-03 11:11:47 +0100125 if (attest_token_len == 0UL) {
126 res->smc_res.x[0] = RSI_ERROR_INPUT;
127
128 /* The signing has failed. Reset the state. */
129 attest_data->token_sign_ctx.state =
130 ATTEST_SIGN_NOT_STARTED;
131 goto out_unmap;
132 }
133
134 attest_data->token_sign_ctx.cca_token_len = attest_token_len;
135 } else {
136 attest_token_len = attest_data->token_sign_ctx.cca_token_len;
137 }
138
139 length = (size < attest_token_len) ? size : attest_token_len;
140
141 /* Copy attestation token */
142 (void)memcpy((void *)(realm_att_token + offset),
143 (void *)(cca_token_buf +
144 attest_data->token_sign_ctx.copied_len),
145 length);
146
147 attest_token_len -= length;
148
149 if (attest_token_len != 0UL) {
150 attest_data->token_sign_ctx.cca_token_len = attest_token_len;
151 attest_data->token_sign_ctx.copied_len += length;
152
153 res->smc_res.x[0] = RSI_INCOMPLETE;
154 } else {
155
156 /* The signing has succeeded. Reset the state. */
157 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
158 res->smc_res.x[0] = RSI_SUCCESS;
159 }
160
161 res->smc_res.x[1] = length;
162
163out_unmap:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000164 /* Unmap realm granule */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100165 buffer_unmap((void *)realm_att_token);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166
167 /* Unlock last level page table (walk_res.g_llt) */
168 granule_unlock(walk_res.llt);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000169}
170
AlexeiFedorov97844202023-04-27 15:17:35 +0100171void handle_rsi_attest_token_init(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000172{
AlexeiFedorovea68b552023-10-03 11:11:47 +0100173 struct rd *rd;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100174 struct rec_attest_data *attest_data;
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200175 void *rpv_ptr;
176 size_t rpv_len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000177 int att_ret;
178
179 assert(rec != NULL);
180
AlexeiFedorovec35c542023-04-27 17:52:02 +0100181 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100182 res->action = UPDATE_REC_RETURN_TO_REALM;
183
Soby Mathewb4c6df42022-11-09 11:13:29 +0000184 /*
185 * Calling RSI_ATTESTATION_TOKEN_INIT any time aborts any ongoing
186 * operation.
187 * TODO: This can be moved to attestation lib
188 */
AlexeiFedorovec35c542023-04-27 17:52:02 +0100189 if (attest_data->token_sign_ctx.state != ATTEST_SIGN_NOT_STARTED) {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000190 int restart;
191
AlexeiFedorovec35c542023-04-27 17:52:02 +0100192 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000193 restart = attestation_heap_reinit_pe(rec->aux_data.attest_heap_buf,
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000194 REC_HEAP_SIZE);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000195 if (restart != 0) {
196 /* There is no provision for this failure so panic */
197 panic();
198 }
199 }
200
AlexeiFedorov2dcd79f2023-10-17 10:04:11 +0100201 /* Clear context for signing an attestation token */
202 (void)memset(&attest_data->token_sign_ctx, 0,
203 sizeof(struct token_sign_cntxt));
204
205 attest_data->token_sign_ctx.state = ATTEST_SIGN_NOT_STARTED;
206
Soby Mathewb4c6df42022-11-09 11:13:29 +0000207 /*
208 * rd lock is acquired so that measurement cannot be updated
209 * simultaneously by another rec
210 */
211 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
212 rd = granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100213 assert(rd != NULL);
214
AlexeiFedorovea68b552023-10-03 11:11:47 +0100215 /* Save challenge value in the context */
216 (void)memcpy((void *)attest_data->token_sign_ctx.challenge,
217 (const void *)&rec->regs[1],
218 ATTEST_CHALLENGE_SIZE);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000219
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200220 get_rpv(rd, &rpv_ptr, &rpv_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000221 att_ret = attest_realm_token_create(rd->algorithm, rd->measurement,
222 MEASUREMENT_SLOT_NR,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200223 rpv_ptr,
224 rpv_len,
AlexeiFedorovec35c542023-04-27 17:52:02 +0100225 &attest_data->token_sign_ctx,
226 attest_data->rmm_realm_token_buf,
227 sizeof(attest_data->rmm_realm_token_buf));
AlexeiFedorovea68b552023-10-03 11:11:47 +0100228 buffer_unmap(rd);
229 granule_unlock(rec->realm_info.g_rd);
230
Soby Mathewb4c6df42022-11-09 11:13:29 +0000231 if (att_ret != 0) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100232 ERROR("FATAL_ERROR: Realm token creation failed\n");
Soby Mathewb4c6df42022-11-09 11:13:29 +0000233 panic();
234 }
235
AlexeiFedorovec35c542023-04-27 17:52:02 +0100236 attest_data->token_sign_ctx.state = ATTEST_SIGN_IN_PROGRESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000237
AlexeiFedorovea68b552023-10-03 11:11:47 +0100238 res->smc_res.x[0] = RSI_SUCCESS;
AlexeiFedorov755a70b2023-10-12 12:31:45 +0100239 res->smc_res.x[1] = REC_ATTEST_TOKEN_BUF_SIZE;
AlexeiFedorov97844202023-04-27 15:17:35 +0100240}
241
242/*
243 * Return 'false' if no IRQ is pending,
244 * return 'true' if there is an IRQ pending, and need to return to Host.
245 */
246static bool check_pending_irq(void)
247{
248 return (read_isr_el1() != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000249}
250
Soby Mathewb4c6df42022-11-09 11:13:29 +0000251void handle_rsi_attest_token_continue(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +0100252 struct rmi_rec_exit *rec_exit,
253 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000254{
AlexeiFedorovec35c542023-04-27 17:52:02 +0100255 struct rec_attest_data *attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100256 unsigned long realm_buf_ipa, offset, size;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100257
Soby Mathewb4c6df42022-11-09 11:13:29 +0000258 assert(rec != NULL);
AlexeiFedorov97844202023-04-27 15:17:35 +0100259 assert(rec_exit != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000260
AlexeiFedorovec35c542023-04-27 17:52:02 +0100261 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100262 res->action = UPDATE_REC_RETURN_TO_REALM;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000263
AlexeiFedorovea68b552023-10-03 11:11:47 +0100264 realm_buf_ipa = rec->regs[1];
265 offset = rec->regs[2];
266 size = rec->regs[3];
267
268 if (!GRANULE_ALIGNED(realm_buf_ipa) ||
269 (offset >= GRANULE_SIZE) ||
270 ((offset + size) > GRANULE_SIZE) ||
271 ((offset + size) < offset)) {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000272 res->smc_res.x[0] = RSI_ERROR_INPUT;
273 return;
274 }
275
AlexeiFedorovea68b552023-10-03 11:11:47 +0100276 if (!addr_in_rec_par(rec, realm_buf_ipa)) {
277 res->smc_res.x[0] = RSI_ERROR_INPUT;
278 return;
279 }
AlexeiFedorov97844202023-04-27 15:17:35 +0100280
AlexeiFedorovea68b552023-10-03 11:11:47 +0100281 if (attest_data->token_sign_ctx.state == ATTEST_SIGN_NOT_STARTED) {
282 /*
283 * Before this call the initial attestation token call
284 * (SMC_RSI_ATTEST_TOKEN_INIT) must have been executed
285 * successfully.
286 */
287 res->smc_res.x[0] = RSI_ERROR_STATE;
288 return;
289 }
290
291 while (attest_data->token_sign_ctx.state == ATTEST_SIGN_IN_PROGRESS) {
292 attest_token_continue_sign_state(attest_data, res);
293 if (check_pending_irq()) {
294 res->action = UPDATE_REC_EXIT_TO_HOST;
295 rec_exit->exit_reason = RMI_EXIT_IRQ;
296 return;
AlexeiFedorov97844202023-04-27 15:17:35 +0100297 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000298 }
AlexeiFedorovea68b552023-10-03 11:11:47 +0100299
300 /* Any other state is considered an error */
301 assert(attest_data->token_sign_ctx.state ==
302 ATTEST_SIGN_TOKEN_WRITE_IN_PROGRESS);
303
304 attest_token_continue_write_state(rec, res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000305}
306
AlexeiFedorov97844202023-04-27 15:17:35 +0100307void handle_rsi_measurement_extend(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000308{
309 struct granule *g_rd;
310 struct rd *rd;
311 unsigned long index;
312 unsigned long rd_addr;
313 size_t size;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000314 void *extend_measurement;
315 unsigned char *current_measurement;
316 int __unused meas_ret;
317
AlexeiFedorov97844202023-04-27 15:17:35 +0100318 assert(rec != NULL);
319
320 res->action = UPDATE_REC_RETURN_TO_REALM;
321
Soby Mathewb4c6df42022-11-09 11:13:29 +0000322 /*
323 * rd lock is acquired so that measurement cannot be updated
324 * simultaneously by another rec
325 */
326 rd_addr = granule_addr(rec->realm_info.g_rd);
327 g_rd = find_lock_granule(rd_addr, GRANULE_STATE_RD);
328
329 assert(g_rd != NULL);
330
331 rd = granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100332 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000333
334 /*
335 * X1: index
336 * X2: size
337 * X3-X10: measurement value
338 */
339 index = rec->regs[1];
340
341 if ((index == RIM_MEASUREMENT_SLOT) ||
342 (index >= MEASUREMENT_SLOT_NR)) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100343 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000344 goto out_unmap_rd;
345 }
346
347 size = rec->regs[2];
348
349 if (size > MAX_EXTENDED_SIZE) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100350 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000351 goto out_unmap_rd;
352 }
353
354 extend_measurement = &rec->regs[3];
355 current_measurement = rd->measurement[index];
356
357 measurement_extend(rd->algorithm,
358 current_measurement,
359 extend_measurement,
360 size,
361 current_measurement);
362
AlexeiFedorov97844202023-04-27 15:17:35 +0100363 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000364
365out_unmap_rd:
366 buffer_unmap(rd);
367 granule_unlock(g_rd);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000368}
369
AlexeiFedorov97844202023-04-27 15:17:35 +0100370void handle_rsi_measurement_read(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000371{
372 struct rd *rd;
373 unsigned long idx;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100374 unsigned int i, cnt;
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200375 unsigned long *measurement_value_part;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000376
377 assert(rec != NULL);
378
AlexeiFedorov97844202023-04-27 15:17:35 +0100379 res->action = UPDATE_REC_RETURN_TO_REALM;
380
Soby Mathewb4c6df42022-11-09 11:13:29 +0000381 /* X1: Index */
382 idx = rec->regs[1];
383
384 if (idx >= MEASUREMENT_SLOT_NR) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100385 res->smc_res.x[0] = RSI_ERROR_INPUT;
386 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000387 }
388
389 /*
390 * rd lock is acquired so that measurement cannot be updated
391 * simultaneously by another rec
392 */
393 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
394 rd = granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100395 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000396
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100397 /* Number of 8-bytes words in measurement */
AlexeiFedorov4faab852023-08-30 15:06:49 +0100398 cnt = (unsigned int)(measurement_get_size(rd->algorithm) /
399 sizeof(unsigned long));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000400
AlexeiFedorovea68b552023-10-03 11:11:47 +0100401 assert(cnt >= (SMC_RESULT_REGS - 1U));
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200402 assert(cnt < ARRAY_LEN(rec->regs));
403
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100404 /* Copy the part of the measurement to res->smc_res.x[] */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100405 for (i = 0U; i < (SMC_RESULT_REGS - 1U); i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200406 measurement_value_part = (unsigned long *)
407 &(rd->measurement[idx][i * sizeof(unsigned long)]);
408 res->smc_res.x[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100409 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000410
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100411 /* Copy the rest of the measurement to the rec->regs[] */
412 for (; i < cnt; i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200413 measurement_value_part = (unsigned long *)
414 &(rd->measurement[idx][i * sizeof(unsigned long)]);
415 rec->regs[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100416 }
417
418 /* Zero-initialize unused area */
419 for (; i < MAX_MEASUREMENT_WORDS; i++) {
420 rec->regs[i + 1U] = 0UL;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000421 }
422
423 buffer_unmap(rd);
424 granule_unlock(rec->realm_info.g_rd);
425
AlexeiFedorov97844202023-04-27 15:17:35 +0100426 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000427}