blob: d843c047c6aba3c36f384deaedc9d652b2fa1821 [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
28#include <err.h>
29#include <fcntl.h>
Etienne Carrierec45d9762017-03-21 15:45:13 +010030#include <pta_invoke_tests.h>
Etienne Carriere41343db2017-03-17 15:38:52 +010031#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <sys/ioctl.h>
35#include <sys/mman.h>
36#include <tee_client_api.h>
37#include <tee_client_api_extensions.h>
38#include <unistd.h>
39
40#include "include/uapi/linux/ion.h"
41#include "ta_sdp_basic.h"
42#include "crypto_common.h"
43
44/*
45 * SDP basic test setup overview.
46 *
47 * - A dedicated trusted application (SDP basic TA) supports 3 commands:
48 * - 'inject' data from a nonsecure buffer into a secure buffer
49 * - 'transform' data inside a secure buffer (bitwise invert + unsigned incr)
50 * - 'dump' data from a secure buffer into a nonsecure buffer
51
52 * - This test client application (CA) invokes the TA for these 3 operations,
53 * inject random value, trasforming them then dump them.
54 *
55 * To do so, CA allocates a 'SDP secure buffer' and invoke the TA for these 3
56 * operations (inject then transform then dump) over the allocate buffer.
57 *
58 * The secure buffer is currently allocation through ION support adn
59 * registered to OP-TEE and as shared memory.
60 *
61 * To enhance test coverage against buffer alignement usecase, the CA invokes
62 * the TA with a variable offset inside the buffer. As CA injects random data
63 * into the buffer, the CA uses one of the random bytes to set the value of the
64 * offset in the accessed secure buffer.
65 *
66 * For debugging support, the CA may map (in nonsecure world) the secure
67 * buffer to read its content. As this is unsafe on a hardened platform, this
68 * operation is default disable. When enable, error only print out a warning
69 * trace but does not actually fail the test. This also give an easy way to
70 * check that some HW complains on access violation when nonsecure accesses
71 * secure data.
72 */
73
74static int verbosity = 1;
75
76struct tee_ctx {
77 TEEC_Context ctx;
78 TEEC_Session sess;
79};
80
81/* exported to xtest */
82int allocate_ion_buffer(size_t size, int heap_id);
83
84/* non zero value forces buffer to be mappeable from nonsecure */
85#define BUF_MUST_MAP 0
86
87#define DEFAULT_ION_HEAP_TYPE ION_HEAP_TYPE_UNMAPPED
88
Etienne Carrierec45d9762017-03-21 15:45:13 +010089enum test_target_ta {
90 TEST_NS_TO_TA,
91 TEST_NS_TO_PTA,
92 TEST_TA_TO_TA,
93 TEST_TA_TO_PTA,
94};
95
Etienne Carriere41343db2017-03-17 15:38:52 +010096int allocate_ion_buffer(size_t size, int heap_id)
97{
98 struct ion_allocation_data alloc_data;
99 struct ion_handle_data hdl_data;
100 struct ion_fd_data fd_data;
101 int ion;
102 int fd = -1;
103
104 ion = open("/dev/ion", O_RDWR);
105 if (ion < 0) {
106 fprintf(stderr, "Error; failed to open /dev/ion\n");
107 verbose("Seems no ION heap is available.\n");
108 verbose("To test ION allocation you can enable\n");
109 verbose("CONFIG_ION and CONFIG_ION_DUMMY in your\n");
110 verbose("linux kernel configuration.\n");
111 return fd;
112 }
113
114 if (heap_id < 0)
115 heap_id = DEFAULT_ION_HEAP_TYPE;
116
117 verbose("Allocate in ION heap '%s'\n",
118 heap_id == ION_HEAP_TYPE_SYSTEM ? "system" :
119 heap_id == ION_HEAP_TYPE_SYSTEM_CONTIG ? "system contig" :
120 heap_id == ION_HEAP_TYPE_CARVEOUT ? "carveout" :
121 heap_id == ION_HEAP_TYPE_CHUNK ? "chunk" :
122 heap_id == ION_HEAP_TYPE_DMA ? "dma" :
123 heap_id == ION_HEAP_TYPE_UNMAPPED ? "unmapped" :
124 "custom");
125
126 alloc_data.len = size;
127 alloc_data.align = 0;
128 alloc_data.flags = 0;
129 alloc_data.heap_id_mask = 1 << heap_id;
130 if (ioctl(ion, ION_IOC_ALLOC, &alloc_data) == -1)
131 goto out;
132
133 fd_data.handle = alloc_data.handle;
134 if (ioctl(ion, ION_IOC_SHARE, &fd_data) != -1)
135 fd = fd_data.fd;
136
137 hdl_data.handle = alloc_data.handle;
138 (void)ioctl(ion, ION_IOC_FREE, &hdl_data);
139out:
140 close(ion);
141 return fd;
142}
143
144static void finalize_tee_ctx(struct tee_ctx *ctx)
145{
146 if (!ctx)
147 return;
148
149 TEEC_CloseSession(&ctx->sess);
150 TEEC_FinalizeContext(&ctx->ctx);
151}
152
Etienne Carrierec45d9762017-03-21 15:45:13 +0100153static int create_tee_ctx(struct tee_ctx *ctx, enum test_target_ta target_ta)
Etienne Carriere41343db2017-03-17 15:38:52 +0100154{
155 TEEC_Result teerc;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100156 TEEC_UUID ta_uuid = TA_SDP_BASIC_UUID;
157 TEEC_UUID pta_uuid = PTA_INVOKE_TESTS_UUID;
158 TEEC_UUID *uuid;
Etienne Carriere41343db2017-03-17 15:38:52 +0100159 uint32_t err_origin;
160
Etienne Carrierec45d9762017-03-21 15:45:13 +0100161 switch (target_ta) {
162 case TEST_NS_TO_TA:
163 case TEST_TA_TO_TA:
164 case TEST_TA_TO_PTA:
165 uuid = &ta_uuid;
166 break;
167 case TEST_NS_TO_PTA:
168 uuid = &pta_uuid;
169 break;
170 default:
171 return -1;
172 }
173
Etienne Carriere41343db2017-03-17 15:38:52 +0100174 teerc = TEEC_InitializeContext(NULL, &ctx->ctx);
175 if (teerc != TEEC_SUCCESS)
176 return -1;
177
Etienne Carrierec45d9762017-03-21 15:45:13 +0100178 teerc = TEEC_OpenSession(&ctx->ctx, &ctx->sess, uuid,
Etienne Carriere41343db2017-03-17 15:38:52 +0100179 TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
180 if (teerc != TEEC_SUCCESS)
Etienne Carrierec45d9762017-03-21 15:45:13 +0100181 fprintf(stderr, "Error: open session to target test %s failed %x %d\n",
182 (target_ta == TEST_NS_TO_PTA) ? "pTA" : "TA",
Etienne Carriere41343db2017-03-17 15:38:52 +0100183 teerc, err_origin);
184
185 return (teerc == TEEC_SUCCESS) ? 0 : -1;
186}
187
188static int tee_register_buffer(struct tee_ctx *ctx, void **shm_ref, int fd)
189{
190 TEEC_Result teerc;
191 TEEC_SharedMemory *shm;
192
193 shm = malloc(sizeof(*shm));
194 if (!shm)
195 return 1;
196
197 shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
198 teerc = TEEC_RegisterSharedMemoryFileDescriptor(&ctx->ctx, shm, fd);
199 if (teerc != TEEC_SUCCESS) {
200 fprintf(stderr, "Error: TEEC_RegisterMemoryFileDescriptor() failed %x\n",
201 teerc);
202 return 1;
203 }
204
205 *shm_ref = shm;
206 return 0;
207}
208
209static void tee_deregister_buffer(struct tee_ctx *ctx, void *shm_ref)
210{
211 (void)ctx;
212
213 if (!shm_ref)
214 return;
215
216 TEEC_ReleaseSharedMemory((TEEC_SharedMemory *)shm_ref);
217 free(shm_ref);
218}
219
220static int inject_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100221 void *in, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100222{
223 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
224 TEEC_Result teerc;
225 TEEC_Operation op;
226 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100227 unsigned cmd;
228
229 switch (ind) {
230 case TEST_NS_TO_TA:
231 cmd = TA_SDP_BASIC_CMD_INJECT;
232 break;
233 case TEST_TA_TO_TA:
234 cmd = TA_SDP_BASIC_CMD_INVOKE_INJECT;
235 break;
236 case TEST_TA_TO_PTA:
237 cmd = TA_SDP_BASIC_CMD_PTA_INJECT;
238 break;
239 case TEST_NS_TO_PTA:
240 cmd = PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC;
241 break;
242 default:
243 return -1;
244 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100245
246 memset(&op, 0, sizeof(op));
247 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
248 TEEC_MEMREF_PARTIAL_OUTPUT,
249 TEEC_NONE, TEEC_NONE);
250
251 op.params[0].tmpref.buffer = in;
252 op.params[0].tmpref.size = len;
253
254 op.params[1].memref.parent = shm;
255 op.params[1].memref.size = len;
256 op.params[1].memref.offset = offset;
257
Etienne Carrieref690b912017-03-21 15:44:13 +0100258 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100259 if (teerc != TEEC_SUCCESS)
260 fprintf(stderr, "Error: invoke SDP test TA (inject) failed %x %d\n",
261 teerc, err_origin);
262
263 return (teerc == TEEC_SUCCESS) ? 0 : -1;
264}
265
266static int transform_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100267 size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100268{
269 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
270 TEEC_Result teerc;
271 TEEC_Operation op;
272 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100273 unsigned cmd;
274
275 switch (ind) {
276 case TEST_NS_TO_TA:
277 cmd = TA_SDP_BASIC_CMD_TRANSFORM;
278 break;
279 case TEST_TA_TO_TA:
280 cmd = TA_SDP_BASIC_CMD_INVOKE_TRANSFORM;
281 break;
282 case TEST_TA_TO_PTA:
283 cmd = TA_SDP_BASIC_CMD_PTA_TRANSFORM;
284 break;
285 case TEST_NS_TO_PTA:
286 cmd = PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC;
287 break;
288 default:
289 return -1;
290 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100291
292 memset(&op, 0, sizeof(op));
293 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
294 TEEC_NONE, TEEC_NONE, TEEC_NONE);
295 op.params[0].memref.parent = shm;
296 op.params[0].memref.size = len;
297 op.params[0].memref.offset = offset;
298
Etienne Carrieref690b912017-03-21 15:44:13 +0100299 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100300 if (teerc != TEEC_SUCCESS)
301 fprintf(stderr, "Error: invoke SDP test TA (transform) failed %x %d\n",
302 teerc, err_origin);
303
304 return (teerc == TEEC_SUCCESS) ? 0 : -1;
305}
306
307static int dump_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100308 void *out, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100309{
310 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
311 TEEC_Result teerc;
312 TEEC_Operation op;
313 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100314 unsigned cmd;
315
316 switch (ind) {
317 case TEST_NS_TO_TA:
318 cmd = TA_SDP_BASIC_CMD_DUMP;
319 break;
320 case TEST_TA_TO_TA:
321 cmd = TA_SDP_BASIC_CMD_INVOKE_DUMP;
322 break;
323 case TEST_TA_TO_PTA:
324 cmd = TA_SDP_BASIC_CMD_PTA_DUMP;
325 break;
326 case TEST_NS_TO_PTA:
327 cmd = PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC;
328 break;
329 default:
330 return -1;
331 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100332
333 memset(&op, 0, sizeof(op));
334 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
335 TEEC_MEMREF_TEMP_OUTPUT,
336 TEEC_NONE, TEEC_NONE);
337 op.params[0].memref.parent = shm;
338 op.params[0].memref.size = len;
339 op.params[0].memref.offset = offset;
340
341 op.params[1].tmpref.buffer = out;
342 op.params[1].tmpref.size = len;
343
Etienne Carrieref690b912017-03-21 15:44:13 +0100344 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100345 if (teerc != TEEC_SUCCESS)
346 fprintf(stderr, "Error: invoke SDP test TA (dump) failed %x %d\n",
347 teerc, err_origin);
348
349 return (teerc == TEEC_SUCCESS) ? 0 : -1;
350}
351
352static int check_sdp_dumped(struct tee_ctx *ctx, void *ref, size_t len,
353 void *out)
354{
355 char *bref = (char *)ref;
356 char *data = (char *)out;
357 int err = 0;
358
359 (void)ctx;
360
361 while(len--)
362 if (*data++ != (unsigned char)(~(*bref++) + 1))
363 err++;
364
365 return err;
366}
367
368/*
369 * Consider 32kByte + 1 of random data is sufficient for an accurate test
370 * whatever the test buffer size is. Random buffer is read as a ring buffer.
371 */
372#define RANDOM_BUFFER_SIZE (32 * 1024 + 1)
373static int get_random_bytes(char *out, size_t len)
374{
375 static char *rand_buf = NULL;
376 static size_t rand_idx = 0;
377 int rc;
378
379 if (!rand_buf) {
380 const char rand_dev[] = "/dev/urandom";
381 int fd;
382
383 rand_buf = malloc(RANDOM_BUFFER_SIZE);
384 if (!rand_buf) {
385 fprintf(stderr, "failed to random buffer memory (%d bytes)\n",
386 RANDOM_BUFFER_SIZE);
387 return -1;
388 }
389
390 fd = open(rand_dev, O_RDONLY);
391 if (fd < 0) {
392 fprintf(stderr, "failed to open %s\n", rand_dev);
393 return -1;
394 }
395
396 rc = read(fd, rand_buf, RANDOM_BUFFER_SIZE);
397 if (rc != RANDOM_BUFFER_SIZE) {
398 fprintf(stderr, "failed to read %d bytes from %s\n",
399 RANDOM_BUFFER_SIZE, rand_dev);
400 return -1;
401 }
402 close(fd);
403 }
404
405 while (len) {
406 size_t t_len = (RANDOM_BUFFER_SIZE < len) ? RANDOM_BUFFER_SIZE : len;
407
408 if ((rand_idx + t_len) > RANDOM_BUFFER_SIZE) {
409 int sz_end = RANDOM_BUFFER_SIZE - rand_idx;
410 int sz_beg = t_len - sz_end;
411
412 memcpy(out, rand_buf + rand_idx, sz_end);
413 memcpy(out + sz_end, rand_buf , sz_beg);
414 rand_idx = sz_beg;
415 } else {
416 memcpy(out, rand_buf + rand_idx, t_len);
417 rand_idx += t_len;
418 }
419 len -= t_len;
420 }
421 return 0;
422}
423
424
Etienne Carrierec45d9762017-03-21 15:45:13 +0100425static int sdp_basic_test(enum test_target_ta ta,
426 size_t size, size_t loop, int ion_heap,
427 int rnd_offset)
Etienne Carriere41343db2017-03-17 15:38:52 +0100428{
429 struct tee_ctx *ctx = NULL;
430 unsigned char *test_buf = NULL;
431 unsigned char *ref_buf = NULL;
432 void *shm_ref = NULL;
433 unsigned int err = 1;
434 int fd = -1;
435 size_t sdp_size = size;
436 size_t offset;
Etienne Carrieref690b912017-03-21 15:44:13 +0100437 size_t loop_cnt;
Etienne Carriere41343db2017-03-17 15:38:52 +0100438
439 if (!loop) {
440 fprintf(stderr, "Error: null loop value\n");
441 return 1;
442 }
443
444 /* reduce size to enable offset tests (max offset is 255 bytes) */
445 if (rnd_offset)
446 size -= 255;
447
448 test_buf = malloc(size);
449 ref_buf = malloc(size);
450 if (!test_buf || !ref_buf) {
451 verbose("failed to allocate memory\n");
452 goto out;
453 }
454
455 fd = allocate_ion_buffer(sdp_size, ion_heap);
456 if (fd < 0) {
457 verbose("Failed to allocate SDP buffer (%lu bytes) in ION heap %d: %d\n",
458 sdp_size, ion_heap, fd);
459 goto out;
460 }
461
462 /* register secure buffer to TEE */
463 ctx = malloc(sizeof(*ctx));
464 if (!ctx)
465 goto out;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100466 if (create_tee_ctx(ctx, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100467 goto out;
468 if (tee_register_buffer(ctx, &shm_ref, fd))
469 goto out;
470
471 /* release registered fd: tee should still hold refcount on resource */
472 close(fd);
473 fd = -1;
474
475 /* invoke trusted application with secure buffer as memref parameter */
Etienne Carrieref690b912017-03-21 15:44:13 +0100476 for (loop_cnt = loop; loop_cnt; loop_cnt--) {
Etienne Carriere41343db2017-03-17 15:38:52 +0100477 /* get an buffer of random-like values */
478 if (get_random_bytes((char *)ref_buf, size))
479 goto out;
480 memcpy(test_buf, ref_buf, size);
481 /* random offset [0 255] */
482 offset = (unsigned int)*ref_buf;
483
484 /* TA writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100485 if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100486 goto out;
487
488 /* TA reads/writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100489 if (transform_sdp_data(ctx, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100490 goto out;
491
492 /* TA reads into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100493 if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carrieref690b912017-03-21 15:44:13 +0100494 goto out;
495
496 /* check dumped data are the expected ones */
497 if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) {
498 fprintf(stderr, "check SDP data: %d errors\n", err);
499 goto out;
500 }
501 }
502
Etienne Carriere41343db2017-03-17 15:38:52 +0100503 err = 0;
504 verbose("%s: successed\n", __func__);
505out:
506 if (err)
507 verbose("test failed\n");
508 if (fd >= 0)
509 close(fd);
510 if (shm_ref)
511 tee_deregister_buffer(ctx, shm_ref);
512 finalize_tee_ctx(ctx);
513 free(ctx);
514 free(ref_buf);
515 free(test_buf);
516 return err;
517}
518
519#define _TO_STR(x) #x
520#define TO_STR(x) _TO_STR(x)
521
522static void usage(const char *progname, size_t size, int loop, int ion_heap)
523{
524 fprintf(stderr, "Usage: %s [OPTION]\n", progname);
525 fprintf(stderr,
526 "Testing basic accesses to secure buffer (SDP) on OP-TEE.\n"
527 "Allocates a secure buffer and invoke a TA to access it.\n"
528 "TA is used to init/transform/dump the secure buffer.\n"
529 "CA check dumped content.\n\n");
530
531 fprintf(stderr, "Options:\n");
532 fprintf(stderr, " -h|--help Print this help and exit\n");
533 fprintf(stderr, " -v Be verbose\n");
534 fprintf(stderr, " -s SIZE SDP buffer byte size [%zu]\n", size);
535 fprintf(stderr, " -n LOOP Test loop iterations [%u]\n", loop);
536 fprintf(stderr, " --ion-heap ID Target ION heap ID [%d]\n", ion_heap);
537 fprintf(stderr, " --no-offset No random offset [0 255] in buffer\n");
538}
539
540#define NEXT_ARG(i) \
541 do { \
542 if (++i == argc) { \
543 fprintf(stderr, "%s: %s: missing argument\n", \
544 argv[0], argv[i-1]); \
545 return 1; \
546 } \
547 } while (0);
548
549int sdp_basic_runner_cmd_parser(int argc, char *argv[])
550{
551 size_t test_size = 5000;
552 size_t test_loop = 1000;
553 int ion_heap = DEFAULT_ION_HEAP_TYPE;
554 int rnd_offset = 1;
555 int i;
556
557 /* Parse command line */
558 for (i = 1; i < argc; i++) {
559 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
560 usage(argv[0], test_size, test_loop, ion_heap);
561 return 0;
562 }
563 }
564 for (i = 1; i < argc; i++) {
565 if (!strcmp(argv[i], "-v")) {
566 verbosity++;
567 } else if (!strcmp(argv[i], "-s")) {
568 NEXT_ARG(i);
569 test_size = atoi(argv[i]);
570 } else if (!strcmp(argv[i], "-n")) {
571 NEXT_ARG(i);
572 test_loop = atoi(argv[i]);
573 } else if (!strcmp(argv[i], "--ion-heap")) {
574 NEXT_ARG(i);
575 ion_heap = atoi(argv[i]);
576 } else if (!strcmp(argv[i], "--no-offset")) {
577 rnd_offset = 0;
578 } else {
579 fprintf(stderr, "%s: invalid argument: %s\n",
580 argv[0], argv[i]);
581 usage(argv[0], test_size, test_loop, ion_heap);
582 return 1;
583 }
584 }
585
Etienne Carrierec45d9762017-03-21 15:45:13 +0100586 verbose("\nSecure Data Path basic accesses: NS invokes SDP TA\n");
587 if (sdp_basic_test(TEST_NS_TO_TA,
588 test_size, test_loop, ion_heap, rnd_offset))
589 return 1;
Etienne Carriere41343db2017-03-17 15:38:52 +0100590
Etienne Carrierec45d9762017-03-21 15:45:13 +0100591 verbose("\nSecure Data Path basic accesses: SDP TA invokes SDP TA\n");
592 if (sdp_basic_test(TEST_TA_TO_TA,
593 test_size, test_loop, ion_heap, rnd_offset))
594 return 1;
595
596 verbose("\nSecure Data Path basic accesses: SDP TA invokes SDP pTA\n");
597 if (sdp_basic_test(TEST_TA_TO_PTA,
598 test_size, test_loop, ion_heap, rnd_offset))
Etienne Carriere41343db2017-03-17 15:38:52 +0100599 return 1;
600
Etienne Carriered1655822017-03-21 15:45:24 +0100601 verbose("\nSecure Data Path basic accesses: NS invokes SDP pTA (shall fail)\n");
602 if (sdp_basic_test(TEST_NS_TO_PTA,
603 test_size, test_loop, ion_heap, rnd_offset))
604 verbose("-> false negative: pTAs refuse SDP memref from NS clients.\n");
605
Etienne Carriere41343db2017-03-17 15:38:52 +0100606 return 0;
607}