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/bootutil/include/bootutil/image.h b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
index f79c77b..2b3163b 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
@@ -40,6 +40,7 @@
 #define IMAGE_MAGIC_V1              0x96f3b83c
 #define IMAGE_MAGIC_NONE            0xffffffff
 #define IMAGE_TLV_INFO_MAGIC        0x6907
+#define IMAGE_TLV_PROT_INFO_MAGIC   0x6908
 
 #define IMAGE_HEADER_SIZE           32
 
@@ -136,7 +137,7 @@
     const struct flash_area *fap;
     uint8_t type;
     bool prot;
-    uint32_t prot_len;
+    uint32_t prot_end;
     uint32_t tlv_off;
     uint32_t tlv_end;
 };
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h b/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
index f903c46..763097d 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
@@ -27,7 +27,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
index 870420e..e295fa8 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
index b577e41..5d5e19d 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/bootutil/src/image_rsa.c b/bl2/ext/mcuboot/bootutil/src/image_rsa.c
index 0a05a6a..9aaf403 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_rsa.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_rsa.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/bootutil/src/image_validate.c b/bl2/ext/mcuboot/bootutil/src/image_validate.c
index 83bf50e..3b18010 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_validate.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_validate.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
@@ -77,12 +77,8 @@
     /* Hash is computed over image header and image itself. */
     size = BOOT_TLV_OFF(hdr);
 
-    /* If protected TLVs are present (e.g. security counter TLV) then the
-     * TLV info header and these TLVs must be included in the hash calculation.
-     */
-    if (hdr->ih_protect_tlv_size != 0) {
-        size += hdr->ih_protect_tlv_size;
-    }
+    /* If protected TLVs are present they are also hashed. */
+    size += hdr->ih_protect_tlv_size;
 
 #ifdef MCUBOOT_RAM_LOADING
     bootutil_sha256_update(&sha256_ctx,(void*)(hdr->ih_load_addr), size);
diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c
index c2b1b5f..ab25e43 100644
--- a/bl2/ext/mcuboot/bootutil/src/loader.c
+++ b/bl2/ext/mcuboot/bootutil/src/loader.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
@@ -545,6 +545,7 @@
     const struct flash_area *fap = NULL;
     struct image_tlv_info info;
     uint32_t off;
+    uint32_t protect_tlv_size;
     int area_id;
     int rc;
 
@@ -566,12 +567,28 @@
         goto done;
     }
 
+    protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size;
+    if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
+        if (protect_tlv_size != info.it_tlv_tot) {
+            rc = BOOT_EBADIMAGE;
+            goto done;
+        }
+
+        if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) {
+            rc = BOOT_EFLASH;
+            goto done;
+        }
+    } else if (protect_tlv_size != 0) {
+        rc = BOOT_EBADIMAGE;
+        goto done;
+    }
+
     if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
         rc = BOOT_EBADIMAGE;
         goto done;
     }
 
-    *size = off + info.it_tlv_tot;
+    *size = off + protect_tlv_size + info.it_tlv_tot;
     rc = 0;
 
 done:
diff --git a/bl2/ext/mcuboot/bootutil/src/tlv.c b/bl2/ext/mcuboot/bootutil/src/tlv.c
index 5d3d32c..3665e82 100644
--- a/bl2/ext/mcuboot/bootutil/src/tlv.c
+++ b/bl2/ext/mcuboot/bootutil/src/tlv.c
@@ -49,6 +49,19 @@
         return -1;
     }
 
+    if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
+        if (hdr->ih_protect_tlv_size != info.it_tlv_tot) {
+            return -1;
+        }
+
+        if (LOAD_IMAGE_DATA(hdr, fap, off_ + info.it_tlv_tot,
+                            &info, sizeof(info))) {
+            return -1;
+        }
+    } else if (hdr->ih_protect_tlv_size != 0) {
+        return -1;
+    }
+
     if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
         return -1;
     }
@@ -57,10 +70,10 @@
     it->fap = fap;
     it->type = type;
     it->prot = prot;
-    off_ += sizeof(info);
-    it->tlv_off = off_;
-    it->prot_len = off_ + it->hdr->ih_protect_tlv_size;
-    it->tlv_end = off_ + info.it_tlv_tot;
+    it->prot_end = off_ + it->hdr->ih_protect_tlv_size;
+    it->tlv_end = off_ + it->hdr->ih_protect_tlv_size + info.it_tlv_tot;
+    // position on first TLV
+    it->tlv_off = off_ + sizeof(info);
     return 0;
 }
 
@@ -88,13 +101,17 @@
     }
 
     while (it->tlv_off < it->tlv_end) {
+        if (it->hdr->ih_protect_tlv_size > 0 && it->tlv_off == it->prot_end) {
+            it->tlv_off += sizeof(struct image_tlv_info);
+        }
+
         rc = LOAD_IMAGE_DATA(it->hdr, it->fap, it->tlv_off, &tlv, sizeof tlv);
         if (rc) {
             return -1;
         }
 
         /* No more TLVs in the protected area */
-        if (it->prot && it->tlv_off >= it->prot_len) {
+        if (it->prot && it->tlv_off >= it->prot_end) {
             return 1;
         }
 
diff --git a/bl2/ext/mcuboot/flash_map_extended.c b/bl2/ext/mcuboot/flash_map_extended.c
index aa56d8b..2f0c8ad 100644
--- a/bl2/ext/mcuboot/flash_map_extended.c
+++ b/bl2/ext/mcuboot/flash_map_extended.c
@@ -9,7 +9,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  */
 
 #include <errno.h>
diff --git a/bl2/ext/mcuboot/flash_map_legacy.c b/bl2/ext/mcuboot/flash_map_legacy.c
index bbf800e..bdcf44b 100644
--- a/bl2/ext/mcuboot/flash_map_legacy.c
+++ b/bl2/ext/mcuboot/flash_map_legacy.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/include/config-rsa.h b/bl2/ext/mcuboot/include/config-rsa.h
index 934ab24..7082268 100644
--- a/bl2/ext/mcuboot/include/config-rsa.h
+++ b/bl2/ext/mcuboot/include/config-rsa.h
@@ -24,7 +24,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  */
 
 /*
diff --git a/bl2/ext/mcuboot/include/flash_map/flash_map.h b/bl2/ext/mcuboot/include/flash_map/flash_map.h
index 16b516d..44dc1f9 100644
--- a/bl2/ext/mcuboot/include/flash_map/flash_map.h
+++ b/bl2/ext/mcuboot/include/flash_map/flash_map.h
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2018-2019 Arm Limited.
  */
 
diff --git a/bl2/ext/mcuboot/include/target.h b/bl2/ext/mcuboot/include/target.h
index a82ed27..0e1a211 100644
--- a/bl2/ext/mcuboot/include/target.h
+++ b/bl2/ext/mcuboot/include/target.h
@@ -8,7 +8,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  */
 
 #ifndef H_TARGETS_TARGET_
diff --git a/bl2/ext/mcuboot/keys.c b/bl2/ext/mcuboot/keys.c
index 6d6ec6a..0640cdc 100644
--- a/bl2/ext/mcuboot/keys.c
+++ b/bl2/ext/mcuboot/keys.c
@@ -20,7 +20,7 @@
 /*
  * Original code taken from mcuboot project at:
  * https://github.com/JuulLabs-OSS/mcuboot
- * Git SHA of the original version: 61fd888a7f4d741714553f36839dd49fb0065731
+ * Git SHA of the original version: 510fddb8e06d76e2442b2a4603d3e1cbefe28be4
  * Modifications are Copyright (c) 2019 Arm Limited.
  */
 
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,