Boot: Introduce new protected TLV format

Introduce new protected TLV format in MCUBoot as part of a partial
synchronization with the mainstream MCUBoot repository. The hash of the
source commit: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4.

Adapt image.py Python script to the new TLV format.

Change-Id: I760927cea3fbc66536623c1ed6606debb97a2e74
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
index d89ec99..d790a75 100644
--- a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
+++ b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
@@ -47,6 +47,7 @@
 
 TLV_INFO_SIZE = 4
 TLV_INFO_MAGIC = 0x6907
+TLV_PROT_INFO_MAGIC = 0x6908
 
 # Sizes of the image trailer, depending on flash write size.
 trailer_sizes = {
@@ -61,17 +62,25 @@
     0x2c, 0xb6, 0x79, 0x80, ])
 
 class TLV():
-    def __init__(self):
+    def __init__(self, magic=TLV_INFO_MAGIC):
+        self.magic = magic
         self.buf = bytearray()
 
+    def __len__(self):
+        return TLV_INFO_SIZE + len(self.buf)
+
     def add(self, kind, payload):
-        """Add a TLV record.  Kind should be a string found in TLV_VALUES above."""
+        """
+        Add a TLV record.  Kind should be a string found in TLV_VALUES above.
+        """
         buf = struct.pack('<BBH', TLV_VALUES[kind], 0, len(payload))
         self.buf += buf
         self.buf += payload
 
     def get(self):
-        header = struct.pack('<HH', TLV_INFO_MAGIC, TLV_INFO_SIZE + len(self.buf))
+        if len(self.buf) == 0:
+            return bytes()
+        header = struct.pack('<HH', self.magic, len(self))
         return header + bytes(self.buf)
 
 class Image():
@@ -160,13 +169,17 @@
             dependencies_num = len(dependencies[DEP_IMAGES_KEY])
             protected_tlv_size += (dependencies_num * 16)
 
+        # At this point the image is already on the payload, this adds
+        # the header to the payload as well
         self.add_header(key, protected_tlv_size, ramLoadAddress)
 
-        tlv = TLV()
+        prot_tlv = TLV(TLV_PROT_INFO_MAGIC)
 
+        # Protected TLVs must be added first, because they are also included
+        # in the hash calculation
         payload = struct.pack('I', self.security_cnt)
-        tlv.add('SEC_CNT', payload)
-        tlv.add('BOOT_RECORD', boot_record)
+        prot_tlv.add('SEC_CNT', payload)
+        prot_tlv.add('BOOT_RECORD', boot_record)
 
         if dependencies_num != 0:
             for i in range(dependencies_num):
@@ -178,27 +191,16 @@
                                 dependencies[DEP_VERSIONS_KEY][i].revision,
                                 dependencies[DEP_VERSIONS_KEY][i].build
                                 )
-                tlv.add('DEPENDENCY', payload)
+                prot_tlv.add('DEPENDENCY', payload)
 
-        # Full TLV size needs to be calculated in advance, because the
-        # header will be protected as well
-        full_size = (TLV_INFO_SIZE + len(tlv.buf) + TLV_HEADER_SIZE
-                     + PAYLOAD_DIGEST_SIZE)
-        if key is not None:
-            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)
+        self.payload += prot_tlv.get()
 
         sha = hashlib.sha256()
         sha.update(self.payload)
         image_hash = sha.digest()
 
+        tlv = TLV()
+
         tlv.add('SHA256', image_hash)
 
         if key is not None:
@@ -210,7 +212,7 @@
             sig = key.sign(self.payload)
             tlv.add(key.sig_tlv(), sig)
 
-        self.payload += tlv.get()[protected_tlv_size:]
+        self.payload += tlv.get()
 
     def add_header(self, key, protected_tlv_size, ramLoadAddress):
         """Install the image header.
@@ -240,9 +242,9 @@
                 IMAGE_MAGIC,
                 0 if (ramLoadAddress is None) else ramLoadAddress, # LoadAddr
                 self.header_size,
-                protected_tlv_size,  # TLV info header + SC TLV (+ DEP. TLVs)
-                len(self.payload) - self.header_size, # ImageSz
-                flags, # Flags
+                protected_tlv_size,  # TLV info header + Protected TLVs
+                len(self.payload) - self.header_size,  # ImageSz
+                flags,
                 self.version.major,
                 self.version.minor or 0,
                 self.version.revision or 0,