Ejemplo n.º 1
0
    def ObtainContents(self):
        gbb = 'gbb.bin'
        fname = tools.GetOutputFilename(gbb)
        if not self.size:
            self.Raise('GBB must have a fixed size')
        gbb_size = self.size
        bmpfv_size = gbb_size - 0x2180
        if bmpfv_size < 0:
            self.Raise('GBB is too small (minimum 0x2180 bytes)')
        sizes = [0x100, 0x1000, bmpfv_size, 0x1000]
        sizes = ['%#x' % size for size in sizes]
        keydir = tools.GetInputFilename(self.keydir)
        gbb_set_command = [
            'gbb_utility', '-s',
            '--hwid=%s' % self.hardware_id,
            '--rootkey=%s/root_key.vbpubk' % keydir,
            '--recoverykey=%s/recovery_key.vbpubk' % keydir,
            '--flags=%d' % self.gbb_flags,
            '--bmpfv=%s' % tools.GetInputFilename(self.bmpblk), fname
        ]

        tools.Run('futility', 'gbb_utility', '-c', ','.join(sizes), fname)
        tools.Run('futility', *gbb_set_command)

        self.SetContents(tools.ReadFile(fname))
        return True
Ejemplo n.º 2
0
    def build_from_git(cls, git_repo, make_target, bintool_path):
        """Build a bintool from a git repo

        This clones the repo in a temporary directory, builds it with 'make',
        then returns the filename of the resulting executable bintool

        Args:
            git_repo (str): URL of git repo
            make_target (str): Target to pass to 'make' to build the tool
            bintool_path (str): Relative path of the tool in the repo, after
                build is complete

        Returns:
            tuple:
                str: Filename of fetched file to copy to a suitable directory
                str: Name of temp directory to remove, or None
            or None on error
        """
        tmpdir = tempfile.mkdtemp(prefix='binmanf.')
        print(f"- clone git repo '{git_repo}' to '{tmpdir}'")
        tools.Run('git', 'clone', '--depth', '1', git_repo, tmpdir)
        print(f"- build target '{make_target}'")
        tools.Run('make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}',
                  make_target)
        fname = os.path.join(tmpdir, bintool_path)
        if not os.path.exists(fname):
            print(f"- File '{fname}' was not produced")
            return None
        return fname, tmpdir
Ejemplo n.º 3
0
    def setUpClass(cls):
        # Create a temporary directory for test files
        cls._indir = tempfile.mkdtemp(prefix='cbfs_util.')
        tools.SetInputDirs([cls._indir])

        # Set up some useful data files
        TestCbfs._make_input_file('u-boot.bin', U_BOOT_DATA)
        TestCbfs._make_input_file('u-boot.dtb', U_BOOT_DTB_DATA)
        TestCbfs._make_input_file('compress', COMPRESS_DATA)

        # Set up a temporary output directory, used by the tools library when
        # compressing files
        tools.PrepareOutputDir(None)

        cls.have_cbfstool = True
        try:
            tools.Run('which', 'cbfstool')
        except:
            cls.have_cbfstool = False

        cls.have_lz4 = True
        try:
            tools.Run('lz4',
                      '--no-frame-crc',
                      '-c',
                      tools.GetInputFilename('u-boot.bin'),
                      binary=True)
        except:
            cls.have_lz4 = False
Ejemplo n.º 4
0
    def GetVblock(self):
        # Join up the data files to be signed
        input_data = b''
        for entry_phandle in self.content:
            data = self.section.GetContentsByPhandle(entry_phandle, self)
            if data is None:
                # Data not available yet
                return False
            input_data += data

        uniq = self.GetUniqueName()
        output_fname = tools.GetOutputFilename('vblock.%s' % uniq)
        input_fname = tools.GetOutputFilename('input.%s' % uniq)
        tools.WriteFile(input_fname, input_data)
        prefix = self.keydir + '/'
        args = [
            'vbutil_firmware',
            '--vblock', output_fname,
            '--keyblock', prefix + self.keyblock,
            '--signprivate', prefix + self.signprivate,
            '--version', '%d' % self.version,
            '--fv', input_fname,
            '--kernelkey', prefix + self.kernelkey,
            '--flags', '%d' % self.preamble_flags,
        ]
        #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
        stdout = tools.Run('futility', *args)
        return tools.ReadFile(output_fname)
Ejemplo n.º 5
0
    def ObtainContents(self):
        """Obtain the contents of the FIT

        This adds the 'data' properties to the input ITB (Image-tree Binary)
        then runs mkimage to process it.
        """
        # self._BuildInput() either returns bytes or raises an exception.
        data = self._BuildInput(self._fdt)
        uniq = self.GetUniqueName()
        input_fname = tools.GetOutputFilename('%s.itb' % uniq)
        output_fname = tools.GetOutputFilename('%s.fit' % uniq)
        tools.WriteFile(input_fname, data)
        tools.WriteFile(output_fname, data)

        args = []
        ext_offset = self._fit_props.get('fit,external-offset')
        if ext_offset is not None:
            args += [
                '-E', '-p',
                '%x' % fdt_util.fdt32_to_cpu(ext_offset.value)
            ]
        tools.Run('mkimage', '-t', '-F', output_fname, *args)

        self.SetContents(tools.ReadFile(output_fname))
        return True
Ejemplo n.º 6
0
 def ReadBlobContents(self):
     if self._strip:
         uniq = self.GetUniqueName()
         out_fname = tools.GetOutputFilename('%s.stripped' % uniq)
         tools.WriteFile(out_fname, tools.ReadFile(self._pathname))
         tools.Run('strip', out_fname)
         self._pathname = out_fname
     super().ReadBlobContents()
     return True
