feat(app/device_assignment): add helper dev_assign_hash_extend

Add wrapper routine to compute incremental hash for a data using
mbedtls PSA hash helpers.

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ie1231d0ba91c80b92d089181999895be58fa60ad
diff --git a/app/device_assignment/el0_app/CMakeLists.txt b/app/device_assignment/el0_app/CMakeLists.txt
index 3195151..9bef0fa 100644
--- a/app/device_assignment/el0_app/CMakeLists.txt
+++ b/app/device_assignment/el0_app/CMakeLists.txt
@@ -89,7 +89,8 @@
 target_sources(rmm-app-dev-assign-elf
     PRIVATE
         "src/dev_assign_el0_app.c"
-        "src/dev_assign_cmds.c")
+        "src/dev_assign_cmds.c"
+        "src/dev_assign_helper.c")
 
 if (RMM_ARCH STREQUAL fake_host)
     target_sources(rmm-app-dev-assign-elf
diff --git a/app/device_assignment/el0_app/src/dev_assign_helper.c b/app/device_assignment/el0_app/src/dev_assign_helper.c
new file mode 100644
index 0000000..15f29f1
--- /dev/null
+++ b/app/device_assignment/el0_app/src/dev_assign_helper.c
@@ -0,0 +1,77 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <dev_assign_helper.h>
+#include <stdbool.h>
+/*
+ * Compute hash using PSA helpers. This helper is used by DA ABIs to
+ * incrementally compute hash as device response is processed by RMM.
+ *
+ * TODO: make arguments generic so that this function is independent of crypto
+ * library used. Currently it is PSA Crypto.
+ *
+ * In:
+ *	algo		- The hash algorithm to compute
+ *	op		- Hash state data structure
+ *	op_flags	- Hash operations to perform SETUP|UPDATE|FINISH
+ *	src		- Source buffer containing the message to hash.
+ *	src_len		- Length of 'src' buffer
+ *	hash_size	- Size of the hash buffer in bytes.
+ * Out:
+ *	op		- Holds the updated hash state
+ *	hash		- Buffer where the hash is to be written.
+ *	hash_length	- Hash length set when op_flags has FINISH
+ */
+int dev_assign_hash_extend(psa_algorithm_t algo, psa_hash_operation_t *op,
+			uint8_t op_flags, const uint8_t *src,
+			size_t src_length, uint8_t *hash, size_t hash_size,
+			size_t *hash_length)
+{
+	psa_status_t psa_rc;
+	int rc = -1;
+
+	/* Make sure that only valid flags are passed */
+	if ((op_flags & (~HASH_OP_VALID_FLAGS)) != 0U) {
+		ERROR("%s called with invalid flag(s) %x\n", __func__, op_flags);
+		goto out_err;
+	}
+
+	/* Make sure that no invalid flag combination is passed */
+	if (op_flags == (HASH_OP_FLAG_SETUP | HASH_OP_FLAG_FINISH)) {
+		ERROR("%s called with incompatible flag(s) %x\n", __func__, op_flags);
+		goto out_err;
+	}
+
+	if ((op_flags & HASH_OP_FLAG_SETUP) != 0U) {
+		psa_rc = psa_hash_setup(op, algo);
+		if (psa_rc != PSA_SUCCESS) {
+			ERROR("%s: psa_hash_setup failed: %d\n", __func__, psa_rc);
+			goto out_psa_err;
+		}
+	}
+	if ((op_flags & HASH_OP_FLAG_UPDATE) != 0U) {
+		psa_rc = psa_hash_update(op, src, src_length);
+		if (psa_rc != PSA_SUCCESS) {
+			ERROR("%s: psa_hash_update failed: %d\n", __func__, psa_rc);
+			goto out_psa_err;
+		}
+	}
+	if ((op_flags & HASH_OP_FLAG_FINISH) != 0U) {
+		psa_rc = psa_hash_finish(op, hash, hash_size, hash_length);
+		if (psa_rc != PSA_SUCCESS) {
+			ERROR("%s: psa_hash_finish failed: %d\n", __func__, psa_rc);
+			goto out_psa_err;
+		}
+	}
+	rc = 0;
+out_psa_err:
+	if (rc == -1) {
+		(void)psa_hash_abort(op);
+	}
+out_err:
+	return rc;
+}
diff --git a/app/device_assignment/el0_app/src/dev_assign_helper.h b/app/device_assignment/el0_app/src/dev_assign_helper.h
new file mode 100644
index 0000000..0adeaa6
--- /dev/null
+++ b/app/device_assignment/el0_app/src/dev_assign_helper.h
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#ifndef DEV_ASSIGN_HELPER_H
+#define DEV_ASSIGN_HELPER_H
+
+#include <psa/crypto.h>
+
+#define HASH_OP_FLAG_SETUP		0x1U
+#define HASH_OP_FLAG_UPDATE		0x2U
+#define HASH_OP_FLAG_FINISH		0x4U
+
+#define HASH_OP_VALID_FLAGS		(HASH_OP_FLAG_SETUP	| \
+					 HASH_OP_FLAG_UPDATE	| \
+					 HASH_OP_FLAG_FINISH)
+
+
+/*
+ * Extend a hash with algorithm 'hash_algo' and with hash 'op'
+ *
+ *	algo		- The hash algorithm to compute
+ *	op		- Hash state data structure
+ *	op_flags	- Hash operations to perform SETUP|UPDATE|FINISH
+ *	src		- Source buffer containing the message to hash.
+ *	src_len		- Length of 'src' buffer
+ *	hash_size	- Size of the hash buffer in bytes.
+ */
+int dev_assign_hash_extend(psa_algorithm_t algo, psa_hash_operation_t *op,
+			uint8_t op_flags, const uint8_t *src,
+			size_t src_length, uint8_t *hash, size_t hash_size,
+			size_t *hash_length);
+
+#endif /* DEV_ASSIGN_HELPER_H */