#!/usr/bin/env python2

from __future__ import print_function

import mmap
import os
import struct
import sys
from argparse import ArgumentParser
import newtimg
from ctypes import *
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA

DEBUG = False

def get_args():
    parser = ArgumentParser(description='Convert Zephyr binaries to mcuboot format')

    parser.add_argument('--bin', required=True, dest='binary_file', \
                        help='Name of *.bin file (input)')

    parser.add_argument('--key', required=False, dest='key_file', \
                        help='Name of private key file (*.pem format)')

    parser.add_argument('--out', required=False, dest='image_file', \
                        default='zephyr.img.bin', \
                        help='Name of *.img file (output)')

    parser.add_argument('--sig', required=False, dest='sig_type', \
                        default='SHA256', \
                        help='Type of signature <SHA256|RSA|EC>')

    parser.add_argument('--word-size', required=False, dest='word_size',
            default=1,
            help='Writable size of flash device (1, 2, 4, or 8)')

    parser.add_argument('--vtoff', required=False, dest='vtable_offs', \
                        default=str(hex(newtimg.OFFSET_VECTOR_TABLE)), \
                        help='Offset to vector table in HEX (default: 0x80)')

    parser.add_argument('--pad', required=False, \
                        help='Pad file with 0xff up to this size (in hex)')

    parser.add_argument('--bit', required=False, action="store_true", \
                        default=False, \
                        help='Whether to add the Boot Image Trailer to the \
                        padded image or not (default: False)')

    parser.add_argument('--verbose', required=False, action="store_true", \
                        default=False, \
                        help='Enable verbose mode')

    parser.add_argument('--version', action='version', version='%(prog)s 1.0')

    parser.add_argument('-f', required=False, action="store_true", \
                        default=False, \
                        help='Flash using JLinkExe')
    parser.add_argument('--image-version', dest='image_version',
            default=1,
            help='Major part of version number')

    return parser.parse_args()

def trailer_size(word_size):
    """
    Compute the size of the image trailer.

    The image trailer size depends on the writable unit size of the
    flash in question.  Given a word size of 1, 2, 4 or 8, return the
    size, in bytes, of the image trailer.  The magic number should be
    placed at this particular offset from the end of the segment
    """
    sizes = { 1: 402, 2: 788, 4: 1560, 8: 3104 }
    return sizes[word_size]

class Signature(object):
    """
    Sign an image appropriately.
    """

    def compute(self, payload, key_file):
        # Base computes sha256.
        ctx = SHA256.new()
        ctx.update(payload)
        self.hash = ctx.digest()
        self.ctx = ctx

    def get_trailer(self):
        return struct.pack('bxh32s', newtimg.IMAGE_TLV_SHA256,
                len(self.hash),
                self.hash)

    def trailer_len(self):
        return 32 + 4

    def get_flags(self):
        return newtimg.IMAGE_F_SHA256

class RSASignature(Signature):

    def compute(self, payload, key_file):
        super(RSASignature, self).compute(payload, key_file)
        with open(key_file, 'rb') as f:
            rsa_key = RSA.importKey(f.read())
        rsa = PKCS1_v1_5.new(rsa_key)
        self.signature = rsa.sign(self.ctx)

    def trailer_len(self):
        return super(RSASignature, self).trailer_len() + newtimg.RSA_SIZE

    def get_trailer(self):
        buf = bytearray(super(RSASignature, self).get_trailer())
        buf.extend(struct.pack('bxh', newtimg.IMAGE_TLV_RSA2048,
                newtimg.RSA_SIZE))
        buf.extend(self.signature)
        return buf

    def get_flags(self):
        return newtimg.IMAGE_F_PKCS15_RSA2048_SHA256 | newtimg.IMAGE_F_SHA256

sigs = {
        'SHA256': Signature,
        'RSA': RSASignature,
        }

class Convert():
    def __init__(self, args):
        self.args = args
        if args.verbose:
            for a in vars(args):
                print("Arg -> {}: {}".format(a, getattr(args, a)))
            self.debug = True
        else:
            self.debug = False

        self.vtable_offs = int(args.vtable_offs, 16)
        self.word_size = int(args.word_size)

        self.load_image(args.binary_file)
        self.validate_header()

        sig = sigs[args.sig_type]()
        header = self.make_header(sig)
        assert len(header) == 32
        self.image[:len(header)] = header

        sig.compute(self.image, args.key_file)
        self.trailer = sig.get_trailer()

        self.image.extend(self.trailer)

        if args.bit:
            self.add_trailer(args.pad)

        self.save_image(args.image_file)

    def load_image(self, name):
        with open(name, 'rb') as f:
            image = f.read()
        self.image = bytearray(image)

    def save_image(self, name):
        with open(name, 'wb') as f:
            f.write(self.image)

    def validate_header(self):
        """Ensure that the image has space for a header

        If the image is build with CONFIG_BOOT_HEADER off, the vector
        table will be at the beginning, rather than the zero padding.
        Verify that the padding is present.
        """

        size = self.vtable_offs

        # First test: check if padded with all zeroes (ARM)
        expected = bytearray(size)
        if self.image[:size] == expected:
            return

        # x86 has a repeating pattern of 0x66 0x90
        for i in range(0, size, 2):
            expected[i] = 0x66
            expected[i + 1] = 0x90

        if self.image[:size] == expected:
            return

        raise Exception("Image does not have space for header")

    def make_header(self, sig):
        image_size = len(self.image) - self.vtable_offs
        tlv_size = sig.trailer_len()
        key_id = 0
        hd = struct.pack('IHBxHxxIIBBHI4x',
                newtimg.IMAGE_MAGIC,
                tlv_size,
                key_id,
                self.vtable_offs,
                image_size,
                sig.get_flags(),
                int(self.args.image_version), 0, 0, 0)
        return hd

    def add_trailer(self, pad):
        """
        Add the image trailer, to indicate to the bootloader that this
        image should be flashed
        """
        if not pad:
            raise Exception("Must specify image length with --pad to use --bit")
        pad = int(pad, 16)

        if len(self.image) > pad:
            raise Exception("Image is too large for padding")

        self.image.extend(b'\xFF' * (pad - len(self.image)))

        magic = struct.pack('4I', *newtimg.BOOT_IMG_MAGIC)
        pos = pad - trailer_size(self.word_size)
        self.image[pos:pos + len(magic)] = magic

def main(argv):
    args = get_args()

    conv = Convert(args)

if __name__ == "__main__":
    main(sys.argv)
