Boot: Add hardware key handling to signing script

Add an optional command line parameter to image signing script
to distinguish where the public key is stored for image
authentication: embedded in MCUBoot or in the image manifest.

Change-Id: I75542e2ee7138e8b2e3891c78293283c0839e81b
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/ext/mcuboot/scripts/imgtool.py b/bl2/ext/mcuboot/scripts/imgtool.py
index 3b6e874..1b539c2 100644
--- a/bl2/ext/mcuboot/scripts/imgtool.py
+++ b/bl2/ext/mcuboot/scripts/imgtool.py
@@ -110,7 +110,7 @@
                            security_cnt=args.security_counter,
                            included_header=args.included_header,
                            pad=pad_size)
-    key = keys.load(args.key) if args.key else None
+    key = keys.load(args.key, args.public_key_format) if args.key else None
     ram_load_address = macro_parser.evaluate_macro(args.layout, image_load_address_re, 0, 1)
     img.sign(key, ram_load_address, args.dependencies)
 
@@ -178,6 +178,9 @@
     sign.add_argument('-l', '--layout', required=True,
                       help='Location of the file that contains preprocessed macros')
     sign.add_argument('-k', '--key', metavar='filename')
+    sign.add_argument("-K", "--public-key-format",
+                      help='In what format to add the public key to the image manifest: full or hash',
+                      metavar='pub_key_format', choices=['full', 'hash'], default='hash')
     sign.add_argument("--align", type=alignment_value, required=True)
     sign.add_argument("-v", "--version", type=version.decode_version,
                       default="0.0.0+0")
diff --git a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
index f64ad4c..cb97a35 100644
--- a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
+++ b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
@@ -36,6 +36,7 @@
         'RAM_LOAD':              0x0000020, }
 TLV_VALUES = {
         'KEYHASH': 0x01,
+        'KEY'    : 0x02,
         'SHA256' : 0x10,
         'RSA2048': 0x20,
         'RSA3072': 0x23,
@@ -152,7 +153,13 @@
         full_size = (TLV_INFO_SIZE + len(tlv.buf) + TLV_HEADER_SIZE
                      + PAYLOAD_DIGEST_SIZE)
         if key is not None:
-            full_size += (TLV_HEADER_SIZE + KEYHASH_SIZE
+            pub = key.get_public_bytes()
+            if key.get_public_key_format() == 'hash':
+                tlv_key_data_size = KEYHASH_SIZE
+            else:
+                tlv_key_data_size = len(pub)
+
+            full_size += (TLV_HEADER_SIZE + tlv_key_data_size
                           + TLV_HEADER_SIZE + key.sig_len())
         tlv_header = struct.pack('HH', TLV_INFO_MAGIC, full_size)
         self.payload += tlv_header + bytes(tlv.buf)
@@ -164,11 +171,13 @@
         tlv.add('SHA256', digest)
 
         if key is not None:
-            pub = key.get_public_bytes()
-            sha = hashlib.sha256()
-            sha.update(pub)
-            pubbytes = sha.digest()
-            tlv.add('KEYHASH', pubbytes)
+            if key.get_public_key_format() == 'hash':
+                sha = hashlib.sha256()
+                sha.update(pub)
+                pubbytes = sha.digest()
+                tlv.add('KEYHASH', pubbytes)
+            else:
+                tlv.add('KEY', pub)
 
             sig = key.sign(self.payload)
             tlv.add(key.sig_tlv(), sig)
diff --git a/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py b/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
index f17f173..b652d90 100644
--- a/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
+++ b/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
@@ -43,13 +43,17 @@
             namedtype.NamedType('publicExponent', univ.Integer()))
 
 class RSAutil():
-    def __init__(self, key):
+    def __init__(self, key, public_key_format='hash'):
         """Construct an RSA key with the given key data"""
         self.key = key
+        self.public_key_format = public_key_format
 
     def key_size(self):
         return self.key.n.bit_length()
 
+    def get_public_key_format(self):
+        return self.public_key_format
+
     @staticmethod
     def generate(key_size=2048):
         if key_size not in RSA_KEY_SIZES:
@@ -104,11 +108,11 @@
         assert len(signature) == self.sig_len()
         return signature
 
-def load(path):
+def load(path, public_key_format='hash'):
     with open(path, 'rb') as f:
         pem = f.read()
     try:
         key = RSA.importKey(pem)
-        return RSAutil(key)
+        return RSAutil(key, public_key_format)
     except ValueError:
         raise Exception("Unsupported RSA key file")