feat(lib/psa): add read_measurement API

This API is added for testing purposes. It makes possible to write test
cases that read measurements back after extending them, and compare
them to expected results.

Change-Id: Iec447d972fdd54a56ab933a065476e0f4d35a6fc
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index bdb79d5..a3ab441 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -74,4 +74,53 @@
 				     size_t measurement_value_size,
 				     bool lock_measurement);
 
+/**
+ * Retrieves a measurement from the requested slot.
+ *
+ * index			Slot number from which measurement is to be
+ *				retrieved.
+ * signer_id			Pointer to signer_id buffer.
+ * signer_id_size		Size of the signer_id buffer in bytes.
+ * signer_id_len		On success, number of bytes that make up
+ * 				signer_id.
+ * version			Pointer to version buffer.
+ * version_size			Size of the version buffer in bytes.
+ * version_len			On success, number of bytes that makeup the
+ * 				version.
+ * measurement_algo		Pointer to measurement_algo.
+ * sw_type			Pointer to sw_type buffer.
+ * sw_type_size			Size of the sw_type buffer in bytes.
+ * sw_type_len			On success, number of bytes that makeup the
+ * 				sw_type.
+ * measurement_value		Pointer to measurement_value buffer.
+ * measurement_value_size	Size of the measurement_value buffer in bytes.
+ * measurement_value_len	On success, number of bytes that make up the
+ * 				measurement_value.
+ * is_locked			Pointer to lock status of requested measurement
+ * 				slot.
+ *
+ * PSA_SUCCESS
+ *	- Success.
+ * PSA_ERROR_INVALID_ARGUMENT
+ *	- The size of at least one of the output buffers is incorrect or the
+ *	  requested slot index is invalid.
+ * PSA_ERROR_DOES_NOT_EXIST
+ *	- The requested slot is empty, does not contain a measurement.
+ */
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked);
+
 #endif /* PSA_MEASURED_BOOT_H */
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 6e9ff78..1ce3984 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -109,6 +109,61 @@
 			NULL, 0);
 }
 
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked)
+{
+	psa_status_t status;
+	struct measured_boot_read_iovec_in_t read_iov_in = {
+		.index = index,
+		.sw_type_size = sw_type_size,
+		.version_size = version_size,
+	};
+
+	struct measured_boot_read_iovec_out_t read_iov_out;
+
+	psa_invec in_vec[] = {
+		{.base = &read_iov_in,
+		 .len = sizeof(struct measured_boot_read_iovec_in_t)},
+	};
+
+	psa_outvec out_vec[] = {
+		{.base = &read_iov_out,
+		 .len = sizeof(struct measured_boot_read_iovec_out_t)},
+		{.base = signer_id, .len = signer_id_size},
+		{.base = measurement_value, .len = measurement_value_size}
+	};
+
+	status = psa_call(RSS_MEASURED_BOOT_HANDLE, RSS_MEASURED_BOOT_READ,
+					  in_vec, IOVEC_LEN(in_vec),
+					  out_vec, IOVEC_LEN(out_vec));
+
+	if (status == PSA_SUCCESS) {
+		*is_locked = read_iov_out.is_locked;
+		*measurement_algo = read_iov_out.measurement_algo;
+		*sw_type_len = read_iov_out.sw_type_len;
+		*version_len = read_iov_out.version_len;
+		memcpy(sw_type, read_iov_out.sw_type, read_iov_out.sw_type_len);
+		memcpy(version, read_iov_out.version, read_iov_out.version_len);
+		*signer_id_len = out_vec[1].len;
+		*measurement_value_len = out_vec[2].len;
+	}
+
+	return status;
+}
+
 #else /* !PLAT_RSS_NOT_SUPPORTED */
 
 psa_status_t
@@ -131,4 +186,24 @@
 
 	return PSA_SUCCESS;
 }
+
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked)
+{
+	return PSA_SUCCESS;
+}
+
 #endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
index 649c3f6..80d2c19 100644
--- a/lib/psa/measured_boot_private.h
+++ b/lib/psa/measured_boot_private.h
@@ -11,8 +11,24 @@
 #include <stdint.h>
 
 /* Measured boot message types that distinguish its services */
+#define RSS_MEASURED_BOOT_READ		1001U
 #define RSS_MEASURED_BOOT_EXTEND	1002U
 
+struct measured_boot_read_iovec_in_t {
+    uint8_t index;
+    uint8_t sw_type_size;
+    uint8_t version_size;
+};
+
+struct measured_boot_read_iovec_out_t {
+    uint8_t  is_locked;
+    uint32_t measurement_algo;
+    uint8_t  sw_type[SW_TYPE_MAX_SIZE];
+    uint8_t  sw_type_len;
+    uint8_t  version[VERSION_MAX_SIZE];
+    uint8_t  version_len;
+};
+
 struct measured_boot_extend_iovec_t {
 	uint8_t  index;
 	uint8_t  lock_measurement;