[coreboot-gerrit] Change in coreboot[master]: util/me_cleaner: Merge upstream, add HAP/AltMeDisable menu option

Jean Lucas (Code Review) gerrit at coreboot.org
Fri Sep 1 05:47:31 CEST 2017


Jean Lucas has uploaded this change for review. ( https://review.coreboot.org/21312


Change subject: util/me_cleaner: Merge upstream, add HAP/AltMeDisable menu option
......................................................................

util/me_cleaner: Merge upstream, add HAP/AltMeDisable menu option

Update me_cleaner to commit 72fff7a which includes the HAP/AltMeDisable
bit flipping function, and add a menu option to only flip this bit while
leaving the rest of the Intel ME/TXT firmware intact. Miscellaneous
language cleanup in the Kconfig as well.

Signed-off-by: Jean Lucas <jean at 4ray.co>

Change-Id: I0ebc5def2b9c01b2cc75f5b1541911a05f95c1ba
---
M src/southbridge/intel/common/firmware/Kconfig
M src/southbridge/intel/common/firmware/Makefile.inc
M util/me_cleaner/README.md
M util/me_cleaner/me_cleaner.py
4 files changed, 164 insertions(+), 107 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/12/21312/1

diff --git a/src/southbridge/intel/common/firmware/Kconfig b/src/southbridge/intel/common/firmware/Kconfig
index 6d33711..2aed690 100644
--- a/src/southbridge/intel/common/firmware/Kconfig
+++ b/src/southbridge/intel/common/firmware/Kconfig
@@ -45,7 +45,7 @@
 	depends on HAVE_IFD_BIN
 	help
 	  The Intel processor in the selected system requires a special firmware
-	  for an integrated controller.  This might be called the Management
+	  for an integrated controller. This might be called the Management
 	  Engine (ME), the Trusted Execution Engine (TXE) or something else
 	  depending on the chip. This firmware might or might not be available
 	  in coreboot's 3rdparty/blobs repository. If it is not and if you don't
@@ -68,51 +68,85 @@
 		SOC_INTEL_BAYTRAIL || SOC_INTEL_BRASWELL)
 	help
 	  Verify the integrity of the supplied Intel ME/TXE firmware before
-	  proceeding with the build, in order to prevent an accidental loading
-	  of a corrupted ME/TXE image.
+	  proceeding with the build, in order to prevent accidental loading of
+	  a corrupted ME/TXE image.
 
 config USE_ME_CLEANER
-	bool "Strip down the Intel ME/TXE firmware"
+	bool "Strip down Intel ME/TXE firmware and enable HAP/AltMeDisable bit in IFD"
 	depends on HAVE_ME_BIN && (NORTHBRIDGE_INTEL_SANDYBRIDGE || \
 		NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_HASWELL || \
 		SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || \
 		SOC_INTEL_BAYTRAIL || SOC_INTEL_BRASWELL)
 	help
-	  Use me_cleaner to remove all the non-fundamental code from the Intel
-	  ME/TXE firmware.
-	  The resulting Intel ME/TXE firmware will have only the code
-	  responsible for the very basic hardware initialization, leaving the
-	  ME/TXE subsystem essentially in a disabled state.
+	  Use me_cleaner to remove all non-fundamental code from the Intel ME/TXT
+	  firmware.
+
+	  The resulting Intel ME/TXE firmware will only have the code responsible
+	  for very basic hardware initialization, essentially leaving the ME/TXT
+	  subsystem in a disabled state.
 
 	  Don't flash a modified ME/TXE firmware and a new coreboot image at the
 	  same time, test them in two different steps.
 
-	  WARNING: this tool isn't based on any official Intel documentation but
-	           only on reverse engineering and trial & error.
+	  WARNING: This tool isn't based on any official Intel documentation, but
+	           on reverse engineering and trial & error.
 
 	  See the project's page
-	   https://github.com/corna/me_cleaner
+	    https://github.com/corna/me_cleaner
 	  or the wiki
