# Copyright (c) 2012 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.

import logging
import os
import re

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error

FLASHROM_ACCESS_FAILED_TOKEN = ('Could not fully verify due to access error, '
                                'ignoring')


class firmware_LockedME(test.test):
    # Needed by autotest
    version = 1

    # Temporary file to read BIOS image into. We run in a tempdir anyway, so it
    # doesn't need a path.
    BIOS_FILE = 'bios.bin'

    def flashrom(self, ignore_status=False, args=()):
        """Run flashrom, expect it to work. Fail if it doesn't"""
        extra = ['-p', 'host'] + list(args)
        return utils.run('flashrom', ignore_status=ignore_status, args=extra)

    def determine_sw_wp_status(self):
        """Determine software write-protect status."""
        logging.info('Check that SW WP is enabled or not...')
        flashrom_result = self.flashrom(args=('--wp-status',))
        logging.info('The above flashrom command returns.... %s',
                flashrom_result.stdout)
        if (("disabled" in flashrom_result.stdout) and
                ("start=0x00000000, len=0x0000000" in flashrom_result.stdout)):
            return False
        else:
            return True

    def has_ME(self):
        """See if we can detect an ME.
        FREG* is printed only when HSFS_FDV is set, which means the descriptor
        table is valid. If we're running a BIOS without a valid descriptor this
        step will fail. Unfortunately, we don't know of a simple and reliable
        way to identify systems that have ME hardware.
        """
        logging.info('See if we have an ME...')
        r = self.flashrom(args=('-V',))
        return r.stdout.find("FREG0") >= 0

    def try_to_rewrite(self, sectname):
        """If we can modify the ME section, restore it and raise an error."""
        logging.info('Try to write section %s...', sectname)
        size = os.stat(sectname).st_size
        utils.run('dd', args=('if=/dev/urandom', 'of=newdata',
                              'count=1', 'bs=%d' % (size)))
        r = self.flashrom(args=('-V', '-w', self.BIOS_FILE,
                                '-i' , '%s:newdata' % (sectname),
                                '--fast-verify'),
                          ignore_status=True)
        if (not r.exit_status and
            FLASHROM_ACCESS_FAILED_TOKEN not in r.stdout):
            logging.info('Oops, it worked! Put it back...')
            self.flashrom(args=('-w', self.BIOS_FILE,
                                '-i', '%s:%s' % (sectname, sectname),
                                '--fast-verify'),
                          ignore_status=True)
            raise error.TestFail('%s is writable, ME is unlocked' % sectname)

    def check_manufacturing_mode(self):
        """Fail if manufacturing mode is not found or enbaled."""

        # See if coreboot told us that the ME is still in Manufacturing Mode.
        # It shouldn't be. We have to look only at the last thing it reports
        # because it reports the values twice and the first one isn't always
        # reliable.
        logging.info('Check for Manufacturing Mode...')
        last = None
        with open('/sys/firmware/log') as infile:
            for line in infile:
                if re.search('ME: Manufacturing Mode', line):
                    last = line
        if last is not None and last.find("YES") >= 0:
            raise error.TestFail("The ME is still in Manufacturing Mode")

    def check_region_inaccessible(self, sectname):
        """Test and ensure a region is not accessible by host CPU."""

        # flashrom should have read the section as all 0xff's. If not,
        # the ME is not locked.
        logging.info('%s should be all 0xff...' % sectname)
        with open(sectname, 'rb') as f:
            for c in f.read():
                if c != chr(0xff):
                    err_string = "%s was readable by flashrom" % sectname
                    raise error.TestFail(err_string)

        # See if it is writable.
        self.try_to_rewrite(sectname)

    def run_once(self, expect_me_present=True):
        """Fail unless the ME is locked.

        @param expect_me_present: False means the system has no ME.
        """
        cpu_arch = utils.get_cpu_arch()
        if cpu_arch == "arm":
            raise error.TestNAError('This test is not applicable, '
                    'because an ARM device has been detected. '
                    'ARM devices do not have an ME (Management Engine)')

        cpu_family = utils.get_cpu_soc_family()
        if cpu_family == "amd":
            raise error.TestNAError('This test is not applicable, '
                    'because an AMD device has been detected. '
                    'AMD devices do not have an ME (Management Engine)')

        # If sw wp is on, and the ME regions are unlocked, they won't be
        # writable so will appear locked.
        if self.determine_sw_wp_status():
            raise error.TestFail('Software wp is enabled. Please disable '
                'software wp prior to running this test.')

        # See if the system even has an ME, and whether we expected that.
        if self.has_ME():
            if not expect_me_present:
                raise error.TestFail('We expected no ME, but found one anyway')
        else:
            if expect_me_present:
                raise error.TestNAError("No ME found. That's probably wrong.")
            else:
                logging.info('We expected no ME and we have no ME, so pass.')
                return

        # Make sure manufacturing mode is off.
        self.check_manufacturing_mode()

        # Read the image using flashrom.
        self.flashrom(args=('-r', self.BIOS_FILE))

        # Use 'IFWI' fmap region as a proxy for a device which doesn't
        # have a dedicated ME region in the boot media.
        r = utils.run('dump_fmap', args=('-p', self.BIOS_FILE))
        is_IFWI_platform = r.stdout.find("IFWI") >= 0

        # Get the bios image and extract the ME components
        logging.info('Pull the ME components from the BIOS...')
        dump_fmap_args = ['-x', self.BIOS_FILE, 'SI_DESC']
        inaccessible_sections = []
        if is_IFWI_platform:
            inaccessible_sections.append('DEVICE_EXTENSION')
        else:
            inaccessible_sections.append('SI_ME')
        dump_fmap_args.extend(inaccessible_sections)
        utils.run('dump_fmap', args=tuple(dump_fmap_args))

        # So far, so good, but we need to be certain. Rather than parse what
        # flashrom tells us about the ME-related registers, we'll just try to
        # change the ME components. We shouldn't be able to.
        self.try_to_rewrite('SI_DESC')
        for sectname in inaccessible_sections:
            self.check_region_inaccessible(sectname)

        # Okay, that's about all we can try. Looks like it's locked.
