sim: Compute TLV size from actual size

Instead of having lots of magic numbers to try and track the resulting
size of the TLV, just determine the size we end up with after encoding
it.  The only place the size is used is in the header within the TLV
itself.  Make this work by putting a placeholder in the TLV, and then
patching the value back after we know the full size.

In addition to removing a lot of magic numbers from the code, this will
make it easier to handle things that vary in size, such as X.509
certificates.

Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index ad53c27..fa2fa7e 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -98,8 +98,6 @@
 pub struct TlvGen {
     flags: u32,
     kinds: Vec<TlvKinds>,
-    /// The total size of the payload.
-    size: u16,
     payload: Vec<u8>,
     dependencies: Vec<Dependency>,
     enc_key: Vec<u8>,
@@ -121,7 +119,6 @@
     pub fn new_hash_only() -> TlvGen {
         TlvGen {
             kinds: vec![TlvKinds::SHA256],
-            size: 4 + 32,
             ..Default::default()
         }
     }
@@ -130,7 +127,6 @@
     pub fn new_rsa_pss() -> TlvGen {
         TlvGen {
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048],
-            size: 4 + 32 + 4 + 32 + 4 + 256,
             ..Default::default()
         }
     }
@@ -139,7 +135,6 @@
     pub fn new_rsa3072_pss() -> TlvGen {
         TlvGen {
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA3072],
-            size: 4 + 32 + 4 + 32 + 4 + 384,
             ..Default::default()
         }
     }
@@ -148,7 +143,6 @@
     pub fn new_ecdsa() -> TlvGen {
         TlvGen {
             kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256],
-            size: 4 + 32 + 4 + 32 + 4 + 72,
             ..Default::default()
         }
     }
@@ -157,7 +151,6 @@
     pub fn new_ed25519() -> TlvGen {
         TlvGen {
             kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519],
-            size: 4 + 32 + 4 + 32 + 4 + 64,
             ..Default::default()
         }
     }
@@ -167,7 +160,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
-            size: 4 + 32 + 4 + 256,
             ..Default::default()
         }
     }
@@ -177,7 +169,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048],
-            size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 256,
             ..Default::default()
         }
     }
@@ -187,7 +178,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW128],
-            size: 4 + 32 + 4 + 24,
             ..Default::default()
         }
     }
@@ -197,7 +187,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW128],
-            size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 24,
             ..Default::default()
         }
     }
@@ -207,7 +196,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW128],
-            size: 4 + 32 + 4 + 32 + 4 + 72 + 4 + 24,
             ..Default::default()
         }
     }
@@ -217,7 +205,6 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCEC256],
-            size: 4 + 32 + 4 + 32 + 4 + 113,
             ..Default::default()
         }
     }
@@ -227,15 +214,9 @@
         TlvGen {
             flags: TlvFlags::ENCRYPTED as u32,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCEC256],
-            size: 4 + 32 + 4 + 32 + 4 + 72 + 4 + 113,
             ..Default::default()
         }
     }
-
-    /// Retrieve the size that the TLV will occupy.  This can be called at any time.
-    pub fn get_size(&self) -> u16 {
-        4 + self.size
-    }
 }
 
 impl ManifestGen for TlvGen {
@@ -263,8 +244,6 @@
     }
 
     fn add_dependency(&mut self, id: u8, version: &ImageVersion) {
-        let my_size = 4 + 4 + 8;
-        self.size += my_size;
         self.dependencies.push(Dependency {
             id: id,
             version: version.clone(),
@@ -318,9 +297,11 @@
         result.extend_from_slice(&protected_tlv);
 
         // add non-protected payload
+        let npro_pos = result.len();
         result.push(0x07);
         result.push(0x69);
-        result.write_u16::<LittleEndian>(self.get_size()).unwrap();
+        // Placeholder for the size.
+        result.write_u16::<LittleEndian>(0).unwrap();
 
         if self.kinds.contains(&TlvKinds::SHA256) {
             // If a signature is not requested, corrupt the hash we are
@@ -564,6 +545,11 @@
             result.extend_from_slice(&buf);
         }
 
+        // Patch the size back into the TLV header.
+        let size = (result.len() - npro_pos) as u16;
+        let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4];
+        size_buf.write_u16::<LittleEndian>(size).unwrap();
+
         result
     }