-	   https://github.com/corna/me_cleaner/wiki/How-to-apply-me_cleaner
-	   https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F
-	   https://github.com/corna/me_cleaner/wiki/me_cleaner-status
-	  for more info about this tool
+	    https://github.com/corna/me_cleaner/wiki/How-to-apply-me_cleaner
+	    https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F
+	    https://github.com/corna/me_cleaner/wiki/me_cleaner-status
+	  for more info about this tool.
 
 	  If unsure, say N.
 
 comment "Please test the modified ME/TXE firmware and coreboot in two steps"
 	depends on USE_ME_CLEANER
 
+config USE_ME_CLEANER_BIT_FLIP
+	bool "Only enable HAP/AltMeDisable bit in IFD"
+	depends on HAVE_ME_BIN && (NORTHBRIDGE_INTEL_SANDYBRIDGE || \
+		NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_HASWELL || \
+		SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || \
+		SOC_INTEL_BAYTRAIL || SOC_INTEL_BRASWELL) && !USE_ME_CLEANER
+	help
+	  Use me_cleaner to only enable the HAP (ME >= 11) or AltMeDisable
+	  (ME < 11) bit in the flash descriptor, which should completely disable
+	  the Intel ME after it initializes.
+
+	  Enabling this option will leave the Intel ME/TXT firmware code intact.
+
+	  Don't flash a modified image and a new coreboot image at the same time,
+	  test them in two different steps.
+
+	  WARNING: This tool isn't based on any official Intel documentation, but
+	           on reverse engineering and trial & error.
+
+	  See the project's page
+	    https://github.com/corna/me_cleaner
+	  or the wiki
+	    https://github.com/corna/me_cleaner/wiki/How-to-apply-me_cleaner
+	    https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F
+	    https://github.com/corna/me_cleaner/wiki/me_cleaner-status
+	  for more info about this tool.
+
+	  If unsure, say N.
+
+comment "Please test the modified image and coreboot in two steps"
+	depends on USE_ME_CLEANER_BIT_FLIP
+
 config HAVE_GBE_BIN
-	bool "Add gigabit ethernet firmware"
+	bool "Add Gigabit Ethernet firmware"
 	depends on HAVE_IFD_BIN
 	help
-	  The integrated gigabit ethernet controller needs a firmware file.
+	  The integrated Gigabit Ethernet controller needs a firmware file.
+
 	  Select this if you are going to use the PCH integrated controller
 	  and have the firmware.
 
 config GBE_BIN_PATH
-	string "Path to gigabit ethernet firmware"
+	string "Path to Gigabit Ethernet firmware"
 	depends on HAVE_GBE_BIN
 	default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/gbe.bin"
 
@@ -177,8 +211,8 @@
 	default ""
 	help
 	  The Gigabit Ethernet ROM region is used when an Intel NIC is built into
-	  the Southbridge/SOC and the platform uses this device instead of an external
-	  PCIe NIC.  It will be located between the ME/TXE and the BIOS region.
+	  the southbridge/SoC and the platform uses this device instead of an external
+	  PCIe NIC. It will be located between the ME/TXE and the BIOS region.
 
 	  Leave this empty if you're unsure.
 
diff --git a/src/southbridge/intel/common/firmware/Makefile.inc b/src/southbridge/intel/common/firmware/Makefile.inc
index d6e6296..a20acce 100644
--- a/src/southbridge/intel/common/firmware/Makefile.inc
+++ b/src/southbridge/intel/common/firmware/Makefile.inc
@@ -66,6 +66,11 @@
 	util/me_cleaner/me_cleaner.py $(obj)/coreboot.pre > \
 		$(obj)/me_cleaner.log
 endif
+ifeq ($(CONFIG_USE_ME_CLEANER_BIT_FLIP),y)
+	printf "    ME_CLEANER coreboot.pre\n"
+	util/me_cleaner/me_cleaner.py -s $(obj)/coreboot.pre > \
+		$(obj)/me_cleaner.log
+endif
 ifeq ($(CONFIG_HAVE_GBE_BIN),y)
 	printf "    IFDTOOL    gbe.bin -> coreboot.pre\n"
 	$(objutil)/ifdtool/ifdtool \
