sim: Validate the SHA256 verification

Instead of stubbing out the image validation code, compile it, and add
the SHA256 TLV to the buffer.

Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/src/main.rs b/sim/src/main.rs
index dfebea7..aa7c75d 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -1,5 +1,8 @@
 #[macro_use] extern crate log;
+extern crate crypto;
 extern crate env_logger;
+extern crate enumflags;
+#[macro_use] extern crate enumflags_derive;
 extern crate docopt;
 extern crate libc;
 extern crate rand;
@@ -19,10 +22,12 @@
 mod c;
 pub mod api;
 mod caps;
+mod tlv;
 
 use simflash::{Flash, SimFlash};
 use area::{AreaDesc, FlashId};
 use caps::Caps;
+use tlv::TlvGen;
 
 const USAGE: &'static str = "
 Mcuboot simulator
@@ -124,7 +129,7 @@
     }
 
     if status.failures > 0 {
-        warn!("{} Tests ran with {} failures", status.failures + status.passes, status.failures);
+        error!("{} Tests ran with {} failures", status.failures + status.passes, status.failures);
         process::exit(1);
     } else {
         warn!("{} Tests ran successfully", status.passes);
@@ -597,16 +602,18 @@
 fn install_image(flash: &mut Flash, offset: usize, len: usize) -> Vec<u8> {
     let offset0 = offset;
 
+    let mut tlv = TlvGen::new_hash_only();
+
     // Generate a boot header.  Note that the size doesn't include the header.
     let header = ImageHeader {
         magic: 0x96f3b83c,
-        tlv_size: 0,
+        tlv_size: tlv.get_size(),
         _pad1: 0,
         hdr_size: 32,
         key_id: 0,
         _pad2: 0,
         img_size: len as u32,
-        flags: 0,
+        flags: tlv.get_flags(),
         ver: ImageVersion {
             major: (offset / (128 * 1024)) as u8,
             minor: 0,
@@ -617,6 +624,7 @@
     };
 
     let b_header = header.as_raw();
+    tlv.add_bytes(&b_header);
     /*
     let b_header = unsafe { slice::from_raw_parts(&header as *const _ as *const u8,
                                                   mem::size_of::<ImageHeader>()) };
@@ -628,6 +636,16 @@
     // The core of the image itself is just pseudorandom data.
     let mut buf = vec![0; len];
     splat(&mut buf, offset);
+    tlv.add_bytes(&buf);
+
+    // Get and append the TLV itself.
+    buf.append(&mut tlv.make_tlv());
+
+    // Pad the block to a flash alignment (8 bytes).
+    while buf.len() % 8 != 0 {
+        buf.push(0xFF);
+    }
+
     flash.write(offset, &buf).unwrap();
     let offset = offset + buf.len();
 
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
new file mode 100644
index 0000000..071af0c
--- /dev/null
+++ b/sim/src/tlv.rs
@@ -0,0 +1,91 @@
+//! TLV Support
+//!
+//! mcuboot images are followed immediately by a list of TLV items that contain integrity
+//! information about the image.  Their generation is made a little complicated because the size of
+//! the TLV block is in the image header, which is included in the hash.  Since some signatures can
+//! vary in size, we just make them the largest size possible.
+//!
+//! Because of this header, we have to make two passes.  The first pass will compute the size of
+//! the TLV, and the second pass will build the data for the TLV.
+
+use crypto::digest::Digest;
+use crypto::sha2::Sha256;
+
+#[derive(EnumFlags, Copy, Clone, Debug)]
+#[repr(u32)]
+#[allow(non_camel_case_types)]
+pub enum Flags {
+    PIC = 0x000001,
+    SHA256 = 0x000002,
+    PKCS15_RSA2048_SHA256 = 0x000004,
+    ECDSA224_SHA256 = 0x000008,
+    NON_BOOTABLE = 0x000010,
+    ECDSA256_SHA256 = 0x000020,
+    PKCS1_PSS_RSA2048_SHA256 = 0x000040,
+}
+
+#[repr(u8)]
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[allow(dead_code)] // TODO: For now
+pub enum TlvKinds {
+    SHA256 = 1,
+    RSA2048 = 2,
+    ECDSA224 = 3,
+    ECDSA256 = 4,
+}
+
+pub struct TlvGen {
+    flags: Flags,
+    kinds: Vec<TlvKinds>,
+    size: u16,
+    hasher: Sha256,
+}
+
+impl TlvGen {
+    /// Construct a new tlv generator that will only contain a hash of the data.
+    pub fn new_hash_only() -> TlvGen {
+        TlvGen {
+            flags: Flags::SHA256,
+            kinds: vec![TlvKinds::SHA256],
+            size: 4 + 32,
+            hasher: Sha256::new(),
+        }
+    }
+
+    /// Retrieve the header flags for this configuration.  This can be called at any time.
+    pub fn get_flags(&self) -> u32 {
+        self.flags as u32
+    }
+
+    /// Retrieve the size that the TLV will occupy.  This can be called at any time.
+    pub fn get_size(&self) -> u16 {
+        self.size
+    }
+
+    /// Add bytes to the covered hash.
+    pub fn add_bytes(&mut self, bytes: &[u8]) {
+        self.hasher.input(bytes);
+    }
+
+    /// Compute the TLV given the specified block of data.
+    pub fn make_tlv(mut self) -> Vec<u8> {
+        let mut result: Vec<u8> = vec![];
+
+        if self.kinds.contains(&TlvKinds::SHA256) {
+            let hash_size = self.hasher.output_bytes();
+            assert!(hash_size == 32); // Assumption made.
+
+            let mut hash = vec![0; hash_size];
+
+            self.hasher.result(&mut hash);
+
+            result.push(TlvKinds::SHA256 as u8);
+            result.push(0);
+            result.push(32);
+            result.push(0);
+            result.append(&mut hash);
+        }
+
+        result
+    }
+}