Sim: Add testcases for AES256 image encryption

Signed-off-by: Salome Thirot <salome.thirot@arm.com>
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 11aaec7..d930473 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -93,6 +93,7 @@
  "serde",
  "serde_derive",
  "simflash",
+ "typenum",
  "untrusted",
 ]
 
@@ -503,9 +504,9 @@
 
 [[package]]
 name = "typenum"
-version = "1.11.2"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
 
 [[package]]
 name = "unicode-segmentation"
diff --git a/sim/Cargo.toml b/sim/Cargo.toml
index ea4dcc9..bea0810 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -16,10 +16,14 @@
 swap-move = ["mcuboot-sys/swap-move"]
 validate-primary-slot = ["mcuboot-sys/validate-primary-slot"]
 enc-rsa = ["mcuboot-sys/enc-rsa"]
+enc-aes256-rsa = ["mcuboot-sys/enc-aes256-rsa"]
 enc-kw = ["mcuboot-sys/enc-kw"]
+enc-aes256-kw = ["mcuboot-sys/enc-aes256-kw"]
 enc-ec256 = ["mcuboot-sys/enc-ec256"]
 enc-ec256-mbedtls = ["mcuboot-sys/enc-ec256-mbedtls"]
+enc-aes256-ec256 = ["mcuboot-sys/enc-aes256-ec256"]
 enc-x25519 = ["mcuboot-sys/enc-x25519"]
+enc-aes256-x25519 = ["mcuboot-sys/enc-aes256-x25519"]
 bootstrap = ["mcuboot-sys/bootstrap"]
 multiimage = ["mcuboot-sys/multiimage"]
 large-write = []
@@ -41,6 +45,7 @@
 pem = "0.8"
 aes-ctr = "0.4.0"
 base64 = "0.12.0"
+typenum = "1.13.0"
 
 # The simulator runs very slowly without optimization.  A value of 1
 # compiles in about half the time, but runs about 5-6 times slower.  2
diff --git a/sim/mcuboot-sys/Cargo.toml b/sim/mcuboot-sys/Cargo.toml
index ac203f1..06f6aec 100644
--- a/sim/mcuboot-sys/Cargo.toml
+++ b/sim/mcuboot-sys/Cargo.toml
@@ -38,18 +38,30 @@
 # Encrypt image in the secondary slot using RSA-OAEP-2048
 enc-rsa = []
 
+# Encrypt  image in the secondary slot using AES-256-CTR and RSA-OAEP-2048
+enc-aes256-rsa = []
+
 # Encrypt image in the secondary slot using AES-KW-128
 enc-kw = []
 
+# Encrypt image in the secondary slot using AES-256-CTR and AES-KW-256
+enc-aes256-kw = []
+
 # Encrypt image in the secondary slot using ECIES-P256
 enc-ec256 = []
 
+# Encrypt image in the secondary slot using AES-256-CTR and ECIES-P256
+enc-aes256-ec256 = []
+
 # Encrypt image in the secondary slot using ECIES-P256 using Mbed TLS
 enc-ec256-mbedtls = []
 
 # Encrypt image in the secondary slot using ECIES-X25519
 enc-x25519 = []
 
+# Encrypt image in the secondary slot using AES-256-CTR and ECIES-X25519
+enc-aes256-x25519 = []
+
 # Allow bootstrapping an empty/invalid primary slot from a valid secondary slot
 bootstrap = []
 
@@ -59,6 +71,7 @@
 # Check (in software) against version downgrades.
 downgrade-prevention = []
 
+
 [build-dependencies]
 cc = "1.0.25"
 
diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs
index 620e84f..082899c 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -19,10 +19,14 @@
     let validate_primary_slot =
                   env::var("CARGO_FEATURE_VALIDATE_PRIMARY_SLOT").is_ok();
     let enc_rsa = env::var("CARGO_FEATURE_ENC_RSA").is_ok();
+    let enc_aes256_rsa = env::var("CARGO_FEATURE_ENC_AES256_RSA").is_ok();
     let enc_kw = env::var("CARGO_FEATURE_ENC_KW").is_ok();
+    let enc_aes256_kw = env::var("CARGO_FEATURE_ENC_AES256_KW").is_ok();
     let enc_ec256 = env::var("CARGO_FEATURE_ENC_EC256").is_ok();
     let enc_ec256_mbedtls = env::var("CARGO_FEATURE_ENC_EC256_MBEDTLS").is_ok();
