#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.

"""Repackage image for signing check.

The image is packaged as follows
Signing will add 16 bytes header (header size and signature offset) plus
8 bytes of padding.

There are two cases:
  if signature_offset == FAKE_SIGN_OFFSET
   header_size contains the length of the file after the 16 byte header
    (or file_size = 16 + header_size)

  if signature_offset != FAKE_SIGN_OFFSET
    header_size =  signature_offset - 16 (not needed/used)
    signature_offset = filesize - 256 - 16 (means the signature is 256 bytes)


The info is free format. Now it is only a string to hold verity table.
|-------------------| <=== Byte 0
| header size       | (integer)
|-------------------| <=== Byte 4
| signature offset  | (integer) pointing to the signature below.
|-------------------| <=== Byte 8
| padding           | Padding
|-------------------| <=== Byte 16
| info (e.g. verity | (4080 bytes)
|  table)           |
|-------------------| <=== Byte 4096
| vmlinuz           | this block is padded to align with 4096 Byte block.
|-------------------| <=== Byte N x 4096
| verity hash table |
|-------------------|
| signature         |
|-------------------|
"""

__author__ = 'kedong@google.com (Ke Dong)'

import os
import re
import shutil
import struct
import subprocess
import sys
import options


optspec = """
repack.py -r <rootfs> -k <kernel> -o <hostdir> -b <bindir> [options...]
--
k,kernel=         kernel image file name [vmlinuz]
r,rootfs=         rootfs image file name [rootfs.squashfs]
o,hostdir=        host directory
b,bindir=         binary directory
s,sign            sign image with production key
bolt_sign         sign a bolt image
t,signing_tool=   tool to call to do the signing [brcm_sign_enc]
q,quiet           suppress print
"""


BLOCK_SIZE = 4096
VERITY_START = '[VERITY-START]'
VERITY_STOP = '[VERITY-STOP]'
VERITY_START_SIZE = '[VERITY-START-SIZE]'
VERITY_STOP_SIZE = '[VERITY-STOP-SIZE]'
FAKE_SIGN_OFFSET = 0x90091efb
quiet = False


def GetRandom():
  """Generate a random hexstring of 64 bytes."""
  return os.urandom(32).encode('hex')


def CheckOutput(args, **kwargs):
  nkwargs = dict(stdout=subprocess.PIPE)
  nkwargs.update(kwargs)
  p = subprocess.Popen(args, **nkwargs)
  data = p.stdout.read()
  retval = p.wait()
  if retval:
    raise Exception('%r returned exit code %d' % (args, retval))
  return data.strip()


def GenerateVerityTable(hostdir, bindir, rootfs):
  """Generate the verity table."""
  return CheckOutput(
      [os.path.join(hostdir, 'usr/bin/verity'), 'mode=create',
       'alg=sha256', 'payload=' + os.path.join(bindir, rootfs),
       'salt=' + GetRandom(), 'hashtree=' + os.path.join(bindir, 'hash.bin')])


def CeilingBlock(size):
  """Calculate the number of blocks based on the size in bytes."""
  return (size + BLOCK_SIZE - 1) / BLOCK_SIZE


def UpdateVerityTable(table, hash_offset):
  """Update the verity table with correct hash table offset.

  Args:
    table:  the verity hash table content
    hash_offset: the hash table offset in sector (each sector has 512 bytes)

  Returns:
    updated verity hash table content
  """
  find_offset = re.compile(r'hashstart=(\d+)')
  return find_offset.sub(r'hashstart=' + str(hash_offset), table)


def FakeSign(fname):
  """Sign the image with valid header but no signature.

  Args:
    fname:  the path to the image file to be signed.
  """
  size = os.stat(fname).st_size
  with open(fname, 'r+b') as f:
    c = f.read()
    f.seek(0)
    f.write(struct.pack('<IIII', size, FAKE_SIGN_OFFSET, 0, 0))
    f.write(c)