diff --git a/util/me_cleaner/README.md b/util/me_cleaner/README.md
index 72c1598..a8bee6d 100644
--- a/util/me_cleaner/README.md
+++ b/util/me_cleaner/README.md
@@ -1,4 +1,4 @@
-# me_cleaner
+# me_cleaner [![Donation](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=B5HCXCLZVCVZ8)
 
 Intel ME is a coprocessor integrated in all post-2006 Intel boards, for which
 this [Libreboot page](https://libreboot.org/faq.html#intelme) has an excellent
diff --git a/util/me_cleaner/me_cleaner.py b/util/me_cleaner/me_cleaner.py
index e8a89cc..a415f2b 100755
--- a/util/me_cleaner/me_cleaner.py
+++ b/util/me_cleaner/me_cleaner.py
@@ -74,7 +74,7 @@
            offset_to + size <= self.region_end:
             for i in range(0, size, 4096):
                 self.f.seek(offset_from + i, 0)
-                block = self.f.read(4096 if size - i >= 4096 else size - i)
+                block = self.f.read(min(size - i, 4096))
                 self.f.seek(offset_from + i, 0)
                 self.f.write(fill * len(block))
                 self.f.seek(offset_to + i, 0)
@@ -86,7 +86,7 @@
         self.f.seek(self.region_start)
         copyf = open(filename, "w+b")
         for i in range(0, size, 4096):
-            copyf.write(self.f.read(4096 if size - i >= 4096 else size - i))
+            copyf.write(self.f.read(min(size - i, 4096)))
         return copyf
 
 
@@ -437,9 +437,13 @@
                                      "as possible from Intel ME/TXE firmware "
                                      "images")
     parser.add_argument("file", help="ME/TXE image or full dump")
-    parser.add_argument("-O", "--output", help="save the modified image in a "
-                        "separate file, instead of modifying the original "
-                        "file")
+    parser.add_argument("-O", "--output", metavar='output_file', help="save "
+                        "the modified image in a separate file, instead of "
+                        "modifying the original file")
+    parser.add_argument("-s", "--soft-disable", help="instead of modifying "
+                        "the Intel ME firmware, just disable it by setting "
+                        "the MeAltDisable bit or the HAP bit (requires a full "
+                        "dump)", action="store_true")
     parser.add_argument("-r", "--relocate", help="relocate the FTPR partition "
                         "to the top of the ME region to save even more space",
                         action="store_true")
@@ -455,21 +459,23 @@
     parser.add_argument("-c", "--check", help="verify the integrity of the "
                         "fundamental parts of the firmware and exit",
                         action="store_true")
