Sim: Add testcases for AES256 image encryption

Signed-off-by: Salome Thirot <salome.thirot@arm.com>
diff --git a/sim/src/caps.rs b/sim/src/caps.rs
index 1d9a612..4af8bd0 100644
--- a/sim/src/caps.rs
+++ b/sim/src/caps.rs
@@ -1,6 +1,6 @@
 // Copyright (c) 2017-2019 Linaro LTD
 // Copyright (c) 2019 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
 //
 // SPDX-License-Identifier: Apache-2.0
 
@@ -25,6 +25,7 @@
     DowngradePrevention  = (1 << 12),
     EncX25519            = (1 << 13),
     Bootstrap            = (1 << 14),
+    Aes256               = (1 << 15),
 }
 
 impl Caps {
diff --git a/sim/src/image.rs b/sim/src/image.rs
index 1fdb1f0..988d136 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -1,6 +1,6 @@
 // Copyright (c) 2019 Linaro LTD
 // Copyright (c) 2019-2020 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
 //
 // SPDX-License-Identifier: Apache-2.0
 
@@ -26,6 +26,7 @@
 };
 use aes_ctr::{
     Aes128Ctr,
+    Aes256Ctr,
     stream_cipher::{
         generic_array::GenericArray,
         NewStreamCipher,
@@ -50,6 +51,7 @@
     UpgradeInfo,
 };
 use crate::tlv::{ManifestGen, TlvGen, TlvFlags};
+use typenum::{U32, U16};
 
 /// A builder for Images.  This describes a single run of the simulator,
 /// capturing the configuration of a particular set of devices, including
@@ -1294,17 +1296,25 @@
     tlv.add_bytes(&b_img);
 
     // Generate encrypted images
-    let flag = TlvFlags::ENCRYPTED as u32;
-    let is_encrypted = (tlv.get_flags() & flag) == flag;
+    let flag = TlvFlags::ENCRYPTED_AES128 as u32 | TlvFlags::ENCRYPTED_AES256 as u32;
+    let is_encrypted = (tlv.get_flags() & flag) != 0;
     let mut b_encimg = vec![];
     if is_encrypted {
+        let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+        let aes256 = (tlv.get_flags() & flag) == flag;
         tlv.generate_enc_key();
         let enc_key = tlv.get_enc_key();
-        let key = GenericArray::from_slice(enc_key.as_slice());
         let nonce = GenericArray::from_slice(&[0; 16]);
-        let mut cipher = Aes128Ctr::new(&key, &nonce);
         b_encimg = b_img.clone();
-        cipher.apply_keystream(&mut b_encimg);
+        if aes256 {
+            let key: &GenericArray<u8, U32> = GenericArray::from_slice(enc_key.as_slice());
+            let mut cipher = Aes256Ctr::new(&key, &nonce);
+            cipher.apply_keystream(&mut b_encimg);
+        } else {
+            let key: &GenericArray<u8, U16> = GenericArray::from_slice(enc_key.as_slice());
+            let mut cipher = Aes128Ctr::new(&key, &nonce);
+            cipher.apply_keystream(&mut b_encimg);
+        }
     }
 
     // Build the TLV itself.
@@ -1408,32 +1418,36 @@
     if Caps::EcdsaP224.present() {
         panic!("Ecdsa P224 not supported in Simulator");
     }
+    let mut aes_key_size = 128;
+    if Caps::Aes256.present() {
+        aes_key_size = 256;
+    }
 
     if Caps::EncKw.present() {
         if Caps::RSA2048.present() {
-            TlvGen::new_rsa_kw()
+            TlvGen::new_rsa_kw(aes_key_size)
         } else if Caps::EcdsaP256.present() {
-            TlvGen::new_ecdsa_kw()
+            TlvGen::new_ecdsa_kw(aes_key_size)
         } else {
-            TlvGen::new_enc_kw()
+            TlvGen::new_enc_kw(aes_key_size)
         }
     } else if Caps::EncRsa.present() {
         if Caps::RSA2048.present() {
-            TlvGen::new_sig_enc_rsa()
+            TlvGen::new_sig_enc_rsa(aes_key_size)
         } else {
-            TlvGen::new_enc_rsa()
+            TlvGen::new_enc_rsa(aes_key_size)
         }
     } else if Caps::EncEc256.present() {
         if Caps::EcdsaP256.present() {
-            TlvGen::new_ecdsa_ecies_p256()
+            TlvGen::new_ecdsa_ecies_p256(aes_key_size)
         } else {
-            TlvGen::new_ecies_p256()
+            TlvGen::new_ecies_p256(aes_key_size)
         }
     } else if Caps::EncX25519.present() {
         if Caps::Ed25519.present() {
-            TlvGen::new_ed25519_ecies_x25519()
+            TlvGen::new_ed25519_ecies_x25519(aes_key_size)
         } else {
-            TlvGen::new_ecies_x25519()
+            TlvGen::new_ecies_x25519(aes_key_size)
         }
     } else {
         // The non-encrypted configuration.
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index a7b2c2d..8ccdb0a 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -1,5 +1,6 @@
 // Copyright (c) 2017-2020 Linaro LTD
 // Copyright (c) 2017-2020 JUUL Labs
+// Copyright (c) 2021 Arm Limited
 //
 // SPDX-License-Identifier: Apache-2.0
 
@@ -29,6 +30,7 @@
 };
 use aes_ctr::{
     Aes128Ctr,
+    Aes256Ctr,
     stream_cipher::{
         generic_array::GenericArray,
         NewStreamCipher,
@@ -36,6 +38,7 @@
     },
 };
 use mcuboot_sys::c;
+use typenum::{U16, U32};
 
 #[repr(u16)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -59,8 +62,9 @@
 pub enum TlvFlags {
     PIC = 0x01,
     NON_BOOTABLE = 0x02,
-    ENCRYPTED = 0x04,
+    ENCRYPTED_AES128 = 0x04,
     RAM_LOAD = 0x20,
+    ENCRYPTED_AES256 = 0x08,
 }
 
 /// A generator for manifests.  The format of the manifest can be either a
@@ -115,8 +119,6 @@
     version: ImageVersion,
 }
 
