Add firmware vblock sha and method to modify firmware

To backup firmware, add firmware vblock sha (firmware body sha is already
exist) and associated method to get these sha. Some methods to set and get
firmware body and vblock are needed.

BUG=chromium-os:33641
TEST=After merging faftsequence.py, use backup_firmware() and restore_firmware()

Change-Id: I8c96acba8872ab191fec8a9f84750e3761f3dc78
Reviewed-on: https://gerrit.chromium.org/gerrit/32503
Reviewed-by: Tom Wai-Hong Tam <waihong@chromium.org>
Commit-Ready: Tom Wai-Hong Tam <waihong@chromium.org>
Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
diff --git a/flashrom_handler.py b/flashrom_handler.py
index 9a29302..ec1f640 100755
--- a/flashrom_handler.py
+++ b/flashrom_handler.py
@@ -28,6 +28,7 @@
         self._version = -1  # Is not set on construction.
         self._flags = 0  # Is not set on construction.
         self._sha = None  # Is not set on construction.
+        self._sig_sha = None # Is not set on construction.
         self._datakey_version = -1 # Is not set on construction.
         self._kernel_subkey_version = -1 # Is not set on construction.
 
@@ -49,6 +50,9 @@
     def get_sha(self):
         return self._sha
 
+    def get_sig_sha(self):
+        return self._sig_sha
+
     def get_datakey_version(self):
         return self._datakey_version
 
@@ -64,6 +68,9 @@
     def set_sha(self, sha):
         self._sha = sha
 
+    def set_sig_sha(self, sha):
+        self._sig_sha = sha
+
     def set_datakey_version(self, version):
         self._datakey_version = version
 
@@ -169,6 +176,10 @@
             section.set_kernel_subkey_version(
                 self.chros_if.retrieve_kernel_subkey_version(vb_section))
 
+            s = hashlib.sha1()
+            s.update(self.fum.get_section(self.image, section.get_sig_name()))
+            section.set_sig_sha(s.hexdigest())
+
         if not self.pub_key_file:
             self._retrieve_pub_key()
 
@@ -382,6 +393,10 @@
             raise FlashromHandlerError(e)
         return gbb_flags
 
+    def get_section_sig_sha(self, section):
+        '''Retrieve SHA1 hash of a firmware vblock section'''
+        return self.fv_sections[section].get_sig_sha()
+
     def get_section_sha(self, section):
         '''Retrieve SHA1 hash of a firmware body section'''
         return self.fv_sections[section].get_sha()
@@ -408,6 +423,12 @@
         blob = self.fum.get_section(self.image, subsection_name)
         return blob
 
+    def get_section_sig(self, section):
+        """Retrieve vblock of a firmware section"""
+        subsection_name = self.fv_sections[section].get_sig_name()
+        blob = self.fum.get_section(self.image, subsection_name)
+        return blob
+
     def _find_ecbin_offset(self, blob):
         '''Return the offset of EC binary from the given firmware blob'''
         # The RW firmware is concatenated from u-boot, dtb, and ecbin.
@@ -438,11 +459,26 @@
         ecbin = blob[ecbin_offset :].rstrip(pad)
         return ecbin
 
-    def set_section_body(self, section, blob):
+    def set_section_body(self, section, blob, write_through=False):
         '''Put the supplied blob to the body of the firmware section'''
         subsection_name = self.fv_sections[section].get_body_name()
         self.image = self.fum.put_section(self.image, subsection_name, blob)
 
+        if write_through:
+            self.dump_partial(subsection_name,
+                              self.chros_if.state_dir_file(subsection_name))
+            self.fum.write_partial(self.image, (subsection_name, ))
+
+    def set_section_sig(self, section, blob, write_through=False):
+        """Put the supplied blob to the vblock of the firmware section"""
+        subsection_name = self.fv_sections[section].get_sig_name()
+        self.image = self.fum.put_section(self.image, subsection_name, blob)
+
+        if write_through:
+            self.dump_partial(subsection_name,
+                              self.chros_if.state_dir_file(subsection_name))
+            self.fum.write_partial(self.image, (subsection_name, ))
+
     def set_section_ecbin(self, section, ecbin, write_through=False):
         '''Put the supplied EC binary to the firwmare section.