-    parser.add_argument("-D", "--extract-descriptor", help="extract the "
-                        "flash descriptor from a full dump; when used with "
+    parser.add_argument("-D", "--extract-descriptor",
+                        metavar='output_descriptor', help="extract the flash "
+                        "descriptor from a full dump; when used with "
                         "--truncate save a descriptor with adjusted regions "
                         "start and end")
-    parser.add_argument("-M", "--extract-me", help="extract the ME firmware "
-                        "from a full dump; when used with --truncate save a "
-                        "truncated ME/TXE image")
+    parser.add_argument("-M", "--extract-me", metavar='output_me_image',
+                        help="extract the ME firmware from a full dump; when "
+                        "used with --truncate save a truncated ME/TXE image")
 
     args = parser.parse_args()
 
-    if args.check:
-        if args.relocate:
-            sys.exit("-c and -r can't be used together")
-        elif args.truncate:
-            sys.exit("-c and -t can't be used together")
+    if args.check and (args.soft_disable or args.relocate or \
+       args.descriptor or args.truncate or args.output):
+        sys.exit("-c can't be used with -s, -r, -d, -t or -O")
+
+    if args.soft_disable and (args.relocate or args.truncate):
+        sys.exit("-s can't be used with -r or -t")
 
     f = open(args.file, "rb" if args.check or args.output else "r+b")
     f.seek(0x10)
@@ -478,14 +484,9 @@
     if magic == b"$FPT":
         print("ME/TXE image detected")
 
-        if args.descriptor:
-            sys.exit("-d requires a full dump")
-
-        if args.extract_descriptor:
-            sys.exit("-D requires a full dump")
-
-        if args.extract_me:
-            sys.exit("-M requires a full dump")
+        if args.descriptor or args.extract_descriptor or args.extract_me or \
+           args.soft_disable:
+            sys.exit("-d, -D, -M and -s require a full dump")
 
         me_start = 0
         f.seek(0, 2)
@@ -501,6 +502,7 @@
         flmap0, flmap1 = unpack("<II", f.read(8))
         frba = flmap0 >> 12 & 0xff0
         fmba = (flmap1 & 0xff) << 4
+        fpsba = flmap1 >> 12 & 0xff0
 
         f.seek(frba)
         flreg = unpack("<III", f.read(12))
@@ -582,74 +584,90 @@
     print("ME/TXE firmware version {}"
           .format('.'.join(str(i) for i in version)))
 
+    if not args.check and args.output:
+        f.close()
+        shutil.copy(args.file, args.output)
+        f = open(args.output, "r+b")
+
+    mef = RegionFile(f, me_start, me_end)
+
+    if me_start > 0:
+        fdf = RegionFile(f, fd_start, fd_end)
+
     if not args.check:
-        if args.output:
-            f.close()
-            shutil.copy(args.file, args.output)
-            f = open(args.output, "r+b")
+        if not args.soft_disable:
+            print("Removing extra partitions...")
+            mef.fill_range(me_start + 0x30, ftpr_offset, b"\xff")
+            mef.fill_range(ftpr_offset + ftpr_lenght, me_end, b"\xff")
 
-        mef = RegionFile(f, me_start, me_end)
+            print("Removing extra partition entries in FPT...")
+            mef.write_to(me_start + 0x30, ftpr_header)
+            mef.write_to(me_start + 0x14, pack("<I", 1))
 
-        if args.descriptor or args.extract_descriptor:
-            fdf = RegionFile(f, fd_start, fd_end)
+            print("Removing EFFS presence flag...")
+            mef.seek(me_start + 0x24)
+            flags = unpack("<I", mef.read(4))[0]
+            flags &= ~(0x00000001)
+            mef.write_to(me_start + 0x24, pack("<I", flags))
 
-        print("Removing extra partitions...")
-        mef.fill_range(me_start + 0x30, ftpr_offset, b"\xff")
-        mef.fill_range(ftpr_offset + ftpr_lenght, me_end, b"\xff")
+            if me11:
+                mef.seek(me_start + 0x10)
+                header = bytearray(mef.read(0x20))
+                header[0x0b] = 0x00
+            else:
+                mef.seek(me_start)
+                header = bytearray(mef.read(0x30))
+                header[0x1b] = 0x00
+            checksum = (0x100 - sum(header) & 0xff) & 0xff
 
-        print("Removing extra partition entries in FPT...")
-        mef.write_to(me_start + 0x30, ftpr_header)
-        mef.write_to(me_start + 0x14, pack("<I", 1))
+            print("Correcting checksum (0x{:02x})...".format(checksum))
+            # The checksum is just the two's complement of the sum of the first
+            # 0x30 bytes in ME < 11 or bytes 0x10:0x30 in ME >= 11 (except for
+            # 0x1b, the checksum itself). In other words, the sum of those
+            # bytes must be always 0x00.
+            mef.write_to(me_start + 0x1b, pack("B", checksum))
 
-        print("Removing EFFS presence flag...")
-        mef.seek(me_start + 0x24)
-        flags = unpack("<I", mef.read(4))[0]
-        flags &= ~(0x00000001)
-        mef.write_to(me_start + 0x24, pack("<I", flags))
+            print("Reading FTPR modules list...")
+            if me11:
+                end_addr, ftpr_offset = \
+                    check_and_remove_modules_me11(mef, me_start, me_end,
+                                                  ftpr_offset, ftpr_lenght,
+                                                  min_ftpr_offset,
+                                                  args.relocate,
+                                                  args.keep_modules)
+            else:
+                end_addr, ftpr_offset = \
+                    check_and_remove_modules(mef, me_start, me_end, ftpr_offset,
+                                             min_ftpr_offset, args.relocate,
+                                             args.keep_modules)
+
+            if end_addr > 0:
+                end_addr = (end_addr // 0x1000 + 1) * 0x1000
+                end_addr += spared_blocks * 0x1000
+
+                print("The ME minimum size should be {0} bytes "
+                      "({0:#x} bytes)".format(end_addr - me_start))
+
+                if me_start > 0:
+                    print("The ME region can be reduced up to:\n"
+                          " {:08x}:{:08x} me".format(me_start, end_addr - 1))
+                elif args.truncate:
+                    print("Truncating file at {:#x}...".format(end_addr))
+                    f.truncate(end_addr)
 
         if me11:
-            mef.seek(me_start + 0x10)
-            header = bytearray(mef.read(0x20))
-            header[0x0b] = 0x00
+            print("Setting the HAP bit in PCHSTRP0 to disable Intel ME...")
+            fdf.seek(fpsba)
+            pchstrp0 = unpack("<I", fdf.read(4))[0]
+            pchstrp0 |= (1 << 16)
+            fdf.write_to(fpsba, pack("<I", pchstrp0))
         else:
-            mef.seek(me_start)
-            header = bytearray(mef.read(0x30))
-            header[0x1b] = 0x00
-        checksum = (0x100 - sum(header) & 0xff) & 0xff
-
-        print("Correcting checksum (0x{:02x})...".format(checksum))
-        # The checksum is just the two's complement of the sum of the first
-        # 0x30 bytes in ME < 11 or bytes 0x10:0x30 in ME >= 11 (except for
-        # 0x1b, the checksum itself). In other words, the sum of those bytes
-        # must be always 0x00.
-        mef.write_to(me_start + 0x1b, pack("B", checksum))
-
-        print("Reading FTPR modules list...")
-        if me11:
-            end_addr, ftpr_offset = \
-                check_and_remove_modules_me11(mef, me_start, me_end,
-                                              ftpr_offset, ftpr_lenght,
-                                              min_ftpr_offset, args.relocate,
-                                              args.keep_modules)
-        else:
-            end_addr, ftpr_offset = \
-                check_and_remove_modules(mef, me_start, me_end, ftpr_offset,
-                                         min_ftpr_offset, args.relocate,
-                                         args.keep_modules)
-
-        if end_addr > 0:
-            end_addr = (end_addr // 0x1000 + 1) * 0x1000
-            end_addr += spared_blocks * 0x1000
-
-            print("The ME minimum size should be {0} bytes "
-                  "({0:#x} bytes)".format(end_addr - me_start))
-
-            if me_start > 0:
-                print("The ME region can be reduced up to:\n"
-                      " {:08x}:{:08x} me".format(me_start, end_addr - 1))
-            elif args.truncate:
-                print("Truncating file at {:#x}...".format(end_addr))
-                f.truncate(end_addr)
+            print("Setting the AltMeDisable bit in PCHSTRP10 to disable Intel "
+                  "ME...")
+            fdf.seek(fpsba + 0x28)
+            pchstrp10 = unpack("<I", fdf.read(4))[0]
+            pchstrp10 |= (1 << 7)
+            fdf.write_to(fpsba + 0x28, pack("<I", pchstrp10))
 
     if args.descriptor:
         print("Removing ME/TXE R/W access to the other flash regions...")
@@ -678,12 +696,12 @@
                       "isn't equal to the end address of the ME\n region: if "
                       "you want to recover the space from the ME region you "
                       "have to\n manually modify the descriptor.\n")
-
-            fdf_copy.close()
         else:
             print("Extracting the descriptor to \"{}\"..."
                   .format(args.extract_descriptor))
-            fdf.save(args.extract_descriptor, fd_end - fd_start).close()
+            fdf_copy = fdf.save(args.extract_descriptor, fd_end - fd_start)
+
+        fdf_copy.close()
 
     if args.extract_me:
         if args.truncate:

-- 
To view, visit https://review.coreboot.org/21312
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0ebc5def2b9c01b2cc75f5b1541911a05f95c1ba
Gerrit-Change-Number: 21312
Gerrit-PatchSet: 1
Gerrit-Owner: Jean Lucas <jean at 4ray.co>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170901/54214fa4/attachment-0001.html>


More information about the coreboot-gerrit mailing list