+    let enc_aes256_ec256 = env::var("CARGO_FEATURE_ENC_AES256_EC256").is_ok();
     let enc_x25519 = env::var("CARGO_FEATURE_ENC_X25519").is_ok();
+    let enc_aes256_x25519 = env::var("CARGO_FEATURE_ENC_AES256_X25519").is_ok();
     let bootstrap = env::var("CARGO_FEATURE_BOOTSTRAP").is_ok();
     let multiimage = env::var("CARGO_FEATURE_MULTIIMAGE").is_ok();
     let downgrade_prevention = env::var("CARGO_FEATURE_DOWNGRADE_PREVENTION").is_ok();
@@ -148,7 +152,10 @@
         conf.define("MCUBOOT_SWAP_USING_SCRATCH", None);
     }
 
-    if enc_rsa {
+    if enc_rsa || enc_aes256_rsa {
+        if enc_aes256_rsa {
+                conf.define("MCUBOOT_AES_256", None);
+        }
         conf.define("MCUBOOT_ENCRYPT_RSA", None);
         conf.define("MCUBOOT_ENC_IMAGES", None);
         conf.define("MCUBOOT_USE_MBED_TLS", None);
@@ -169,7 +176,10 @@
         conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
     }
 
-    if enc_kw {
+    if enc_kw || enc_aes256_kw {
+        if enc_aes256_kw {
+            conf.define("MCUBOOT_AES_256", None);
+        }
         conf.define("MCUBOOT_ENCRYPT_KW", None);
         conf.define("MCUBOOT_ENC_IMAGES", None);
 
@@ -234,7 +244,10 @@
         conf.file("../../ext/tinycrypt/lib/source/ctr_mode.c");
         conf.file("../../ext/tinycrypt/lib/source/hmac.c");
         conf.file("../../ext/tinycrypt/lib/source/ecc_dh.c");
-    } else if enc_ec256_mbedtls {
+    } else if enc_ec256_mbedtls || enc_aes256_ec256 {
+        if enc_aes256_ec256 {
+            conf.define("MCUBOOT_AES_256", None);
+        }
         conf.define("MCUBOOT_ENCRYPT_EC256", None);
         conf.define("MCUBOOT_ENC_IMAGES", None);
         conf.define("MCUBOOT_USE_MBED_TLS", None);
@@ -283,18 +296,42 @@
         conf.file("../../ext/tinycrypt/lib/source/hmac.c");
     }
 
+    else if enc_aes256_x25519 {
+        conf.define("MCUBOOT_AES_256", None);
+        conf.define("MCUBOOT_ENCRYPT_X25519", None);
+        conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+
+        conf.file("../../boot/bootutil/src/encrypted.c");
+        conf.file("csupport/keys.c");
+
+        conf.include("../../ext/mbedtls/crypto/include");
+        conf.file("../../ext/fiat/src/curve25519.c");
+        conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
+        conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+        conf.file("../../ext/mbedtls/crypto/library/platform.c");
+        conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
+        conf.file("../../ext/mbedtls/crypto/library/aes.c");
+        conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+        conf.file("../../ext/mbedtls/crypto/library/md.c");
+        conf.file("../../ext/mbedtls/crypto/library/sha512.c");
+    }
+
     if sig_rsa && enc_kw {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa-kw.h>"));
-    } else if sig_rsa || sig_rsa3072 || enc_rsa {
+    } else if sig_rsa || sig_rsa3072 || enc_rsa || enc_aes256_rsa {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
-    } else if sig_ecdsa_mbedtls || enc_ec256_mbedtls {
+    } else if sig_ecdsa_mbedtls || enc_ec256_mbedtls || enc_aes256_ec256 {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ec.h>"));
     } else if (sig_ecdsa || enc_ec256) && !enc_kw {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
     } else if sig_ed25519 || enc_x25519 {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
-    } else if enc_kw {
+    } else if enc_kw || enc_aes256_kw {
         conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+    } else if enc_aes256_x25519 {
+        conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ed25519.h>"));
     }
 
     conf.file("../../boot/bootutil/src/image_validate.c");
diff --git a/sim/mcuboot-sys/csupport/keys.c b/sim/mcuboot-sys/csupport/keys.c
index 8011629..f9325be 100644
--- a/sim/mcuboot-sys/csupport/keys.c
+++ b/sim/mcuboot-sys/csupport/keys.c
@@ -256,11 +256,20 @@
 #endif
 
 #if defined(MCUBOOT_ENCRYPT_KW)
+#if defined(MCUBOOT_AES_256)
+unsigned char enc_key[] = {
+  0xE4, 0x5C, 0x51, 0x46, 0xD2, 0x1C, 0x82, 0x35, 0xCC, 0x1A, 0x19, 0xAF,
+  0xA1, 0xF2, 0xAA, 0x20, 0xC8, 0x8C, 0x7F, 0x40, 0x6C, 0xDB, 0x22, 0xAA,
+  0x6A, 0xB5, 0xCB, 0xAA, 0xF8, 0xB1, 0x5B, 0xB4
+};
+static unsigned int enc_key_len = 32;
+#else
 unsigned char enc_key[] = {
   0xd1, 0x5a, 0x04, 0x95, 0xc4, 0xc2, 0xa8, 0xff, 0x30, 0x78, 0xce, 0x49,
   0xb5, 0xfc, 0xb2, 0xdd
 };
 static unsigned int enc_key_len = 16;
+#endif
 const struct bootutil_key bootutil_enc_key = {
     .key = enc_key,
     .len = &enc_key_len,
diff --git a/sim/mcuboot-sys/csupport/run.c b/sim/mcuboot-sys/csupport/run.c
index 2bea140..c8bfd4e 100644
--- a/sim/mcuboot-sys/csupport/run.c
+++ b/sim/mcuboot-sys/csupport/run.c
@@ -174,6 +174,15 @@
 int kw_encrypt_(const uint8_t *kek, const uint8_t *seckey, uint8_t *encbuf)
 {
 #ifdef MCUBOOT_ENCRYPT_KW
+#ifdef MCUBOOT_AES_256
+    int key_len = 256;
+    int out_size = 40;
+    int in_len = 32;
+#else
+    int key_len = 128;
+    int out_size = 24;
+    int in_len = 16;
+#endif
     mbedtls_nist_kw_context kw;
     size_t olen;
     int rc;
@@ -182,13 +191,13 @@
 
     mbedtls_nist_kw_init(&kw);
 
-    rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, 128, 1);
+    rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, key_len, 1);
     if (rc) {
         goto done;
     }
 
-    rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, 16, encbuf,
-            &olen, 24);
+    rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, in_len, encbuf,
+            &olen, out_size);
 
 done:
     mbedtls_nist_kw_free(&kw);
