[PATCH 10/14] platform/x86/intel/ifs: Add metadata validation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The data portion of IFS test image file contains a meta-data
structure in addition to test data and hashes.

Introduce the layout of this meta_data structure and validate
the sanity of certain fields of the new-image before loading.

Tweak references to IFS test image chunks to reflect the updated
layout of the test image.

Reviewed-by: Tony Luck <tony.luck@xxxxxxxxx>
Signed-off-by: Jithu Joseph <jithu.joseph@xxxxxxxxx>
---
 drivers/platform/x86/intel/ifs/ifs.h  |  2 +
 drivers/platform/x86/intel/ifs/load.c | 54 +++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index be37512535f2..bb43fd65d2d2 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -196,6 +196,7 @@ union ifs_status {
  * @valid_chunks: number of chunks which could be validated.
  * @status: it holds simple status pass/fail/untested
  * @scan_details: opaque scan status code from h/w
+ * @cur_batch: suffix indicating the currently loaded test file
  */
 struct ifs_data {
 	int	integrity_cap_bit;
@@ -205,6 +206,7 @@ struct ifs_data {
 	int	valid_chunks;
 	int	status;
 	u64	scan_details;
+	int	cur_batch;
 };
 
 struct ifs_work {
diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c
index 3cb13a7aa74b..d300cf3ce5bd 100644
--- a/drivers/platform/x86/intel/ifs/load.c
+++ b/drivers/platform/x86/intel/ifs/load.c
@@ -8,8 +8,24 @@
 
 #include "ifs.h"
 
+struct meta_data {
+	unsigned int meta_type;		// metadata type
+	unsigned int meta_size;		// size of this entire struct including hdrs.
+	unsigned int test_type;		// IFS test type
+	unsigned int fusa_info;		// Fusa info
+	unsigned int total_images;	// Total number of images
+	unsigned int current_image;	// Current Image #
+	unsigned int total_chunks;	// Total number of chunks in this image
+	unsigned int starting_chunk;	// Starting chunk number in this image
+	unsigned int size_per_chunk;	// size of each chunk
+	unsigned int chunks_per_stride;	// number of chunks in a stride
+	unsigned int reserved[54];	// Align to 256 bytes for chunk alignment.
+};
+
 #define IFS_HEADER_SIZE	(sizeof(struct microcode_header_intel))
 #define IFS_HEADER_VER	2
+#define META_TYPE_IFS	1
+#define IFS_CHUNK_ALIGNMENT	256
 static  struct microcode_header_intel *ifs_header_ptr;	/* pointer to the ifs image header */
 static u64 ifs_hash_ptr;			/* Address of ifs metadata (hash) */
 static u64 ifs_test_image_ptr;			/* 256B aligned address of test pattern */
@@ -98,6 +114,41 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
 	complete(&ifs_done);
 }
 
+static int validate_ifs_metadata(struct device *dev)
+{
+	struct ifs_data *ifsd = ifs_get_data(dev);
+	struct meta_data *ifs_meta;
+	char test_file[64];
+	int ret = -EINVAL;
+
+	snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.scan",
+		 boot_cpu_data.x86, boot_cpu_data.x86_model,
+		 boot_cpu_data.x86_stepping, ifsd->cur_batch);
+
+	ifs_meta = (struct meta_data *)microcode_intel_find_meta_data(ifs_header_ptr,
+								      META_TYPE_IFS);
+	if (!ifs_meta) {
+		dev_err(dev, "IFS Metadata missing in file %s\n", test_file);
+		return ret;
+	}
+
+	ifs_test_image_ptr = (u64)ifs_meta + sizeof(struct meta_data);
+
+	/* Scan chunk start must be 256 byte aligned */
+	if (!IS_ALIGNED(ifs_test_image_ptr, IFS_CHUNK_ALIGNMENT)) {
+		dev_err(dev, "Scan pattern offset is not 256 byte aligned in %s\n", test_file);
+		return ret;
+	}
+
+	if (ifs_meta->current_image != ifsd->cur_batch) {
+		dev_warn(dev, "Suffix metadata is not matching with filename %s(0x%02x)\n",
+			 test_file, ifs_meta->current_image);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * IFS requires scan chunks authenticated per each socket in the platform.
  * Once the test chunk is authenticated, it is automatically copied to secured memory
@@ -114,6 +165,9 @@ static int scan_chunks_sanity_check(struct device *dev)
 	if (!package_authenticated)
 		return ret;
 
+	ret = validate_ifs_metadata(dev);
+	if (ret)
+		return ret;
 
 	ifsd->loading_error = false;
 	ifsd->loaded_version = ifs_header_ptr->rev;
-- 
2.25.1




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux