blob: de097857751a937698a967dbd8fb9da16e308c09 [file] [log] [blame]
Mate Toth-Pal57fadaf2025-02-06 10:21:30 +01001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <app.h>
7#include <app_common.h>
8#include <app_services.h>
9#include <assert.h>
Mate Toth-Pal646c6032025-02-06 11:01:37 +010010#include <attest_services.h>
Mate Toth-Pal57fadaf2025-02-06 10:21:30 +010011#include <console.h>
Mate Toth-Pal646c6032025-02-06 11:01:37 +010012#include <errno.h>
13#include <random_app.h>
14#include <rmm_el3_ifc.h>
Mate Toth-Pal57fadaf2025-02-06 10:21:30 +010015
16typedef uint64_t (*app_service_func)(struct app_data_cfg *app_data,
17 unsigned long arg0,
18 unsigned long arg1,
19 unsigned long arg2,
20 unsigned long arg3);
21
22static uint64_t app_service_print(struct app_data_cfg *app_data,
23 unsigned long arg0,
24 unsigned long arg1,
25 unsigned long arg2,
26 unsigned long arg3)
27{
28 size_t len = arg0;
29 size_t i;
30 size_t offset = 0;
31 char print_buf[4];
32
33 (void)arg1;
34 (void)arg2;
35 (void)arg3;
36
37 while (len > 0U) {
38 char *shared_page;
39 size_t to_print = len;
40
41 if (to_print > sizeof(print_buf)) {
42 to_print = sizeof(print_buf);
43 }
44 shared_page = app_data->el2_shared_page;
45 assert(shared_page != NULL);
46 (void)memcpy(print_buf, &shared_page[offset], to_print);
47 for (i = 0; i < to_print; ++i) {
48 (void)console_putc((int)print_buf[i]);
49 }
50 offset += to_print;
51 len -= to_print;
52 }
53 return 0;
54}
55
Mate Toth-Pal646c6032025-02-06 11:01:37 +010056static uint64_t app_service_get_random(struct app_data_cfg *app_data,
57 unsigned long arg0,
58 unsigned long arg1,
59 unsigned long arg2,
60 unsigned long arg3)
61{
62 size_t len = arg0;
63 uint8_t buf[GRANULE_SIZE];
64 int ret;
65 void *shared_page;
66
67 (void)arg1;
68 (void)arg2;
69 (void)arg3;
70
71 if (len >= GRANULE_SIZE) {
72 return (uint64_t)(-EINVAL);
73 }
74
75 /* TODO: The random app generates the random values to the shared memory between
76 * RMM and random app. that gets copied to buf. That's gets copied to the shared
77 * memory between RMM and calling app. This should be optimised.
78 */
79
80 struct app_data_cfg *random_app_data = random_app_get_data_cfg();
81
82 ret = random_app_prng_get_random(random_app_data, buf, len);
83 if (ret != 0) {
84 return (uint64_t)ret;
85 }
86
87 shared_page = app_data->el2_shared_page;
88 assert(shared_page != NULL);
89 /* coverity[misra_c_2012_rule_9_1_violation:SUPPRESS] */
90 (void)memcpy(shared_page, (void *)buf, len);
91 return 0;
92}
93
94static uint64_t app_service_get_realm_attestation_key(struct app_data_cfg *app_data,
95 unsigned long arg0,
96 unsigned long arg1,
97 unsigned long arg2,
98 unsigned long arg3)
99{
100 uintptr_t buf;
101 size_t attest_key_size;
102 struct service_get_realm_attestation_key_struct *shared_page;
103
104 (void)arg0;
105 (void)arg1;
106 (void)arg2;
107 (void)arg3;
108
109 /*
110 * Get the realm attestation key. The key is retrieved in raw format.
111 */
112 buf = rmm_el3_ifc_get_shared_buf_locked();
113
114 if (rmm_el3_ifc_get_realm_attest_key(buf,
115 rmm_el3_ifc_get_shared_buf_size(),
116 &attest_key_size,
117 ATTEST_KEY_CURVE_ECC_SECP384R1) != 0) {
118 rmm_el3_ifc_release_shared_buf();
119 return (uint64_t)(-EINVAL);
120 }
121
122 if (attest_key_size >= APP_MAX_ATTEST_KEY_SIZE) {
123 return (uint64_t)(-EINVAL);
124 }
125
126 shared_page = app_data->el2_shared_page;
127 assert(shared_page != NULL);
128 shared_page->attest_key_buf_size = attest_key_size;
129 (void)memcpy((void *)shared_page->attest_key_buf,
130 (void *)buf, shared_page->attest_key_buf_size);
131
132 /* Clear the private key from the buffer */
133 (void)memset((uint8_t *)buf, 0, attest_key_size);
134
135 rmm_el3_ifc_release_shared_buf();
136
137 return 0;
138}
139
140static uint64_t app_service_get_platform_token(struct app_data_cfg *app_data,
141 unsigned long arg0,
142 unsigned long arg1,
143 unsigned long arg2,
144 unsigned long arg3)
145{
146 size_t current_hunk_len = 0;
147 size_t bytes_remaining = 0;
148 size_t hash_size = arg0;
149 int ret;
150 uintptr_t shared_buf;
151 void *shared_page_void;
152 struct service_get_platform_token_struct *shared_page_get_plat_token;
153
154 size_t service_token_buf_len = sizeof(shared_page_get_plat_token->token_hunk_buf);
155
156 (void)arg1;
157 (void)arg2;
158 (void)arg3;
159
160 if (hash_size >= GRANULE_SIZE) {
161 return (uint64_t)(-EINVAL);
162 }
163
164 shared_buf = rmm_el3_ifc_get_shared_buf_locked();
165
166 shared_page_void = app_data->el2_shared_page;
167 assert(shared_page_void != NULL);
168 (void)memcpy((void *)shared_buf, shared_page_void, hash_size);
169
170 do {
171 ret = rmm_el3_ifc_get_platform_token(
172 shared_buf,
173 service_token_buf_len,
174 hash_size,
175 &current_hunk_len,
176 &bytes_remaining);
177 } while (ret == E_RMM_AGAIN);
178
179 if (ret != E_RMM_OK) {
180 assert(ret != 0);
181 rmm_el3_ifc_release_shared_buf();
182 return (uint64_t)ret;
183 }
184
185 shared_page_get_plat_token = app_data->el2_shared_page;
186 assert(shared_page_get_plat_token != NULL);
187 assert(current_hunk_len <= GRANULE_SIZE);
188 assert(current_hunk_len <= sizeof(shared_page_get_plat_token->token_hunk_buf));
189 /* coverity[misra_c_2012_rule_21_18_violation:SUPPRESS] */
190 (void)memcpy((void *)shared_page_get_plat_token->token_hunk_buf, (void *)shared_buf, current_hunk_len);
191 rmm_el3_ifc_release_shared_buf();
192
193 shared_page_get_plat_token->token_hunk_len = current_hunk_len;
194 shared_page_get_plat_token->remaining_len = bytes_remaining;
195
196 return 0;
197}
198
199#if ATTEST_EL3_TOKEN_SIGN
200static uint64_t app_service_get_realm_attest_pub_key_from_el3(struct app_data_cfg *app_data,
201 unsigned long arg0,
202 unsigned long arg1,
203 unsigned long arg2,
204 unsigned long arg3)
205{
206 uintptr_t buf;
207 size_t attest_key_size;
208 struct service_get_realm_attestation_pub_key_struct *shared_page;
209
210 (void)arg0;
211 (void)arg1;
212 (void)arg2;
213 (void)arg3;
214
215 /*
216 * Get the realm attestation key. The key is retrieved in raw format.
217 */
218 buf = rmm_el3_ifc_get_shared_buf_locked();
219
220 /* When EL3 service is used for attestation, EL3 returns public key in raw format */
221 if (rmm_el3_ifc_get_realm_attest_pub_key_from_el3(buf,
222 rmm_el3_ifc_get_shared_buf_size(),
223 &attest_key_size,
224 ATTEST_KEY_CURVE_ECC_SECP384R1) != 0) {
225 rmm_el3_ifc_release_shared_buf();
226 return -EINVAL;
227 }
228
229 shared_page = app_data->el2_shared_page;
230 assert(attest_key_size <= sizeof(shared_page->attest_pub_key_buf));
231 shared_page->attest_pub_key_buf_size = attest_key_size;
232 memcpy((void *)&(shared_page->attest_pub_key_buf), (const void *)buf, attest_key_size);
233 rmm_el3_ifc_release_shared_buf();
234 return 0;
235}
236
237static uint64_t app_service_el3_token_sign_queue_try_enqueue(struct app_data_cfg *app_data,
238 unsigned long arg0,
239 unsigned long arg1,
240 unsigned long arg2,
241 unsigned long arg3)
242{
243 uint64_t ret;
244 struct service_el3_token_sign_request *request = app_data->el2_shared_page;
245
246 (void)arg0;
247 (void)arg1;
248 (void)arg2;
249 (void)arg3;
250
251 ret = el3_token_sign_queue_try_enqueue(request);
252 return ret;
253}
254
255static uint64_t app_service_el3_ifc_el3_token_sign_supported(struct app_data_cfg *app_data,
256 unsigned long arg0,
257 unsigned long arg1,
258 unsigned long arg2,
259 unsigned long arg3)
260{
261 (void)app_data;
262 (void)arg0;
263 (void)arg1;
264 (void)arg2;
265 (void)arg3;
266
267 return rmm_el3_ifc_el3_token_sign_supported();
268}
269#endif
270
Mate Toth-Pal57fadaf2025-02-06 10:21:30 +0100271static app_service_func service_functions[APP_SERVICE_COUNT] = {
Mate Toth-Pal646c6032025-02-06 11:01:37 +0100272 [APP_SERVICE_PRINT] = app_service_print,
273 [APP_SERVICE_RANDOM] = app_service_get_random,
274 [APP_SERVICE_GET_REALM_ATTESTATION_KEY] = app_service_get_realm_attestation_key,
275 [APP_SERVICE_GET_PLATFORM_TOKEN] = app_service_get_platform_token,
276#if ATTEST_EL3_TOKEN_SIGN
277 [APP_SERVICE_GET_REALM_ATTEST_PUB_KEY_FROM_EL3] = app_service_get_realm_attest_pub_key_from_el3,
278 [APP_SERVICE_EL3_TOKEN_SIGN_QUEUE_TRY_ENQUEUE] = app_service_el3_token_sign_queue_try_enqueue,
279 [APP_SERVICE_EL3_IFC_EL3_TOKEN_SIGN_SUPPORTED] = app_service_el3_ifc_el3_token_sign_supported,
280#endif /* ATTEST_EL3_TOKEN_SIGN */
281 };
Mate Toth-Pal57fadaf2025-02-06 10:21:30 +0100282
283uint64_t call_app_service(unsigned long service_id,
284 struct app_data_cfg *app_data,
285 unsigned long arg0,
286 unsigned long arg1,
287 unsigned long arg2,
288 unsigned long arg3)
289{
290 (void)arg0;
291 (void)arg1;
292 (void)arg2;
293 (void)arg3;
294
295 assert(service_id < APP_SERVICE_COUNT);
296 assert(service_functions[service_id] != NULL);
297
298 return service_functions[service_id](app_data, arg0, arg1, arg2, arg3);
299}
300