def RealSign(bindir, hostdir, key, ifname, ofname, signing_tool):
  """Sign the image with production key."""
  olddir = os.getcwd()
  os.chdir(os.path.join(bindir, 'signing'))
  p = subprocess.Popen([os.path.join(hostdir, 'usr/bin', signing_tool)],
                       stdin=subprocess.PIPE, shell=False)
  for cmd in ['sign_kernel_file', ifname, ofname + '-sig.bin', 'l', key,
              ofname]:
    p.stdin.write(cmd + '\n')
  p.stdin.close()
  retval = p.wait()
  os.chdir(olddir)
  if retval:
    raise Exception('%s returned exit code %d' % (signing_tool, retval))


def RealSignBolt(hostdir, fname):
  """Sign the kernel image with the bolt signing tool.

  This uses the broadcom signing tool to sign a kerel for
  secure boot.  The function expects to be called with the
  current directory equal to out/build/images.

  Args:
    hostdir: Absoluate path to buildroot's out/host directory.
    fname: Name of the image to be signed

  Raises:
    Exception: if the signing tools fails.
  """

  tool_path = os.path.join(hostdir, 'usr/bin/boltsigning/gfiber')
  shutil.copy('signing/gfhd254_private.pem', '/dev/shm/gfhd254_private.pem')
  shutil.copy(fname, os.path.join(tool_path, 'kernel.img'))
  exit_code = subprocess.call(
      ['wine', '../imagetool.exe', '-L', 'kernel', '-O', 'kernel.cfg',
       '-K', 'signing=true'], cwd=tool_path)
  subprocess.call(['shred', '-fuz', '/dev/shm/gfhd254_private.pem'])
  if exit_code:
    raise Exception('bolt signing tool returned exit code %d' % (exit_code,))
  shutil.copy(os.path.join(tool_path, 'kernel.img.signed'), fname)


def PackVerity(kname, vname, info):
  """Pack verity information in the final image.

  Args:
    kname:  the path to the kernel file.
    vname:  the path to the verity hash table file.
    info:   the original verity table.
  """
  with open(kname, 'r+b') as f:
    verity_data = ''
    kernel_data = f.read()
    kernel_size = len(kernel_data)
    with open(vname, 'rb') as v:
      verity_data = v.read()
    padding_size = (CeilingBlock(kernel_size)*BLOCK_SIZE) - kernel_size
    # offset is the number of sectors to where the hash data begins (see diagram
    # at top of file):
    # The calculates the number of blocks (which are 4096 long) to the hash data
    # start and then multiplies by 8 to convert to sectors which are 512  bytes.
    offset = (1 + CeilingBlock(kernel_size)) * 8
    f.seek(0)
    verity_table = UpdateVerityTable(info, offset)
    if not quiet:
      print verity_table
      print 'hash_size=' + str(len(verity_data))
    f.write('%-4080.4080s' %
            (VERITY_START + verity_table + VERITY_STOP +
             VERITY_START_SIZE + str(len(verity_data)) + VERITY_STOP_SIZE))
    f.write(kernel_data)
    if padding_size > 0:
      f.write('\0'*padding_size)
    f.write(verity_data)


def main():
  global quiet  # gpylint: disable-msg=W0603
  o = options.Options(optspec)
  opt, unused_flags, unused_extra = o.parse(sys.argv[1:])

  quiet = opt.quiet
  verity_table = GenerateVerityTable(opt.hostdir, opt.bindir,
                                     opt.rootfs)
  PackVerity(os.path.join(opt.bindir, opt.kernel),
             os.path.join(opt.bindir, 'hash.bin'),
             verity_table)
  if opt.sign:
    if opt.bolt_sign:
      fname = os.path.join(opt.bindir, opt.kernel)
      RealSignBolt(opt.hostdir, fname)
    else:
      ifname = os.path.join(opt.bindir, 'signing', opt.kernel)
      ofname = os.path.join(opt.bindir, opt.kernel)
      shutil.copy(ofname, ifname)
      RealSign(opt.bindir, opt.hostdir, 'gfiber_private.pem', ifname, ofname,
               opt.signing_tool)
  else:
    FakeSign(os.path.join(opt.bindir, opt.kernel))


if __name__ == '__main__':
  sys.exit(main())