-const AES_KEY_LEN: usize = 16;
-
 impl TlvGen {
     /// Construct a new tlv generator that will only contain a hash of the data.
     #[allow(dead_code)]
@@ -160,81 +162,126 @@
     }
 
     #[allow(dead_code)]
-    pub fn new_enc_rsa() -> TlvGen {
+    pub fn new_enc_rsa(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_sig_enc_rsa() -> TlvGen {
+    pub fn new_sig_enc_rsa(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_enc_kw() -> TlvGen {
+    pub fn new_enc_kw(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_rsa_kw() -> TlvGen {
+    pub fn new_rsa_kw(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_ecdsa_kw() -> TlvGen {
+    pub fn new_ecdsa_kw(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_ecies_p256() -> TlvGen {
+    pub fn new_ecies_p256(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCEC256],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_ecdsa_ecies_p256() -> TlvGen {
+    pub fn new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCEC256],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_ecies_x25519() -> TlvGen {
+    pub fn new_ecies_x25519(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ENCX25519],
             ..Default::default()
         }
     }
 
     #[allow(dead_code)]
-    pub fn new_ed25519_ecies_x25519() -> TlvGen {
+    pub fn new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen {
+        let flag = if aes_key_size == 256 {
+            TlvFlags::ENCRYPTED_AES256 as u32
+        } else {
+            TlvFlags::ENCRYPTED_AES128 as u32
+        };
         TlvGen {
-            flags: TlvFlags::ENCRYPTED as u32,
+            flags: flag,
             kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519, TlvKinds::ENCX25519],
             ..Default::default()
         }
@@ -480,19 +527,27 @@
         }
 
         if self.kinds.contains(&TlvKinds::ENCKW) {
-            let key_bytes = base64::decode(
-                include_str!("../../enc-aes128kw.b64").trim()).unwrap();
-
+            let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+            let aes256 = (self.get_flags() & flag) == flag;
+            let key_bytes = if aes256 {
+                base64::decode(
+                    include_str!("../../enc-aes256kw.b64").trim()).unwrap()
+            } else {
+                base64::decode(
+                    include_str!("../../enc-aes128kw.b64").trim()).unwrap()
+            };
             let cipherkey = self.get_enc_key();
             let cipherkey = cipherkey.as_slice();
-            let encbuf = match c::kw_encrypt(&key_bytes, cipherkey) {
+            let keylen = if aes256 { 32 } else { 16 };
+            let encbuf = match c::kw_encrypt(&key_bytes, cipherkey, keylen) {
                 Ok(v) => v,
                 Err(_) => panic!("Failed to encrypt secret key"),
             };
 
-            assert!(encbuf.len() == 24);
+            let size = if aes256 { 40 } else { 24 };
+            assert!(encbuf.len() == size);
             result.write_u16::<LittleEndian>(TlvKinds::ENCKW as u16).unwrap();
-            result.write_u16::<LittleEndian>(24).unwrap();
+            result.write_u16::<LittleEndian>(size as u16).unwrap();
             result.extend_from_slice(&encbuf);
         }
 
@@ -503,7 +558,6 @@
                 pem::parse(include_bytes!("../../enc-x25519-pub.pem").as_ref()).unwrap()
             };
             assert_eq!(key_bytes.tag, "PUBLIC KEY");
-
             let rng = rand::SystemRandom::new();
             let alg = if self.kinds.contains(&TlvKinds::ENCEC256) {
                 &agreement::ECDH_P256
@@ -535,15 +589,19 @@
                 }
             }
 
+            let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+            let aes256 = (self.get_flags() & flag) == flag;
+
             let derived_key = match agreement::agree_ephemeral(
                 pk, &peer_pubk, ring::error::Unspecified, |shared| {
                     let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &[]);
                     let prk = salt.extract(&shared);
-                    let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(48)) {
+                    let okm_len = if aes256 { 64 } else { 48 };
+                    let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(okm_len)) {
                         Ok(okm) => okm,
                         Err(_) => panic!("Failed building HKDF OKM"),
                     };
-                    let mut buf = [0u8; 48];
+                    let mut buf = if aes256 { vec![0u8; 64] } else { vec![0u8; 48] };
                     match okm.fill(&mut buf) {
                         Ok(_) => Ok(buf),
                         Err(_) => panic!("Failed generating HKDF output"),
@@ -554,13 +612,20 @@
                 Err(_) => panic!("Failed building HKDF"),
             };
 
-            let key = GenericArray::from_slice(&derived_key[..16]);
             let nonce = GenericArray::from_slice(&[0; 16]);
-            let mut cipher = Aes128Ctr::new(&key, &nonce);
             let mut cipherkey = self.get_enc_key();
-            cipher.apply_keystream(&mut cipherkey);
+            if aes256 {
+                let key: &GenericArray<u8, U32> = GenericArray::from_slice(&derived_key[..32]);
+                let mut cipher = Aes256Ctr::new(&key, &nonce);
+                cipher.apply_keystream(&mut cipherkey);
+            } else {
+                let key: &GenericArray<u8, U16> = GenericArray::from_slice(&derived_key[..16]);
+                let mut cipher = Aes128Ctr::new(&key, &nonce);
+                cipher.apply_keystream(&mut cipherkey);
+            }
 
-            let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[16..]);
+            let size = if aes256 { 32 } else { 16 };
+            let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[size..]);
             let tag = hmac::sign(&key, &cipherkey);
 
             let mut buf = vec![];
@@ -569,13 +634,15 @@
             buf.append(&mut cipherkey);
 
             if self.kinds.contains(&TlvKinds::ENCEC256) {
-                assert!(buf.len() == 113);
+                let size = if aes256 { 129 } else { 113 };
+                assert!(buf.len() == size);
                 result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap();
-                result.write_u16::<LittleEndian>(113).unwrap();
+                result.write_u16::<LittleEndian>(size as u16).unwrap();
             } else {
-                assert!(buf.len() == 80);
+                let size = if aes256 { 96 } else { 80 };
+                assert!(buf.len() == size);
                 result.write_u16::<LittleEndian>(TlvKinds::ENCX25519 as u16).unwrap();
-                result.write_u16::<LittleEndian>(80).unwrap();
+                result.write_u16::<LittleEndian>(size as u16).unwrap();
             }
             result.extend_from_slice(&buf);
         }
@@ -590,7 +657,13 @@
 
     fn generate_enc_key(&mut self) {
         let rng = rand::SystemRandom::new();
-        let mut buf = vec![0u8; AES_KEY_LEN];
+        let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+        let aes256 = (self.get_flags() & flag) == flag;
+        let mut buf = if aes256 {
+            vec![0u8; 32]
+        } else {
+            vec![0u8; 16]
+        };
         if rng.fill(&mut buf).is_err() {
             panic!("Error generating encrypted key");
         }
@@ -599,7 +672,7 @@
     }
 
     fn get_enc_key(&self) -> Vec<u8> {
-        if self.enc_key.len() != AES_KEY_LEN {
+        if self.enc_key.len() != 32 && self.enc_key.len() != 16 {
             panic!("No random key was generated");
         }
         self.enc_key.clone()