Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index 6680b4f..61d56a2 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2020 Linaro LTD
+// Copyright (c) 2017-2021 Linaro LTD
 // Copyright (c) 2017-2020 JUUL Labs
 // Copyright (c) 2021 Arm Limited
 //
@@ -67,8 +67,8 @@
     PIC = 0x01,
     NON_BOOTABLE = 0x02,
     ENCRYPTED_AES128 = 0x04,
-    RAM_LOAD = 0x20,
     ENCRYPTED_AES256 = 0x08,
+    RAM_LOAD = 0x20,
 }
 
 /// A generator for manifests.  The format of the manifest can be either a
@@ -96,6 +96,11 @@
     /// corrupt the signature.
     fn corrupt_sig(&mut self);
 
+    /// Estimate the size of the TLV.  This can be called before the payload is added (but after
+    /// other information is added).  Some of the signature algorithms can generate variable sized
+    /// data, and therefore, this can slightly overestimate the size.
+    fn estimate_size(&self) -> usize;
+
     /// Construct the manifest for this payload.
     fn make_tlv(self: Box<Self>) -> Vec<u8>;
 
@@ -332,8 +337,67 @@
         self.gen_corrupted = true;
     }
 
+    fn estimate_size(&self) -> usize {
+        // Begin the estimate with the 4 byte header.
+        let mut estimate = 4;
+        // A very poor estimate.
+
+        // Estimate the size of the image hash.
+        if self.kinds.contains(&TlvKinds::SHA256) {
+            estimate += 4 + 32;
+        }
+
+        // Add an estimate in for each of the signature algorithms.
+        if self.kinds.contains(&TlvKinds::RSA2048) {
+            estimate += 4 + 32; // keyhash
+            estimate += 4 + 256; // RSA2048
+        }
+        if self.kinds.contains(&TlvKinds::RSA3072) {
+            estimate += 4 + 32; // keyhash
+            estimate += 4 + 384; // RSA3072
+        }
+        if self.kinds.contains(&TlvKinds::ECDSA256) {
+            estimate += 4 + 32; // keyhash
+
+            // ECDSA signatures are encoded as ASN.1 with the x and y values stored as signed
+            // integers.  As such, the size can vary by 2 bytes, if the 256-bit value has the high
+            // bit, it takes an extra 0 byte to avoid it being seen as a negative number.
+            estimate += 4 + 72; // ECDSA256 (varies)
+        }
+        if self.kinds.contains(&TlvKinds::ED25519) {
+            estimate += 4 + 32; // keyhash
+            estimate += 4 + 64; // ED25519 signature.
+        }
+
+        // Estimate encryption.
+        let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+        let aes256 = (self.get_flags() & flag) == flag;
+
+        if self.kinds.contains(&TlvKinds::ENCRSA2048) {
+            estimate += 4 + 256;
+        }
+        if self.kinds.contains(&TlvKinds::ENCKW) {
+            estimate += 4 + if aes256 { 40 } else { 24 };
+        }
+        if self.kinds.contains(&TlvKinds::ENCEC256) {
+            estimate += 4 + if aes256 { 129 } else { 113 };
+        }
+        if self.kinds.contains(&TlvKinds::ENCX25519) {
+            estimate += 4 + if aes256 { 96 } else { 80 };
+        }
+
+        // Gather the size of the dependency information.
+        if self.protect_size() > 0 {
+            estimate += 4 + (16 * self.dependencies.len());
+        }
+
+        estimate
+    }
+
     /// Compute the TLV given the specified block of data.
     fn make_tlv(self: Box<Self>) -> Vec<u8> {
+        let size_estimate = self.estimate_size();
+
         let mut protected_tlv: Vec<u8> = vec![];
 
         if self.protect_size() > 0 {
@@ -663,6 +727,25 @@
         let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4];
         size_buf.write_u16::<LittleEndian>(size).unwrap();
 
+        // ECDSA is stored as an ASN.1 integer.  For a 128-bit value, this maximally results in 33
+        // bytes of storage for each of the two values.  If the high bit is zero, it will take 32
+        // bytes, if the top 8 bits are zero, it will take 31 bits, and so on.  The smaller size
+        // will occur with decreasing likelihood.  We'll allow this to get a bit smaller, hopefully
+        // allowing the tests to pass with false failures rare.  For this case, we'll handle up to
+        // the top 16 bits of both numbers being all zeros (1 in 2^32).
+        if !Caps::has_ecdsa() {
+            if size_estimate != result.len() {
+                panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len());
+            }
+        } else {
+            if size_estimate < result.len() || size_estimate > result.len() + 6 {
+                panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len());
+            }
+        }
+        if size_estimate != result.len() {
+            log::warn!("Size off: {} actual {}", size_estimate, result.len());
+        }
+
         result
     }