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