#!/usr/bin/python2
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A module to support automated testing of ChromeOS firmware.

Utilizes services provided by saft_flashrom_util.py read/write the
flashrom chip and to parse the flash rom image.

See docstring for FlashromHandler class below.
"""

import hashlib
import os
import struct
import tempfile

import six

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chip_utils
from autotest_lib.client.cros.faft.utils import saft_flashrom_util


class FvSection(object):
    """An object to hold information about a firmware section.

    This includes file names for the signature header and the body, and the
    version number.
    """

    def __init__(self, sig_name, body_name, fwid_name=None):
        """
        @param sig_name: name of signature section in fmap
        @param body_name: name of body section in fmap
        @param fwid_name: name of fwid section in fmap
        @type sig_name: str | None
        @type body_name: str | None
        @type fwid_name: str | None
        """
        self._sig_name = sig_name
        self._body_name = body_name
        self._fwid_name = fwid_name
        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.

    def names(self):
        """Return the desired file names for the signature, body, and fwid."""
        return (self._sig_name, self._body_name, self._fwid_name)

    def get_sig_name(self):
        return self._sig_name

    def get_body_name(self):
        return self._body_name

    def get_fwid_name(self):
        return self._fwid_name

    def get_version(self):
        return self._version

    def get_flags(self):
        return self._flags

    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

    def get_kernel_subkey_version(self):
        return self._kernel_subkey_version

    def set_version(self, version):
        self._version = version

    def set_flags(self, flags):
        self._flags = flags

    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

    def set_kernel_subkey_version(self, version):
        self._kernel_subkey_version = version


class FlashromHandlerError(Exception):
    """An object to represent Flashrom errors"""
    pass


class _FlashromErrorWrapper(object):
    """Wrap calls to flashrom, giving cleaner error messages.

    @param description: The start of the failure message ("Failed to <verb>...")
    """
    def __init__(self, description):
        self.description = description

    def __enter__(self):
        """Enter the context"""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """Exit the context, converting CmdError into summarized errors.

        @raise FlashromHandlerError: if the wrapped code raises CmdError.
        """
        if not isinstance(exc_val, error.CmdError):
            del exc_tb
            return
        result = exc_val.result_obj
        lines = [result.command]
        for line in result.stdout.splitlines():
            # grab anything mentioning 'status', but avoid very long lines
            if len(line) < 80 and 'status' in line.lower():
                lines.append(line)
        lines.extend(result.stderr.splitlines())

        err_msg = '%s.' % self.description.rstrip('.')
        err_msg += '  [summarized output, check rpc server log for full]:'
        err_msg += '  [rc=%s] ' % result.exit_status
        err_msg += ' || '.join(lines)
        err = FlashromHandlerError(err_msg)
        try:
            six.reraise(type(err), err, exc_tb)
        finally:
            del exc_tb


class FlashromHandler(object):
    """An object to provide logical services for automated flashrom testing."""

    DELTA = 1  # value to add to a byte to corrupt a section contents

    # File in the state directory to store public root key.
    PUB_KEY_FILE_NAME = 'root.pubkey'
    FW_KEYBLOCK_FILE_NAME = 'firmware.keyblock'
    FW_PRIV_DATA_KEY_FILE_NAME = 'firmware_data_key.vbprivk'
    KERNEL_SUBKEY_FILE_NAME = 'kernel_subkey.vbpubk'
    EC_EFS_KEY_FILE_NAME = 'key_ec_efs.vbprik2'
    FWID_MOD_DELIMITER = '~'

    def __init__(
            self,
            os_if,
            pub_key_file=None,
            dev_key_path='./',
            target='bios',
            subdir=None
    ):
        """The flashrom handler is not fully initialized upon creation

        @param os_if: an object providing interface to OS services
        @param pub_key_file: the name of the file contaning a public key to
                             use for verifying both existing and new firmware.
        @param dev_key_path: path to directory containing *.vpubk and *.vbprivk
                             files, for use in signing
        @param target: flashrom target ('bios' or 'ec')
        @param subdir: name of subdirectory of state dir, to use for sections
                    Default: same as target, resulting in
                    '/usr/local/tmp/faft/bios'
        @type os_if: client.cros.faft.utils.os_interface.OSInterface
        @type pub_key_file: str | None
        @type dev_key_path: str
        @type target: str
        """
        self.fum = None
        self.image = ''
        self.os_if = os_if
        self.initialized = False
        self._available = None
        self._unavailable_err = None

        if subdir is None:
            subdir = target
        self.subdir = subdir

        self.pub_key_file = pub_key_file
        self.dev_key_path = dev_key_path

        self.target = target
        if self.target == 'bios':
            self.fum = saft_flashrom_util.flashrom_util(
                    self.os_if, target_is_ec=False)
            self.fv_sections = {
                    'ro': FvSection(None, None, 'RO_FRID'),
                    'a': FvSection('VBOOTA', 'FVMAIN', 'RW_FWID_A'),
                    'b': FvSection('VBOOTB', 'FVMAINB', 'RW_FWID_B'),
                    'me_a': FvSection(None, 'ME_RW_A'),
                    'me_b': FvSection(None, 'ME_RW_B'),
                    'rec': FvSection(None, 'RECOVERY_MRC_CACHE'),
                    'ec_a': FvSection(None, 'ECMAINA'),
                    'ec_b': FvSection(None, 'ECMAINB'),
                    'rw_legacy': FvSection(None, 'RW_LEGACY'),
            }
        elif self.target == 'ec':
            self.fum = saft_flashrom_util.flashrom_util(
                    self.os_if, target_is_ec=True)
            self.fv_sections = {
                    'ro': FvSection(None, None, 'RO_FRID'),
                    'rw': FvSection(None, 'EC_RW', 'RW_FWID'),
                    'rw_b': FvSection(None, 'EC_RW_B'),
            }
        else:
            raise FlashromHandlerError("Invalid target.")

    def is_available(self):
        """Check if the programmer is available, by specifying no commands.

        @rtype: bool
        """
        if self._available is None:
            # Cache the status to avoid trying flashrom every time.
            try:
                self.fum.check_target()
                self._available = True
            except error.CmdError as e:
                # First line: "Command <flashrom -p host> failed, rc=2"
                self._unavailable_err = str(e).split('\n', 1)[0]
                self._available = False
        return self._available

    def section_file(self, *paths):
        """
        Return a full path for the given basename, in this handler's subdir.
        Example: subdir 'bios' -> '/usr/local/tmp/faft/bios/FV_GBB'

        @param paths: variable number of path pieces, same as in os.path.join
        @return: an absolute path from this handler's subdir and the pieces.
        """
        if any(os.path.isabs(x) for x in paths):
            raise FlashromHandlerError(
                    "Absolute paths are not allowed in section_file()")

        return os.path.join(self.os_if.state_dir, self.subdir, *paths)

    def init(self, image_file=None, allow_fallback=False):
        """Initialize the object, by reading the image.

        This is separate from new_image, to isolate the implementation detail of
        self.image being non-empty.

        @param image_file: the path of the image file to read.
                If None or empty string, read the flash device instead.
        @param allow_fallback: if True, fall back to reading the flash device
                if the image file doesn't exist.
        @type image_file: str
        @type allow_fallback: bool

        @raise FlashromHandlerError: if no target flash device was usable.
        """
        # Raise an exception early if there's no usable flash.
        if not self.is_available():
            # Can't tell for sure whether it's broken or simply nonexistent.
            raise FlashromHandlerError(
                    "Could not detect a usable %s flash device: %s."
                    % (self.target, self._unavailable_err))

        if image_file and allow_fallback and not os.path.isfile(image_file):
            self.os_if.log(
                    "Using %s flash contents instead of missing image: %s"
                    % (self.target.upper(), image_file))
            image_file = None

        self.new_image(image_file)
        self.initialized = True

    def deinit(self):
        """Clear the in-memory image data, and mark self uninitialized."""
        self.image = ''
        self.os_if.remove_dir(self.section_file())
        self.initialized = False

    def dump_flash(self, target_filename):
        """Copy the flash device's data into a file, but don't parse it.

        @param target_filename: the file to create
        """
        self.fum.dump_flash(target_filename)

    def new_image(self, image_file=None):
        """Parse the full flashrom image and store sections into files.

        @param image_file: the name of the file containing a full ChromeOS
                       flashrom image. If not passed in or empty, the actual
                       flash device is read and its contents are saved into a
                       temporary file which is used instead.
        @type image_file: str | None

        The input file is parsed and the sections of importance (as defined in
        self.fv_sections) are saved in separate files in the state directory
        as defined in the os_if object.
        """

        if image_file:
            with open(image_file, 'rb') as image_f:
                self.image = image_f.read()
            self.fum.set_firmware_layout(image_file)
        else:
            self.image = self.fum.read_whole()

        self.os_if.create_dir(self.section_file())

        for section in self.fv_sections.itervalues():
            for subsection_name in section.names():
                if not subsection_name:
                    continue
                blob = self.fum.get_section(self.image, subsection_name)
                if blob:
                    blob_filename = self.section_file(subsection_name)
                    with open(blob_filename, 'wb') as blob_f:
                        blob_f.write(blob)

            blob = self.fum.get_section(self.image, section.get_body_name())
            if blob:
                s = hashlib.sha1()
                s.update(blob)
                section.set_sha(s.hexdigest())

            # If there is no "sig" subsection, skip reading version and flags.
            if not section.get_sig_name():
                continue

            # Now determine this section's version number.
            vb_section = self.fum.get_section(self.image,
                                              section.get_sig_name())

            section.set_version(self.os_if.retrieve_body_version(vb_section))
            section.set_flags(self.os_if.retrieve_preamble_flags(vb_section))
            section.set_datakey_version(
                    self.os_if.retrieve_datakey_version(vb_section))
            section.set_kernel_subkey_version(
                    self.os_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()

    def _retrieve_pub_key(self):
        """Retrieve root public key from the firmware GBB section."""

        gbb_header_format = '<4s20s2I'
        pubk_header_format = '<2Q'

        gbb_section = self.fum.get_section(self.image, 'FV_GBB')

        # do some sanity checks
        try:
            sig, _, rootk_offs, rootk_size = struct.unpack_from(
                    gbb_header_format, gbb_section)
        except struct.error, e:
            raise FlashromHandlerError(e)

        if sig != '$GBB' or (rootk_offs + rootk_size) > len(gbb_section):
            raise FlashromHandlerError('Bad gbb header')

        key_body_offset, key_body_size = struct.unpack_from(
                pubk_header_format, gbb_section, rootk_offs)

        # Generally speaking the offset field can be anything, but in case of
        # GBB section the key is stored as a standalone entity, so the offset
        # of the key body is expected to be equal to the key header size of
        # 0x20.
        # Should this convention change, the check below would fail, which
        # would be a good prompt for revisiting this test's behavior and
        # algorithms.
        if key_body_offset != 0x20 or key_body_size > rootk_size:
            raise FlashromHandlerError('Bad public key format')

        # All checks passed, let's store the key in a file.
        self.pub_key_file = self.os_if.state_dir_file(self.PUB_KEY_FILE_NAME)
        with open(self.pub_key_file, 'w') as key_f:
            key = gbb_section[rootk_offs:rootk_offs + key_body_offset +
                              key_body_size]
            key_f.write(key)

    def verify_image(self):
        """Confirm the image's validity.

        Using the file supplied to init() as the public key container verify
        the two sections' (FirmwareA and FirmwareB) integrity. The contents of
        the sections is taken from the files created by new_image()

        In case there is an integrity error raises FlashromHandlerError
        exception with the appropriate error message text.
        """

        for section in self.fv_sections.itervalues():
            if section.get_sig_name():
                cmd = 'vbutil_firmware --verify %s --signpubkey %s  --fv %s' % (
                        self.section_file(section.get_sig_name()),
                        self.pub_key_file,
                        self.section_file(section.get_body_name()))
                self.os_if.run_shell_command(cmd)

    def _modify_section(self,
                        section,
                        delta,
                        body_or_sig=False,
                        corrupt_all=False):
        """Modify a firmware section inside the image, either body or signature.

        If corrupt_all is set, the passed in delta is added to all bytes in the
        section. Otherwise, the delta is added to the value located at 2% offset
        into the section blob, either body or signature.

        Calling this function again for the same section the complimentary
        delta value would restore the section contents.
        """

        if not self.image:
            raise FlashromHandlerError(
                    'Attempt at using an uninitialized object')
        if section not in self.fv_sections:
            raise FlashromHandlerError('Unknown FW section %s' % section)

        # Get the appropriate section of the image.
        if body_or_sig:
            subsection_name = self.fv_sections[section].get_body_name()
        else:
            subsection_name = self.fv_sections[section].get_sig_name()
        blob = self.fum.get_section(self.image, subsection_name)

        # Modify the byte in it within 2% of the section blob.
        modified_index = len(blob) / 50
        if corrupt_all:
            blob_list = [('%c' % ((ord(x) + delta) % 0x100)) for x in blob]
        else:
            blob_list = list(blob)
            blob_list[modified_index] = (
                    '%c' % ((ord(blob[modified_index]) + delta) % 0x100))
        self.image = self.fum.put_section(self.image, subsection_name,
                                          ''.join(blob_list))

        return subsection_name

    def corrupt_section(self, section, corrupt_all=False):
        """Corrupt a section signature of the image"""

        return self._modify_section(
                section,
                self.DELTA,
                body_or_sig=False,
                corrupt_all=corrupt_all)

    def corrupt_section_body(self, section, corrupt_all=False):
        """Corrupt a section body of the image"""

        return self._modify_section(
                section, self.DELTA, body_or_sig=True, corrupt_all=corrupt_all)

    def restore_section(self, section, restore_all=False):
        """Restore a previously corrupted section signature of the image."""

        return self._modify_section(
                section,
                -self.DELTA,
                body_or_sig=False,
                corrupt_all=restore_all)

    def restore_section_body(self, section, restore_all=False):
        """Restore a previously corrupted section body of the image."""

        return self._modify_section(
                section,
                -self.DELTA,
                body_or_sig=True,
                corrupt_all=restore_all)

    def corrupt_firmware(self, section, corrupt_all=False):
        """Corrupt a section signature in the FLASHROM!!!"""

        subsection_name = self.corrupt_section(
                section, corrupt_all=corrupt_all)
        self.fum.write_partial(self.image, (subsection_name, ))

    def corrupt_firmware_body(self, section, corrupt_all=False):
        """Corrupt a section body in the FLASHROM!!!"""

        subsection_name = self.corrupt_section_body(
                section, corrupt_all=corrupt_all)
        self.fum.write_partial(self.image, (subsection_name, ))

    def restore_firmware(self, section, restore_all=False):
        """Restore the previously corrupted section sig in the FLASHROM!!!"""

        subsection_name = self.restore_section(
                section, restore_all=restore_all)
        self.fum.write_partial(self.image, (subsection_name, ))

    def restore_firmware_body(self, section, restore_all=False):
        """Restore the previously corrupted section body in the FLASHROM!!!"""

        subsection_name = self.restore_section_body(section, restore_all=False)
        self.fum.write_partial(self.image, (subsection_name, ))

    def firmware_sections_equal(self):
        """Check if firmware sections A and B are equal.

        This function presumes that the entire BIOS image integrity has been
        verified, so different signature sections mean different images and
        vice versa.
        """
        sig_a = self.fum.get_section(self.image,
                                     self.fv_sections['a'].get_sig_name())
        sig_b = self.fum.get_section(self.image,
                                     self.fv_sections['b'].get_sig_name())
        return sig_a == sig_b

    def copy_from_to(self, src, dst):
        """Copy one firmware image section to another.

        This function copies both signature and body of one firmware section
        into another. After this function runs both sections are identical.
        """
        src_sect = self.fv_sections[src]
        dst_sect = self.fv_sections[dst]
        self.image = self.fum.put_section(
                self.image, dst_sect.get_body_name(),
                self.fum.get_section(self.image, src_sect.get_body_name()))
        # If there is no "sig" subsection, skip copying signature.
        if src_sect.get_sig_name() and dst_sect.get_sig_name():
            self.image = self.fum.put_section(
                    self.image, dst_sect.get_sig_name(),
                    self.fum.get_section(self.image, src_sect.get_sig_name()))
        self.write_whole()

    def write_whole(self):
        """Write the whole image into the flashrom."""

        if not self.image:
            raise FlashromHandlerError(
                    'Attempt at using an uninitialized object')
        self.fum.write_whole(self.image)

    def write_partial(self, subsection_name, blob=None, write_through=True):
        """Write the subsection part into the flashrom.

        One can pass a blob to update the data of the subsection before write
        it into the flashrom.
        """

        if not self.image:
            raise FlashromHandlerError(
                    'Attempt at using an uninitialized object')

        if blob is not None:
            self.image = self.fum.put_section(self.image, subsection_name,
                                              blob)

        if write_through:
            self.dump_partial(
                    subsection_name, self.section_file(subsection_name))
            self.fum.write_partial(self.image, (subsection_name, ))

    def dump_whole(self, filename):
        """Write the whole image into a file."""

        if not self.image:
            raise FlashromHandlerError(
                    'Attempt at using an uninitialized object')
        open(filename, 'w').write(self.image)

    def dump_partial(self, subsection_name, filename):
        """Write the subsection part into a file."""

        if not self.image:
            raise FlashromHandlerError(
                    'Attempt at using an uninitialized object')
        blob = self.fum.get_section(self.image, subsection_name)
        open(filename, 'w').write(blob)

    def dump_section_body(self, section, filename):
        """Write the body of a firmware section into a file"""
        subsection_name = self.fv_sections[section].get_body_name()
        self.dump_partial(subsection_name, filename)

    def get_section_hash(self, section):
        """Retrieve the hash of the body of a firmware section"""
        ecrw = chip_utils.ecrw()

        # add a dot to avoid set_from_file breaking if tmpname has an underscore
        with tempfile.NamedTemporaryFile(prefix=ecrw.chip_name + '.') as f:
            self.dump_section_body(section, f.name)
            ecrw.set_from_file(f.name)
            result = ecrw.compute_hash_bytes()
        return result

    def get_gbb_flags(self):
        """Retrieve the GBB flags"""
        gbb_header_format = '<12sL'
        gbb_section = self.fum.get_section(self.image, 'FV_GBB')
        try:
            _, gbb_flags = struct.unpack_from(gbb_header_format, gbb_section)
        except struct.error, e:
            raise FlashromHandlerError(e)
        return gbb_flags

    def set_gbb_flags(self, flags, write_through=False):
        """Retrieve the GBB flags"""
        gbb_header_format = '<L'
        section_name = 'FV_GBB'
        gbb_section = self.fum.get_section(self.image, section_name)
        try:
            formatted_flags = struct.pack(gbb_header_format, flags)
        except struct.error, e:
            raise FlashromHandlerError(e)
        gbb_section = gbb_section[:12] + formatted_flags + gbb_section[16:]
        self.write_partial(section_name, gbb_section, write_through)

    def enable_write_protect(self):
        """Enable write protect of the flash chip"""
        description = 'Failed to enable %s write-protect' % self.target
        with _FlashromErrorWrapper(description):
            self.fum.enable_write_protect()

    def disable_write_protect(self):
        """Disable write protect of the flash chip"""
        description = 'Failed to disable %s write-protect' % self.target
        with _FlashromErrorWrapper(description):
            self.fum.disable_write_protect()

    def set_write_protect_region(self, region, enabled=None):
        """
        Set write protection region by name, using current image's layout.

        The name should match those seen in `futility dump_fmap <image>`, and
        is not checked against self.firmware_layout, due to different naming.

        @param region: Region to set (usually WP_RO)
        @param enabled: If True, run --wp-enable; if False, run --wp-disable.
                        If None (default), don't specify either one.
        """
        if region is None:
            raise FlashromHandlerError("Region must not be None")
        image_file = self.os_if.create_temp_file('wp_')
        self.os_if.write_file(image_file, self.image)

        if enabled is None:
            verb = 'set'
        else:
            verb = 'enable' if enabled else 'disable'
        msg = 'Failed to %s %s write-protect region (%s)' % (
            verb, self.target, region)

        with _FlashromErrorWrapper(msg):
            self.fum.set_write_protect_region(image_file, region, enabled)

        self.os_if.remove_file(image_file)

    def set_write_protect_range(self, start, length, enabled=None):
        """
        Set write protection range by offsets, using current image's layout.

        @param start: offset (bytes) from start of flash to start of range
        @param length: offset (bytes) from start of range to end of range
        @param enabled: If True, run --wp-enable; if False, run --wp-disable.
                        If None (default), don't specify either one.
        """
        if enabled is None:
            verb = 'set'
        else:
            verb = 'enable' if enabled else 'disable'
        msg = 'Failed to %s %s write-protect range (start=%s, length=%s)' % (
            verb, self.target, start, length)

        with _FlashromErrorWrapper(msg):
            self.fum.set_write_protect_range(start, length, enabled)

    def get_write_protect_status(self):
        """Get a dict describing the status of the write protection

        @return: {'enabled': True/False, 'start': '0x0', 'length': '0x0', ...}
        @rtype: dict
        """
        return self.fum.get_write_protect_status()

    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()

    def get_section_version(self, section):
        """Retrieve version number of a firmware section"""
        return self.fv_sections[section].get_version()

    def get_section_flags(self, section):
        """Retrieve preamble flags of a firmware section"""
        return self.fv_sections[section].get_flags()

    def get_section_datakey_version(self, section):
        """Retrieve data key version number of a firmware section"""
        return self.fv_sections[section].get_datakey_version()

    def get_section_kernel_subkey_version(self, section):
        """Retrieve kernel subkey version number of a firmware section"""
        return self.fv_sections[section].get_kernel_subkey_version()

    def get_section_body(self, section):
        """Retrieve body of a firmware section"""
        subsection_name = self.fv_sections[section].get_body_name()
        blob = self.fum.get_section(self.image, subsection_name)
        return blob

    def has_section_body(self, section):
        """Return True if the section body is in the image"""
        return bool(self.get_section_body(section))

    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 get_section_fwid(self, section, strip_null=True):
        """
        Retrieve fwid blob of a firmware section.

        @param section: Name of the section whose fwid to return.
        @param strip_null: If True, remove \0 from the end of the blob.
        @return: fwid of the section

        @type section: str
        @type strip_null: bool
        @rtype: str | None

        """
        subsection_name = self.fv_sections[section].get_fwid_name()
        if not subsection_name:
            return None
        blob = self.fum.get_section(self.image, subsection_name)
        if strip_null:
            blob = blob.rstrip('\0')
        return 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.write_partial(subsection_name, blob, write_through)

    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.write_partial(subsection_name, blob, write_through)

    def set_section_fwid(self, section, blob, write_through=False):
        """Put the supplied blob to the fwid of the firmware section"""
        subsection_name = self.fv_sections[section].get_fwid_name()
        self.write_partial(subsection_name, blob, write_through)

    def resign_ec_rwsig(self):
        """Resign the EC image using rwsig."""
        key_ec_efs = os.path.join(self.dev_key_path, self.EC_EFS_KEY_FILE_NAME)
        # Dump whole EC image to a file and execute the sign command.
        with tempfile.NamedTemporaryFile() as f:
            self.dump_whole(f.name)
            self.os_if.run_shell_command(
                    'futility sign --type rwsig --prikey %s %s' % (key_ec_efs,
                                                                   f.name))
            self.new_image(f.name)

    def set_section_version(self, section, version, flags,
                            write_through=False):
        """
        Re-sign the firmware section using the supplied version number and
        flag.
        """
        if (self.get_section_version(section) == version
                    and self.get_section_flags(section) == flags):
            return  # No version or flag change, nothing to do.
        if version < 0:
            raise FlashromHandlerError(
                    'Attempt to set version %d on section %s' % (version,
                                                                 section))
        fv_section = self.fv_sections[section]
        sig_name = self.section_file(fv_section.get_sig_name())
        sig_size = os.path.getsize(sig_name)

        # Construct the command line
        args = ['--vblock %s' % sig_name]
        args.append('--keyblock %s' % os.path.join(self.dev_key_path,
                                                   self.FW_KEYBLOCK_FILE_NAME))
        args.append('--fv %s' % self.section_file(fv_section.get_body_name()))
        args.append('--version %d' % version)
        args.append('--kernelkey %s' % os.path.join(
                self.dev_key_path, self.KERNEL_SUBKEY_FILE_NAME))
        args.append('--signprivate %s' % os.path.join(
                self.dev_key_path, self.FW_PRIV_DATA_KEY_FILE_NAME))
        args.append('--flags %d' % flags)
        cmd = 'vbutil_firmware %s' % ' '.join(args)
        self.os_if.run_shell_command(cmd)

        #  Pad the new signature.
        with open(sig_name, 'a') as sig_f:
            f_size = os.fstat(sig_f.fileno()).st_size
            pad = '\0' * (sig_size - f_size)
            sig_f.write(pad)

        # Inject the new signature block into the image
        with open(sig_name, 'r') as sig_f:
            new_sig = sig_f.read()
        self.write_partial(fv_section.get_sig_name(), new_sig, write_through)

    def _modify_section_fwid(self, section):
        """Modify a section's fwid on the handler, adding a tilde and the
        section name (in caps) to the end: ~RO, ~RW, ~A, ~B.

        @param section: the single section to act on
        @return: the new fwid

        @type section: str
        @rtype: str
        """

        fwid = self.get_section_fwid(section, strip_null=False)

        if fwid is None:
            return None

        fwid_size = len(fwid)

        if not fwid:
            raise FlashromHandlerError(
                    "FWID (%s, %s) is empty: %s" %
                    (self.target.upper(), section.upper(), repr(fwid)))

        fwid = fwid.rstrip('\0')
        suffix = self.FWID_MOD_DELIMITER + section.upper()

        if suffix in fwid:
            raise FlashromHandlerError(
                    "FWID (%s, %s) is already modified: %s" %
                    (self.target.upper(), section.upper(), repr(fwid)))

        # Append a suffix, after possibly chopping off characters to make room.
        if len(fwid) + len(suffix) > fwid_size:
            fwid = fwid[:fwid_size - len(suffix)]
        fwid += suffix

        padded_fwid = fwid.ljust(fwid_size, '\0')
        self.set_section_fwid(section, padded_fwid)
        return fwid

    def _strip_section_fwid(self, section, write_through=True):
        """Modify a section's fwid on the handler, stripping any suffix added
        by _modify_section_fwid: ~RO, ~RW, ~A, ~B.

        @param section: the single section to act on
        @param write_through: if True (default), write to flash immediately
        @return: the suffix that was stripped

        @type section: str
        @type write_through: bool
        @rtype: str | None
        """

        fwid = self.get_section_fwid(section, strip_null=False)
        if fwid is None:
            return None

        fwid_size = len(fwid)

        if not fwid:
            raise FlashromHandlerError(
                    "FWID (%s, %s) is empty: %s" %
                    (self.target.upper(), section.upper(), repr(fwid)))

        fwid = fwid.rstrip('\0')
        mod_indicator = self.FWID_MOD_DELIMITER + section.upper()

        # Remove any suffix, and return the suffix if found.
        if mod_indicator in fwid:
            (stripped_fwid, remainder) = fwid.split(mod_indicator, 1)

            padded_fwid = stripped_fwid.ljust(fwid_size, '\0')
            self.set_section_fwid(section, padded_fwid, write_through)

            return fwid
        return None

    def modify_fwids(self, sections):
        """Modify the fwid in the in-memory image.

        @param sections: section(s) to modify.
        @return: fwids for the modified sections, as {section: fwid}

        @type sections: tuple | list
        @rtype: dict
        """
        fwids = {}
        for section in sections:
            fwids[section] = self._modify_section_fwid(section)

        return fwids

    def strip_modified_fwids(self):
        """Strip any trailing suffixes (from modify_fwids) out of the FWIDs.

        @return: a dict of any fwids that were adjusted, by section (ro, a, b)
        @rtype: dict
        """

        suffixes = {}
        for section in self.fv_sections:
            suffix = self._strip_section_fwid(section)
            if suffix is not None:
                suffixes[section] = suffix

        return suffixes

    def get_write_cmd(self, image=None):
        """Get the command needed to write the whole image to the device.

        @param image: the filename (empty to use current handler data)
        """
        if image:
            return self.fum.get_write_cmd(image)
        else:
            tmp_image = self.os_if.create_temp_file('tmp_%s.bin.' % self.target)
            self.os_if.write_file(tmp_image, self.image)
            cmd = self.fum.get_write_cmd(tmp_image)
            return '%s; rm %s' % (cmd, tmp_image)
