cros_bundle_firmware: Do not fail when using extracted BL2

To generate a flasher write_firmware takes the image apart, and then
modifies SPL to make it use the changed u-boot blob size. At this
point SPL blob is retrieved from the binary image, so its size is
likely to be larger than the actual blob. This poses a problem for
image verification, which expects the the value in the header size
field to exactly match the blob size.

To address this - allow blob size to exceed the size value in the blob
header.

BUG=chrome-os-partner:18447
TEST=manual

   . with u-boot/ebuild modifications enabling variable size SPL ran
     the following commands

   $ emerge-peach_pit chromeos-bootimage chromeos-u-boot exynos-pre-boot
   $ sudo cros_write_firmware -b peach -w sd:. -M exynos --board peach \
      -i /build/peach_pit/firmware/image-peach_pit.bin \
      --dt /tmp/u-peach/dts/exynos5420-peach_pit.dtb -F spi \
      -U /build/peach_pit/firmware/u-boot.bin

     observed the generated SD card flash the onboard SPI flash on
     peach_pit, and then observed the peach_pit boot from SPI flash
     after reset

   . unittests still pass

   $ FEATURES=test sudo -E emerge cros-devutils

Change-Id: Ie32343409d1c2d2cf0ba8e78dd078ee278b4995f
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/58226
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/host/lib/exynos.py b/host/lib/exynos.py
index de769aa..d3fc032 100644
--- a/host/lib/exynos.py
+++ b/host/lib/exynos.py
@@ -265,7 +265,7 @@
     return data[:checksum_offset]+ struct.pack(
       '<L', checksum) + data[checksum_offset + 4:]
 
-  def _VerifyBl2(self, data):
+  def _VerifyBl2(self, data, loose_check):
     """Verify BL2 integrity.
 
     Fixed size and variable size SPL have different formats. Determine format,
@@ -274,7 +274,8 @@
 
     Args:
       data: The BL2 data to update.
-
+      loose_check: a Boolean, if true - the variable size SPL blob could be
+                   larger than the size value in the header
     Raises:
       CmdError if SPL blob is of unrecognizable format.
     """
@@ -282,8 +283,8 @@
     # Variable size format is more sophisticated, check it first.
     try:
       size = struct.unpack('<I', data[:4])[0]
-      if size == len(data):
-        check_sum = sum(ord(x) for x in data[8:])
+      if size == len(data) or (loose_check and (size < len(data))):
+        check_sum = sum(ord(x) for x in data[8:size])
         # Compare with header checksum
         if check_sum == struct.unpack('<I', data[4:8])[0]:
           # this is a variable size SPL
@@ -303,7 +304,7 @@
     raise CmdError("Unrecognizable bl2 format")
 
 
-  def Configure(self, fdt, spl_load_size, orig_bl2, name=''):
+  def Configure(self, fdt, spl_load_size, orig_bl2, name='', loose_check=False):
     """Configure an Exynos BL2 binary for our needs.
 
     We create a new modified BL2 and return its file name.
@@ -312,13 +313,17 @@
       fdt: Device tree containing the parameter values.
       spl_load_size: Size of U-Boot image that SPL must load
       orig_bl2: Filename of original BL2 file to modify.
+      name: a string, suffix to add to the generated file name
+      loose_check: if True - allow var size SPL blob to be larger, then the
+                   size value in the header. This is necessary for cases when
+                   SPL is pulled out of an image (and is padded).
 
     Raises:
       CmdError if machine parameter block could not be found.
     """
     self._out.Info('Configuring BL2')
     data = self._tools.ReadFile(orig_bl2)
-    self._VerifyBl2(data)
+    self._VerifyBl2(data, loose_check)
 
     # Locate the parameter block
     marker = struct.pack('<L', 0xdeadbeef)
diff --git a/host/lib/write_firmware.py b/host/lib/write_firmware.py
index c486423..4363606 100644
--- a/host/lib/write_firmware.py
+++ b/host/lib/write_firmware.py
@@ -680,7 +680,8 @@
       spl_load_size = os.stat(raw_image).st_size
 
       bl2_handler = ExynosBl2(self._tools, self._out)
-      bl2_file = bl2_handler.Configure(self._fdt, spl_load_size, bl2, 'flasher')
+      bl2_file = bl2_handler.Configure(self._fdt, spl_load_size,
+                                       bl2, 'flasher', False)
       data = self._tools.ReadFile(bl1) + self._tools.ReadFile(bl2_file)
 
       # Pad BL2 out to the required size.