imgtool: export data vector to be signed

Extend sign/create command so it allows to export image's byte string
which is the substrate for the image signature. The new option is
'--vector-to-sign'. It might takes 'payload' or 'digest'.
The exported data might be used to calculate the signature externally.

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py
index 834ec9d..e97810e 100644
--- a/scripts/imgtool/image.py
+++ b/scripts/imgtool/image.py
@@ -305,7 +305,7 @@
         return cipherkey, ciphermac, pubk
 
     def create(self, key, public_key_format, enckey, dependencies=None,
-               sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None):
+               sw_type=None, custom_tlvs=None, encrypt_keylen=128, clear=False, fixed_sig=None, pub_key=None, vector_to_sign=None):
         self.enckey = enckey
 
         # Calculate the hash of the public key
@@ -315,6 +315,8 @@
             sha.update(pub)
             pubbytes = sha.digest()
         elif pub_key is not None:
+            if hasattr(pub_key, 'sign'):
+                print("sign the payload")
             pub = pub_key.get_public_bytes()
             sha = hashlib.sha256()
             sha.update(pub)
@@ -433,26 +435,34 @@
 
         tlv.add('SHA256', digest)
 
-        if key is not None and fixed_sig is None:
-            if public_key_format == 'hash':
-                tlv.add('KEYHASH', pubbytes)
-            else:
-                tlv.add('PUBKEY', pub)
+        if public_key_format == 'hash':
+            tlv.add('KEYHASH', pubbytes)
+        else:
+            tlv.add('PUBKEY', pub)
 
+        if vector_to_sign == 'payload':
+            # Stop amending data to the image
+            # Just keep data vector which is expected to be sigend
+            print('export payload')
+            return
+        elif vector_to_sign == 'digest':
+            self.payload = digest
+            print('export digest')
+            return
+
+        if key is not None and fixed_sig is None:
             # `sign` expects the full image payload (sha256 done internally),
             # while `sign_digest` expects only the digest of the payload
 
             if hasattr(key, 'sign'):
+                print("sign the payload")
                 sig = key.sign(bytes(self.payload))
             else:
+                print("sign the digest")
                 sig = key.sign_digest(digest)
             tlv.add(key.sig_tlv(), sig)
             self.signature = sig
         elif fixed_sig is not None and key is None:
-            if public_key_format == 'hash':
-                tlv.add('KEYHASH', pubbytes)
-            else:
-                tlv.add('PUBKEY', pub)
             tlv.add(pub_key.sig_tlv(), fixed_sig['value'])
             self.signature = fixed_sig['value']
         else:
diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py
index 920df78..ea95bad 100755
--- a/scripts/imgtool/main.py
+++ b/scripts/imgtool/main.py
@@ -321,6 +321,10 @@
 @click.option('--sig-out', metavar='filename',
               help='Path to the file to which signature will be written'
               'The image signature will be encoded as base64 formatted string')
+@click.option('--vector-to-sign', type=click.Choice(['payload', 'digest']),
+              help='send to OUTFILE the payload or payload''s digest instead of'
+              'complied image. These data can be used for external image'
+              'signing')
 @click.command(help='''Create a signed or unsigned image\n
                INFILE and OUTFILE are parsed as Intel HEX if the params have
                .hex extension, otherwise binary format is used''')
@@ -329,7 +333,7 @@
          endian, encrypt_keylen, encrypt, infile, outfile, dependencies,
          load_addr, hex_addr, erased_val, save_enctlv, security_counter,
          boot_record, custom_tlv, rom_fixed, max_align, clear, fix_sig,
-         fix_sig_pubkey, sig_out):
+         fix_sig_pubkey, sig_out, vector_to_sign):
 
     if confirm:
         # Confirmed but non-padded images don't make much sense, because
@@ -393,7 +397,8 @@
         }
 
     img.create(key, public_key_format, enckey, dependencies, boot_record,
-               custom_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key)
+               custom_tlvs, int(encrypt_keylen), clear, baked_signature, pub_key,
+               vector_to_sign)
     img.save(outfile, hex_addr)
 
     if sig_out is not None: