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