Ejemplo n.º 7
0
    def fetch_from_url(cls, url):
        """Fetch a bintool from a URL

        Args:
            url (str): URL to fetch from

        Returns:
            tuple:
                str: Filename of fetched file to copy to a suitable directory
                str: Name of temp directory to remove, or None
        """
        fname, tmpdir = tools.Download(url)
        tools.Run('chmod', 'a+x', fname)
        return fname, tmpdir
Ejemplo n.º 8
0
 def ObtainContents(self):
     data = b''
     for entry in self._mkimage_entries.values():
         # First get the input data and put it in a file. If not available,
         # try later.
         if not entry.ObtainContents():
             return False
         data += entry.GetData()
     uniq = self.GetUniqueName()
     input_fname = tools.GetOutputFilename('mkimage.%s' % uniq)
     tools.WriteFile(input_fname, data)
     output_fname = tools.GetOutputFilename('mkimage-out.%s' % uniq)
     tools.Run('mkimage', '-d', input_fname, *self._args, output_fname)
     self.SetContents(tools.ReadFile(output_fname))
     return True
Ejemplo n.º 9
0
    def apt_install(cls, package):
        """Install a bintool using the 'aot' tool

        This requires use of servo so may request a password

        Args:
            package (str): Name of package to install

        Returns:
            True, assuming it completes without error
        """
        args = ['sudo', 'apt', 'install', '-y', package]
        print('- %s' % ' '.join(args))
        tools.Run(*args)
        return True
Ejemplo n.º 10
0
def BuildElfTestFiles(target_dir):
    """Build ELF files used for testing in binman

    This compiles and links the test files into the specified directory. It the
    Makefile and source files in the binman test/ directory.

    Args:
        target_dir: Directory to put the files into
    """
    if not os.path.exists(target_dir):
        os.mkdir(target_dir)
    testdir = os.path.join(binman_dir, 'test')

    # If binman is involved from the main U-Boot Makefile the -r and -R
    # flags are set in MAKEFLAGS. This prevents this Makefile from working
    # correctly. So drop any make flags here.
    if 'MAKEFLAGS' in os.environ:
        del os.environ['MAKEFLAGS']
    tools.Run('make', '-C', target_dir, '-f',
              os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
Ejemplo n.º 11
0
def GetSymbols(fname, patterns):
    """Get the symbols from an ELF file

    Args:
        fname: Filename of the ELF file to read
        patterns: List of regex patterns to search for, each a string

    Returns:
        None, if the file does not exist, or Dict:
          key: Name of symbol
          value: Hex value of symbol
    """
    stdout = tools.Run('objdump', '-t', fname)
    lines = stdout.splitlines()
    if patterns:
        re_syms = re.compile('|'.join(patterns))
    else:
        re_syms = None
    syms = {}
    syms_started = False
    for line in lines:
        if not line or not syms_started:
            if 'SYMBOL TABLE' in line:
                syms_started = True
            line = None  # Otherwise code coverage complains about 'continue'
            continue
        if re_syms and not re_syms.search(line):
            continue

        space_pos = line.find(' ')
        value, rest = line[:space_pos], line[space_pos + 1:]
        flags = rest[:7]
        parts = rest[7:].split()
        section, size = parts[:2]
        if len(parts) > 2:
            name = parts[2] if parts[2] != '.hidden' else parts[3]
            syms[name] = Symbol(section, int(value, 16), int(size, 16),
                                flags[1] == 'w')

    # Sort dict by address
    return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
Ejemplo n.º 12
0
    def GetVblock(self, required):
        """Get the contents of this entry

        Args:
            required: True if the data must be present, False if it is OK to
                return None

        Returns:
            bytes content of the entry, which is the signed vblock for the
                provided data
        """
        # Join up the data files to be signed
        input_data = self.GetContents(required)
        if input_data is None:
            return None

        uniq = self.GetUniqueName()
        output_fname = tools.GetOutputFilename('vblock.%s' % uniq)
        input_fname = tools.GetOutputFilename('input.%s' % uniq)
        tools.WriteFile(input_fname, input_data)
        prefix = self.keydir + '/'
        args = [
            'vbutil_firmware',
            '--vblock',
            output_fname,
            '--keyblock',
            prefix + self.keyblock,
            '--signprivate',
            prefix + self.signprivate,
            '--version',
            '%d' % self.version,
            '--fv',
            input_fname,
            '--kernelkey',
            prefix + self.kernelkey,
            '--flags',
            '%d' % self.preamble_flags,
        ]
        #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
        stdout = tools.Run('futility', *args)
        return tools.ReadFile(output_fname)
Ejemplo n.º 13
0
import tempfile
import unittest

# Bring in the patman and dtoc libraries (but don't override the first path
# in PYTHONPATH)
OUR_PATH = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(2, os.path.join(OUR_PATH, '..'))

# pylint: disable=C0413
from patman import test_util
from patman import tools
import fip_util

HAVE_FIPTOOL = True
try:
    tools.Run('which', 'fiptool')
except ValueError:
    HAVE_FIPTOOL = False


# pylint: disable=R0902,R0904
class TestFip(unittest.TestCase):
    """Test of fip_util classes"""

    #pylint: disable=W0212
    def setUp(self):
        # Create a temporary directory for test files
        self._indir = tempfile.mkdtemp(prefix='fip_util.')
        tools.SetInputDirs([self._indir])

        # Set up a temporary output directory, used by the tools library when