@@ -232,7 +241,8 @@
 
 #if defined(MCUBOOT_SIGN_RSA) || \
     (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
-    (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS))
+    (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
+    (defined(MCUBOOT_ENCRYPT_X25519) && defined(MCUBOOT_USE_MBED_TLS))
     mbedtls_platform_set_calloc_free(calloc, free);
 #endif
 
diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs
index 5f518f5..7814375 100644
--- a/sim/mcuboot-sys/src/c.rs
+++ b/sim/mcuboot-sys/src/c.rs
@@ -1,6 +1,6 @@
 // Copyright (c) 2017-2019 Linaro LTD
 // Copyright (c) 2017-2019 JUUL Labs
-// Copyright (c) 2019 Arm Limited
+// Copyright (c) 2019-2021 Arm Limited
 //
 // SPDX-License-Identifier: Apache-2.0
 
@@ -67,9 +67,12 @@
     }
 }
 
-pub fn kw_encrypt(kek: &[u8], seckey: &[u8]) -> Result<[u8; 24], &'static str> {
+pub fn kw_encrypt(kek: &[u8], seckey: &[u8], keylen: u32) -> Result<Vec<u8>, &'static str> {
     unsafe {
-        let mut encbuf = [0u8; 24];
+        let mut encbuf = vec![0u8; 24];
+        if keylen == 32 {
+            encbuf = vec![0u8; 40];
+        }
         if raw::kw_encrypt_(kek.as_ptr(), seckey.as_ptr(), encbuf.as_mut_ptr()) == 0 {
             return Ok(encbuf);
         }
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()