blob: 1decef505c622dd9bf4a699cea0ff9592bb77018 [file] [log] [blame]
Etienne Carriere41343db2017-03-17 15:38:52 +01001/*
2 * Copyright (c) 2016, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
Etienne Carrierec45d9762017-03-21 15:45:13 +010028#include <pta_invoke_tests.h>
Etienne Carriere41343db2017-03-17 15:38:52 +010029#include <string.h>
Etienne Carrierec45d9762017-03-21 15:45:13 +010030#include <ta_sdp_basic.h>
Etienne Carriere41343db2017-03-17 15:38:52 +010031#include <tee_api.h>
32#include <tee_internal_api_extensions.h>
33#include <tee_internal_api.h>
34#include <tee_ta_api.h>
35#include <trace.h>
36
Etienne Carriere41343db2017-03-17 15:38:52 +010037
38/*
39 * Basic Secure Data Path access test commands:
40 * - command INJECT: copy from non secure input into secure output.
41 * - command TRANSFROM: read, transform and write from/to secure in/out.
42 * - command DUMP: copy from secure input into non secure output.
43 */
44
45static TEE_Result cmd_inject(uint32_t types,
46 TEE_Param params[TEE_NUM_PARAMS])
47{
Etienne Carriere102092e2019-03-28 15:24:22 +010048 TEE_Result rc = TEE_ERROR_GENERIC;
Etienne Carriere41343db2017-03-17 15:38:52 +010049 const int sec_idx = 1; /* highlight secure buffer index */
50 const int ns_idx = 0; /* highlight nonsecure buffer index */
51
52 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
53 TEE_PARAM_TYPE_MEMREF_OUTPUT,
54 TEE_PARAM_TYPE_NONE,
55 TEE_PARAM_TYPE_NONE)) {
56 EMSG("bad parameters %x", (unsigned)types);
57 return TEE_ERROR_BAD_PARAMETERS;
58 }
59
60 if (params[sec_idx].memref.size < params[ns_idx].memref.size)
61 return TEE_ERROR_SHORT_BUFFER;
62
63 /*
64 * We could rely on the TEE to provide consistent buffer/size values
65 * to reference a buffer with a unique and consistent secure attribute
66 * value. Hence it is safe enough (and more optimal) to test only the
67 * secure attribute of a single byte of it. Yet, since the current
68 * test does not deal with performance, let check the secure attribute
69 * of each byte of the buffer.
70 */
71 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
72 TEE_MEMORY_ACCESS_READ |
73 TEE_MEMORY_ACCESS_NONSECURE,
74 params[ns_idx].memref.buffer,
75 params[ns_idx].memref.size);
76 if (rc != TEE_SUCCESS) {
77 EMSG("TEE_CheckMemoryAccessRights(nsec) failed %x", rc);
78 return rc;
79 }
80
81 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
82 TEE_MEMORY_ACCESS_WRITE |
83 TEE_MEMORY_ACCESS_SECURE,
84 params[sec_idx].memref.buffer,
85 params[sec_idx].memref.size);
86 if (rc != TEE_SUCCESS) {
87 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
88 return rc;
89 }
90
91
92#ifdef CFG_CACHE_API
93 /*
94 * we should invalidate cache (here we assume buffer were not
95 * filled through cpu core caches. We flush buffers so that
96 * cache is not corrupted in cache target buffer not aligned
97 * on cache line size.
98 */
99 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
100 params[sec_idx].memref.size);
101 if (rc != TEE_SUCCESS) {
102 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
103 params[sec_idx].memref.buffer,
104 params[sec_idx].memref.size, rc);
105 return rc;
106 }
107#endif /* CFG_CACHE_API */
108
109 /* inject data */
110 TEE_MemMove(params[sec_idx].memref.buffer,
111 params[ns_idx].memref.buffer,
112 params[sec_idx].memref.size);
113
114#ifdef CFG_CACHE_API
115 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
116 params[sec_idx].memref.size);
117 if (rc != TEE_SUCCESS) {
118 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
119 params[sec_idx].memref.buffer,
120 params[sec_idx].memref.size, rc);
121 return rc;
122 }
123#endif /* CFG_CACHE_API */
124
125 return rc;
126}
127
128static TEE_Result cmd_transform(uint32_t types,
129 TEE_Param params[TEE_NUM_PARAMS])
130{
Etienne Carriere102092e2019-03-28 15:24:22 +0100131 TEE_Result rc = TEE_ERROR_GENERIC;
132 unsigned char *p = NULL;
133 size_t sz = 0;
Etienne Carriere41343db2017-03-17 15:38:52 +0100134
135 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
136 TEE_PARAM_TYPE_NONE,
137 TEE_PARAM_TYPE_NONE,
138 TEE_PARAM_TYPE_NONE))
139 return TEE_ERROR_BAD_PARAMETERS;
140
141 /*
142 * We could rely on the TEE to provide consistent buffer/size values
143 * to reference a buffer with a unique and consistent secure attribute
144 * value. Hence it is safe enough (and more optimal) to test only the
145 * secure attribute of a single byte of it. Yet, since the current
146 * test does not deal with performance, let check the secure attribute
147 * of each byte of the buffer.
148 */
149 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
150 TEE_MEMORY_ACCESS_READ |
151 TEE_MEMORY_ACCESS_WRITE |
152 TEE_MEMORY_ACCESS_SECURE,
153 params[0].memref.buffer,
154 params[0].memref.size);
155 if (rc != TEE_SUCCESS) {
156 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
157 return rc;
158 }
159
160
161#ifdef CFG_CACHE_API
162 /*
163 * we should invalidate cache (here we assume buffer were not
164 * filled through cpu core caches. We flush buffers so that
165 * cache is not corrupted in cache target buffer not aligned
166 * on cache line size.
167 */
168 rc = TEE_CacheFlush(params[0].memref.buffer,
169 params[0].memref.size);
170 if (rc != TEE_SUCCESS) {
171 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
172 params[0].memref.buffer,
173 params[0].memref.size, rc);
174 return rc;
175 }
176#endif /* CFG_CACHE_API */
177
178 /* transform the data */
179 p = (unsigned char *)params[0].memref.buffer;
180 sz = params[0].memref.size;
181 for (; sz; sz--, p++)
182 *p = ~(*p) + 1;
183
184#ifdef CFG_CACHE_API
185 rc = TEE_CacheFlush(params[0].memref.buffer,
186 params[0].memref.size);
187 if (rc != TEE_SUCCESS) {
188 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
189 params[0].memref.buffer,
190 params[0].memref.size, rc);
191 return rc;
192 }
193#endif /* CFG_CACHE_API */
194
195 return rc;
196}
197
198static TEE_Result cmd_dump(uint32_t types,
199 TEE_Param params[TEE_NUM_PARAMS])
200{
Etienne Carriere102092e2019-03-28 15:24:22 +0100201 TEE_Result rc = TEE_ERROR_GENERIC;
Etienne Carriere41343db2017-03-17 15:38:52 +0100202 const int sec_idx = 0; /* highlight secure buffer index */
203 const int ns_idx = 1; /* highlight nonsecure buffer index */
204
205 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
206 TEE_PARAM_TYPE_MEMREF_OUTPUT,
207 TEE_PARAM_TYPE_NONE,
208 TEE_PARAM_TYPE_NONE))
209 return TEE_ERROR_BAD_PARAMETERS;
210
211 if (params[ns_idx].memref.size < params[sec_idx].memref.size)
212 return TEE_ERROR_SHORT_BUFFER;
213
214 /*
215 * We could rely on the TEE to provide consistent buffer/size values
216 * to reference a buffer with a unique and consistent secure attribute
217 * value. Hence it is safe enough (and more optimal) to test only the
218 * secure attribute of a single byte of it. Yet, since the current
219 * test does not deal with performance, let check the secure attribute
220 * of each byte of the buffer.
221 */
222 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
223 TEE_MEMORY_ACCESS_WRITE |
224 TEE_MEMORY_ACCESS_NONSECURE,
225 params[ns_idx].memref.buffer,
226 params[ns_idx].memref.size);
227 if (rc != TEE_SUCCESS) {
228 EMSG("TEE_CheckMemoryAccessRights(nsec) failed %x", rc);
229 return rc;
230 }
231
232 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
233 TEE_MEMORY_ACCESS_READ |
234 TEE_MEMORY_ACCESS_SECURE,
235 params[sec_idx].memref.buffer,
236 params[sec_idx].memref.size);
237 if (rc != TEE_SUCCESS) {
238 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
239 return rc;
240 }
241
242#ifdef CFG_CACHE_API
243 /*
244 * we should invalidate cache (here we assume buffer were not
245 * filled through cpu core caches. We flush buffers so that
246 * cache is not corrupted in cache target buffer not aligned
247 * on cache line size.
248 */
249 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
250 params[sec_idx].memref.size);
251 if (rc != TEE_SUCCESS) {
252 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
253 params[sec_idx].memref.buffer,
254 params[sec_idx].memref.size, rc);
255 return rc;
256 }
257#endif /* CFG_CACHE_API */
258
259 /* dump the data */
260 TEE_MemMove(params[ns_idx].memref.buffer,
261 params[sec_idx].memref.buffer,
262 params[sec_idx].memref.size);
263
264 return rc;
265}
266
Etienne Carrieref690b912017-03-21 15:44:13 +0100267static TEE_Result cmd_invoke(uint32_t nParamTypes,
268 TEE_Param pParams[TEE_NUM_PARAMS],
269 uint32_t nCommandID)
270{
271 const TEE_UUID uuid = TA_SDP_BASIC_UUID;
272 static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100273 uint32_t ret_orig = 0;
274 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carrieref690b912017-03-21 15:44:13 +0100275
276 if (sess == TEE_HANDLE_NULL) {
Cedric Augere668b3f2019-09-11 13:41:21 +0200277 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
278 &sess, &ret_orig);
Etienne Carrieref690b912017-03-21 15:44:13 +0100279 if (res != TEE_SUCCESS) {
280 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED \n");
281 goto cleanup_return;
282 }
283
284 }
285
Cedric Augere668b3f2019-09-11 13:41:21 +0200286 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
287 nCommandID, nParamTypes, pParams, &ret_orig);
Etienne Carrieref690b912017-03-21 15:44:13 +0100288 if (res != TEE_SUCCESS) {
289 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED %x/%d\n",
290 res, ret_orig);
291 }
292
293cleanup_return:
294 if (res != TEE_SUCCESS) {
295 TEE_CloseTASession(sess);
296 sess = TEE_HANDLE_NULL;
297 }
298 return res;
299}
300
Etienne Carrierec45d9762017-03-21 15:45:13 +0100301static TEE_Result cmd_invoke_pta(uint32_t nParamTypes,
302 TEE_Param pParams[TEE_NUM_PARAMS],
303 uint32_t nCommandID)
304{
305 const TEE_UUID uuid = PTA_INVOKE_TESTS_UUID;
306 static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
Etienne Carriere102092e2019-03-28 15:24:22 +0100307 uint32_t ret_orig = 0;
308 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100309
310 if (sess == TEE_HANDLE_NULL) {
Cedric Augere668b3f2019-09-11 13:41:21 +0200311 res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
312 &sess, &ret_orig);
Etienne Carrierec45d9762017-03-21 15:45:13 +0100313 if (res != TEE_SUCCESS) {
314 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED \n");
315 goto cleanup_return;
316 }
317
318 }
319
Cedric Augere668b3f2019-09-11 13:41:21 +0200320 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE,
321 nCommandID, nParamTypes, pParams, &ret_orig);
Etienne Carrierec45d9762017-03-21 15:45:13 +0100322 if (res != TEE_SUCCESS) {
323 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED %x/%d\n",
324 res, ret_orig);
325 }
326
327cleanup_return:
328 if (res != TEE_SUCCESS) {
329 TEE_CloseTASession(sess);
330 sess = TEE_HANDLE_NULL;
331 }
332 return res;
333}
334
Etienne Carriere41343db2017-03-17 15:38:52 +0100335TEE_Result TA_CreateEntryPoint(void)
336{
337 return TEE_SUCCESS;
338}
339
340void TA_DestroyEntryPoint(void)
341{
342}
343
344TEE_Result TA_OpenSessionEntryPoint(uint32_t nParamTypes,
345 TEE_Param pParams[TEE_NUM_PARAMS],
346 void **ppSessionContext)
347{
348 (void)nParamTypes;
349 (void)pParams;
350 (void)ppSessionContext;
351 return TEE_SUCCESS;
352}
353
354void TA_CloseSessionEntryPoint(void *pSessionContext)
355{
356 (void)pSessionContext;
357}
358
359TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext,
360 uint32_t nCommandID, uint32_t nParamTypes,
361 TEE_Param pParams[TEE_NUM_PARAMS])
362{
363 (void)pSessionContext;
364
365 switch (nCommandID) {
366 case TA_SDP_BASIC_CMD_INJECT:
367 return cmd_inject(nParamTypes, pParams);
368 case TA_SDP_BASIC_CMD_TRANSFORM:
369 return cmd_transform(nParamTypes, pParams);
370 case TA_SDP_BASIC_CMD_DUMP:
371 return cmd_dump(nParamTypes, pParams);
Etienne Carrieref690b912017-03-21 15:44:13 +0100372
373 case TA_SDP_BASIC_CMD_INVOKE_INJECT:
374 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_INJECT);
375 case TA_SDP_BASIC_CMD_INVOKE_TRANSFORM:
376 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_TRANSFORM);
377 case TA_SDP_BASIC_CMD_INVOKE_DUMP:
378 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_DUMP);
379
Etienne Carrierec45d9762017-03-21 15:45:13 +0100380 case TA_SDP_BASIC_CMD_PTA_INJECT:
381 return cmd_invoke_pta(nParamTypes, pParams, PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC);
382 case TA_SDP_BASIC_CMD_PTA_TRANSFORM:
383 return cmd_invoke_pta(nParamTypes, pParams, PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC);
384 case TA_SDP_BASIC_CMD_PTA_DUMP:
385 return cmd_invoke_pta(nParamTypes, pParams, PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC);
386
Etienne Carriere41343db2017-03-17 15:38:52 +0100387 default:
388 return TEE_ERROR_BAD_PARAMETERS;
389 }
390}