xtest: SDP basic tests TA to TA with SDP memref

Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
diff --git a/host/xtest/sdp_basic.c b/host/xtest/sdp_basic.c
index a0fb3ab..e9d5443 100644
--- a/host/xtest/sdp_basic.c
+++ b/host/xtest/sdp_basic.c
@@ -194,12 +194,14 @@
 }
 
 static int inject_sdp_data(struct tee_ctx *ctx,
-		    void *in, size_t offset, size_t len, void *shm_ref)
+		    void *in, size_t offset, size_t len, void *shm_ref, int ind)
 {
 	TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
 	TEEC_Result teerc;
 	TEEC_Operation op;
 	uint32_t err_origin;
+	unsigned cmd = ind ? TA_SDP_BASIC_CMD_INVOKE_INJECT :
+				TA_SDP_BASIC_CMD_INJECT;
 
 	memset(&op, 0, sizeof(op));
 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
@@ -213,8 +215,7 @@
 	op.params[1].memref.size = len;
 	op.params[1].memref.offset = offset;
 
-	teerc = TEEC_InvokeCommand(&ctx->sess, TA_SDP_BASIC_CMD_INJECT, &op,
-								&err_origin);
+	teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
 	if (teerc != TEEC_SUCCESS)
 		fprintf(stderr, "Error: invoke SDP test TA (inject) failed %x %d\n",
 			teerc, err_origin);
@@ -223,12 +224,14 @@
 }
 
 static int transform_sdp_data(struct tee_ctx *ctx,
-			size_t offset, size_t len, void *shm_ref)
+			size_t offset, size_t len, void *shm_ref, int ind)
 {
 	TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
 	TEEC_Result teerc;
 	TEEC_Operation op;
 	uint32_t err_origin;
+	unsigned cmd = ind ? TA_SDP_BASIC_CMD_INVOKE_TRANSFORM :
+				TA_SDP_BASIC_CMD_TRANSFORM;
 
 	memset(&op, 0, sizeof(op));
 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
@@ -237,8 +240,7 @@
 	op.params[0].memref.size = len;
 	op.params[0].memref.offset = offset;
 
-	teerc = TEEC_InvokeCommand(&ctx->sess, TA_SDP_BASIC_CMD_TRANSFORM, &op,
-								&err_origin);
+	teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
 	if (teerc != TEEC_SUCCESS)
 		fprintf(stderr, "Error: invoke SDP test TA (transform) failed %x %d\n",
 			teerc, err_origin);
@@ -247,12 +249,14 @@
 }
 
 static int dump_sdp_data(struct tee_ctx *ctx,
-		  void *out, size_t offset, size_t len, void *shm_ref)
+		  void *out, size_t offset, size_t len, void *shm_ref, int ind)
 {
 	TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
 	TEEC_Result teerc;
 	TEEC_Operation op;
 	uint32_t err_origin;
+	unsigned cmd = ind ? TA_SDP_BASIC_CMD_INVOKE_DUMP :
+				TA_SDP_BASIC_CMD_DUMP;
 
 	memset(&op, 0, sizeof(op));
 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
@@ -265,8 +269,7 @@
 	op.params[1].tmpref.buffer = out;
 	op.params[1].tmpref.size = len;
 
-	teerc = TEEC_InvokeCommand(&ctx->sess, TA_SDP_BASIC_CMD_DUMP, &op,
-								&err_origin);
+	teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
 	if (teerc != TEEC_SUCCESS)
 		fprintf(stderr, "Error: invoke SDP test TA (dump) failed %x %d\n",
 			teerc, err_origin);
@@ -357,6 +360,7 @@
 	int fd = -1;
 	size_t sdp_size = size;
 	size_t offset;
+	size_t loop_cnt;
 
 	if (!loop) {
 		fprintf(stderr, "Error: null loop value\n");
@@ -395,7 +399,7 @@
 	fd = -1;
 
 	/* invoke trusted application with secure buffer as memref parameter */
-	while (loop--) {
+	for (loop_cnt = loop; loop_cnt; loop_cnt--) {
 		/* get an buffer of random-like values */
 		if (get_random_bytes((char *)ref_buf, size))
 			goto out;
@@ -404,15 +408,15 @@
 		offset = (unsigned int)*ref_buf;
 
 		/* TA writes into SDP buffer */
-		if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref))
+		if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, 0))
 			goto out;
 
 		/* TA reads/writes into SDP buffer */
-		if (transform_sdp_data(ctx, offset, size, shm_ref))
+		if (transform_sdp_data(ctx, offset, size, shm_ref, 0))
 			goto out;
 
 		/* TA reads into SDP buffer */
-		if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref))
+		if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, 0))
 			goto out;
 
 		/* check dumped data are the expected ones */
@@ -421,6 +425,35 @@
 			goto out;
 		}
 	}
+
+	/* invoke trusted application with secure buffer as memref parameter */
+	for (loop_cnt = loop; loop_cnt; loop_cnt--) {
+		/* get an buffer of random-like values */
+		if (get_random_bytes((char *)ref_buf, size))
+			goto out;
+		memcpy(test_buf, ref_buf, size);
+		/* random offset [0 255] */
+		offset = (unsigned int)*ref_buf;
+
+		/* TA writes into SDP buffer */
+		if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, 1))
+			goto out;
+
+		/* TA reads/writes into SDP buffer */
+		if (transform_sdp_data(ctx, offset, size, shm_ref, 1))
+			goto out;
+
+		/* TA reads into SDP buffer */
+		if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, 1))
+			goto out;
+
+		/* check dumped data are the expected ones */
+		if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) {
+			fprintf(stderr, "check SDP data: %d errors\n", err);
+			goto out;
+		}
+	}
+
 	err = 0;
 	verbose("%s: successed\n", __func__);
 out:
diff --git a/ta/sdp_basic/include/ta_sdp_basic.h b/ta/sdp_basic/include/ta_sdp_basic.h
index 7a6999c..c8fa01e 100644
--- a/ta/sdp_basic/include/ta_sdp_basic.h
+++ b/ta/sdp_basic/include/ta_sdp_basic.h
@@ -31,8 +31,12 @@
 #define TA_SDP_BASIC_UUID { 0x12345678, 0x5b69, 0x11e4, \
 	{ 0x9d, 0xbb, 0x10, 0x1f, 0x74, 0xf0, 0x00, 0x99 } }
 
-#define TA_SDP_BASIC_CMD_INJECT		0
-#define TA_SDP_BASIC_CMD_TRANSFORM	1
-#define TA_SDP_BASIC_CMD_DUMP		2
+#define TA_SDP_BASIC_CMD_INJECT			0
+#define TA_SDP_BASIC_CMD_TRANSFORM		1
+#define TA_SDP_BASIC_CMD_DUMP			2
+
+#define TA_SDP_BASIC_CMD_INVOKE_INJECT		3
+#define TA_SDP_BASIC_CMD_INVOKE_TRANSFORM	4
+#define TA_SDP_BASIC_CMD_INVOKE_DUMP		5
 
 #endif /* TA_SDP_BASIC_H */
diff --git a/ta/sdp_basic/ta_sdp_basic.c b/ta/sdp_basic/ta_sdp_basic.c
index 5b1df2e..7df0d22 100644
--- a/ta/sdp_basic/ta_sdp_basic.c
+++ b/ta/sdp_basic/ta_sdp_basic.c
@@ -263,6 +263,38 @@
 	return rc;
 }
 
+static TEE_Result cmd_invoke(uint32_t nParamTypes,
+			     TEE_Param pParams[TEE_NUM_PARAMS],
+			     uint32_t nCommandID)
+{
+        const TEE_UUID uuid = TA_SDP_BASIC_UUID;
+        static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
+        uint32_t ret_orig;
+        TEE_Result res;
+
+	if (sess == TEE_HANDLE_NULL) {
+	        res = TEE_OpenTASession(&uuid, 0, 0, NULL, &sess, &ret_orig);
+		if (res != TEE_SUCCESS) {
+	                EMSG("SDP basic test TA: TEE_OpenTASession() FAILED \n");
+	                goto cleanup_return;
+		}
+
+        }
+
+        res = TEE_InvokeTACommand(sess, 0, nCommandID, nParamTypes, pParams, &ret_orig);
+        if (res != TEE_SUCCESS) {
+                EMSG("SDP basic test TA: TEE_OpenTASession() FAILED %x/%d\n",
+								res, ret_orig);
+        }
+
+cleanup_return:
+	if (res != TEE_SUCCESS) {
+		TEE_CloseTASession(sess);
+		sess = TEE_HANDLE_NULL;
+	}
+        return res;
+}
+
 TEE_Result TA_CreateEntryPoint(void)
 {
 	return TEE_SUCCESS;
@@ -300,6 +332,14 @@
 		return cmd_transform(nParamTypes, pParams);
 	case TA_SDP_BASIC_CMD_DUMP:
 		return cmd_dump(nParamTypes, pParams);
+
+	case TA_SDP_BASIC_CMD_INVOKE_INJECT:
+		return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_INJECT);
+	case TA_SDP_BASIC_CMD_INVOKE_TRANSFORM:
+		return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_TRANSFORM);
+	case TA_SDP_BASIC_CMD_INVOKE_DUMP:
+		return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_DUMP);
+
 	default:
 		return TEE_ERROR_BAD_PARAMETERS;
 	}