Infineon: Add cyw20829 platform, shared slot feature, json memory map, psoc6 xip

Based in 1.8.0 release of MCUBoot library

This commit adds CYW20829 Infineon platform support with following capabilities:
1. Overwrite and swap upgrade mode support
2. Multi-image with up to 4 images
3. Hardware security counter is supported for CYW20829 platform

Add XIP support for PSOC6 platform - place BOOT slot in external memory and execute it in place using SMIF in XIP mode

and some new features for Infineon devices.

1. Shared upgrade slot feature - use one shared area for upgrade slots of multiple images
2. Memory map defined using JSON file - define memory regions for bootloader and user app in conventional way using JSON file
diff --git a/sim/mcuboot-sys/Cargo.toml b/sim/mcuboot-sys/Cargo.toml
index ef09755..e3a00cb 100644
--- a/sim/mcuboot-sys/Cargo.toml
+++ b/sim/mcuboot-sys/Cargo.toml
@@ -30,34 +30,62 @@
 # Overwrite only upgrade
 overwrite-only = []
 
-swap-status = []
-
 swap-move = []
 
+swap-status = []
+
 # Disable validation of the primary slot
 validate-primary-slot = []
 
 # 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 = []
 
 # Support multiple images (currently 2 instead of 1).
 multiimage = []
 
+# Support simulation of ram-loading.  No swaps are performed, and the
+# image is copied to RAM before loading it.
+ram-load = []
+
+# Support simulation of direct XIP.  No swaps are performed, the image
+# is directly executed out of whichever partition contains the most
+# appropriate image.
+direct-xip = []
+
 # Check (in software) against version downgrades.
 downgrade-prevention = []
 
+# Large write.  Not meaningful, but present here so that the
+# full-suite tests will work for this configuration.
+large-write = []
+
 [build-dependencies]
 cc = "1.0.25"
 
diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs
index a2206c9..1a08741 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -2,10 +2,11 @@
 
 extern crate cc;
 
+use std::collections::BTreeSet;
 use std::env;
 use std::fs;
 use std::io;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 
 fn main() {
     // Feature flags.
@@ -20,37 +21,51 @@
     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();
+    let ram_load = env::var("CARGO_FEATURE_RAM_LOAD").is_ok();
+    let direct_xip = env::var("CARGO_FEATURE_DIRECT_XIP").is_ok();
 
-    let mut conf = cc::Build::new();
-    conf.define("__BOOTSIM__", None);
-    conf.define("MCUBOOT_HAVE_LOGGING", None);
-    conf.define("MCUBOOT_USE_FLASH_AREA_GET_SECTORS", None);
-    conf.define("MCUBOOT_HAVE_ASSERT_H", None);
-    if !swap_status {
-        conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("128"));
-    }
-    conf.define("MCUBOOT_IMAGE_NUMBER", Some(if multiimage { "2" } else { "1" }));
+    let mut conf = CachedBuild::new();
+    conf.conf.define("__BOOTSIM__", None);
+    conf.conf.define("MCUBOOT_HAVE_LOGGING", None);
+    conf.conf.define("MCUBOOT_USE_FLASH_AREA_GET_SECTORS", None);
+    conf.conf.define("MCUBOOT_HAVE_ASSERT_H", None);
+    conf.conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("128"));
+    conf.conf.define("MCUBOOT_IMAGE_NUMBER", Some(if multiimage { "2" } else { "1" }));
 
     if downgrade_prevention && !overwrite_only {
         panic!("Downgrade prevention requires overwrite only");
     }
 
     if bootstrap {
-        conf.define("MCUBOOT_BOOTSTRAP", None);
+        conf.conf.define("MCUBOOT_BOOTSTRAP", None);
+        conf.conf.define("MCUBOOT_OVERWRITE_ONLY_FAST", None);
     }
 
     if validate_primary_slot {
-        conf.define("MCUBOOT_VALIDATE_PRIMARY_SLOT", None);
+        conf.conf.define("MCUBOOT_VALIDATE_PRIMARY_SLOT", None);
     }
 
     if downgrade_prevention {
-        conf.define("MCUBOOT_DOWNGRADE_PREVENTION", None);
+        conf.conf.define("MCUBOOT_DOWNGRADE_PREVENTION", None);
+    }
+
+    if ram_load {
+        conf.conf.define("MCUBOOT_RAM_LOAD", None);
+    }
+
+    if direct_xip {
+        conf.conf.define("MCUBOOT_DIRECT_XIP", None);
     }
 
     // Currently no more than one sig type can be used simultaneously.
@@ -60,35 +75,35 @@
     }
 
     if sig_rsa || sig_rsa3072 {
-        conf.define("MCUBOOT_SIGN_RSA", None);
+        conf.conf.define("MCUBOOT_SIGN_RSA", None);
         // The Kconfig style defines must be added here as well because
         // they are used internally by "config-rsa.h"
         if sig_rsa {
-            conf.define("MCUBOOT_SIGN_RSA_LEN", "2048");
-            conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "2048");
+            conf.conf.define("MCUBOOT_SIGN_RSA_LEN", "2048");
+            conf.conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "2048");
         } else {
-            conf.define("MCUBOOT_SIGN_RSA_LEN", "3072");
-            conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "3072");
+            conf.conf.define("MCUBOOT_SIGN_RSA_LEN", "3072");
+            conf.conf.define("CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN", "3072");
         }
-        conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
 
-        conf.include("../../ext/mbedtls/crypto/include");
-        conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.file("../../ext/mbedtls/library/sha256.c");
         conf.file("csupport/keys.c");
 
-        conf.file("../../ext/mbedtls/crypto/library/rsa.c");
-        conf.file("../../ext/mbedtls/crypto/library/bignum.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
-        conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/rsa.c");
+        conf.file("../../ext/mbedtls/library/bignum.c");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
     } else if sig_ecdsa {
-        conf.define("MCUBOOT_SIGN_EC256", None);
-        conf.define("MCUBOOT_USE_TINYCRYPT", None);
+        conf.conf.define("MCUBOOT_SIGN_EC256", None);
+        conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
 
         if !enc_kw {
-            conf.include("../../ext/mbedtls-asn1/include");
+            conf.conf.include("../../ext/mbedtls/include");
         }
-        conf.include("../../ext/tinycrypt/lib/include");
+        conf.conf.include("../../ext/tinycrypt/lib/include");
 
         conf.file("csupport/keys.c");
 
@@ -97,115 +112,119 @@
         conf.file("../../ext/tinycrypt/lib/source/ecc.c");
         conf.file("../../ext/tinycrypt/lib/source/ecc_dsa.c");
         conf.file("../../ext/tinycrypt/lib/source/ecc_platform_specific.c");
-
-        conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
-        conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
     } else if sig_ecdsa_mbedtls {
-        conf.define("MCUBOOT_SIGN_EC256", None);
-        conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.conf.define("MCUBOOT_SIGN_EC256", None);
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
 
-        conf.include("../../ext/mbedtls/crypto/include");
-        conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.file("../../ext/mbedtls/library/sha256.c");
         conf.file("csupport/keys.c");
 
-        conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
-        conf.file("../../ext/mbedtls/crypto/library/bignum.c");
-        conf.file("../../ext/mbedtls/crypto/library/ecdsa.c");
-        conf.file("../../ext/mbedtls/crypto/library/ecp.c");
-        conf.file("../../ext/mbedtls/crypto/library/ecp_curves.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/bignum.c");
+        conf.file("../../ext/mbedtls/library/ecdsa.c");
+        conf.file("../../ext/mbedtls/library/ecp.c");
+        conf.file("../../ext/mbedtls/library/ecp_curves.c");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
     } else if sig_ed25519 {
-        conf.define("MCUBOOT_SIGN_ED25519", None);
-        conf.define("MCUBOOT_USE_TINYCRYPT", None);
+        conf.conf.define("MCUBOOT_SIGN_ED25519", None);
+        conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
 
-        conf.include("../../ext/tinycrypt/lib/include");
-        conf.include("../../ext/tinycrypt-sha512/lib/include");
-        conf.include("../../ext/mbedtls-asn1/include");
+        conf.conf.include("../../ext/tinycrypt/lib/include");
+        conf.conf.include("../../ext/tinycrypt-sha512/lib/include");
+        conf.conf.include("../../ext/mbedtls/include");
         conf.file("../../ext/tinycrypt/lib/source/sha256.c");
         conf.file("../../ext/tinycrypt-sha512/lib/source/sha512.c");
         conf.file("../../ext/tinycrypt/lib/source/utils.c");
         conf.file("csupport/keys.c");
         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/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
     } else if !enc_ec256 && !enc_x25519 {
         // No signature type, only sha256 validation. The default
         // configuration file bundled with mbedTLS is sufficient.
         // When using ECIES-P256 rely on Tinycrypt.
-        conf.define("MCUBOOT_USE_MBED_TLS", None);
-        conf.include("../../ext/mbedtls/crypto/include");
-        conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.file("../../ext/mbedtls/library/sha256.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
     }
 
     if overwrite_only {
-        conf.define("MCUBOOT_OVERWRITE_ONLY", None);
-        conf.define("MCUBOOT_OVERWRITE_ONLY_FAST", None);
+        conf.conf.define("MCUBOOT_OVERWRITE_ONLY", None);
     }
 
     if swap_move {
-        conf.define("MCUBOOT_SWAP_USING_MOVE", None);
-        conf.file("../../boot/bootutil/src/swap_move.c");
+        conf.conf.define("MCUBOOT_SWAP_USING_MOVE", None);
+    } else if !overwrite_only {
+        conf.conf.define("CONFIG_BOOT_SWAP_USING_SCRATCH", None);
+        conf.conf.define("MCUBOOT_SWAP_USING_SCRATCH", None);
     }
-
     if swap_status {
-        conf.define("MCUBOOT_SWAP_USING_STATUS", None);
-        conf.define("MCUBOOT_LOG_LEVEL", "MCUBOOT_LOG_LEVEL_DEBUG");
-        conf.define("MCUBOOT_MAX_IMG_SECTORS", Some("2000"));
-        conf.define("CY_FLASH_ALIGN", "512");
-        conf.file("../../boot/bootutil/src/swap_status.c");
-        conf.file("../../boot/bootutil/src/swap_status_part.c");
-        conf.file("../../boot/bootutil/src/swap_status_misc.c");
-        conf.file("../../boot/bootutil/src/crc32c.c");
-//        conf.file("../../boot/cypress/cy_flash_pal/cy_my_support.c");
-        conf.include("../../boot/cypress/cy_flash_pal");
+        conf.conf.define("MCUBOOT_SWAP_USING_STATUS", None);
+        conf.conf.define("CY_FLASH_ALIGN", "512");
+        conf.conf.file("../../boot/bootutil/src/swap_status.c");
+        conf.conf.file("../../boot/bootutil/src/swap_status_part.c");
+        conf.conf.file("../../boot/bootutil/src/swap_status_misc.c");
+        conf.conf.file("../../boot/bootutil/src/crc32c.c");
     }
 
-    if enc_rsa {
-        conf.define("MCUBOOT_ENCRYPT_RSA", None);
-        conf.define("MCUBOOT_ENC_IMAGES", None);
-        conf.define("MCUBOOT_USE_MBED_TLS", None);
+    if enc_rsa || enc_aes256_rsa {
+        if enc_aes256_rsa {
+                conf.conf.define("MCUBOOT_AES_256", None);
+        }
+        conf.conf.define("MCUBOOT_ENCRYPT_RSA", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
 
         conf.file("../../boot/bootutil/src/encrypted.c");
         conf.file("csupport/keys.c");
 
-        conf.include("../../ext/mbedtls/crypto/include");
-        conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.conf.include("../../ext/mbedtls/library");
+        conf.file("../../ext/mbedtls/library/sha256.c");
 
-        conf.file("../../ext/mbedtls/crypto/library/platform.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
-        conf.file("../../ext/mbedtls/crypto/library/rsa.c");
-        conf.file("../../ext/mbedtls/crypto/library/rsa_internal.c");
-        conf.file("../../ext/mbedtls/crypto/library/md.c");
-        conf.file("../../ext/mbedtls/crypto/library/aes.c");
-        conf.file("../../ext/mbedtls/crypto/library/bignum.c");
-        conf.file("../../ext/mbedtls/crypto/library/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/rsa.c");
+        conf.file("../../ext/mbedtls/library/rsa_alt_helpers.c");
+        conf.file("../../ext/mbedtls/library/md.c");
+        conf.file("../../ext/mbedtls/library/aes.c");
+        conf.file("../../ext/mbedtls/library/bignum.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
     }
 
-    if enc_kw {
-        conf.define("MCUBOOT_ENCRYPT_KW", None);
-        conf.define("MCUBOOT_ENC_IMAGES", None);
+    if enc_kw || enc_aes256_kw {
+        if enc_aes256_kw {
+            conf.conf.define("MCUBOOT_AES_256", None);
+        }
+        conf.conf.define("MCUBOOT_ENCRYPT_KW", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
 
         conf.file("../../boot/bootutil/src/encrypted.c");
         conf.file("csupport/keys.c");
 
         if sig_rsa || sig_rsa3072 {
-            conf.file("../../ext/mbedtls/crypto/library/sha256.c");
+            conf.file("../../ext/mbedtls/library/sha256.c");
         }
 
         /* Simulator uses Mbed-TLS to wrap keys */
-        conf.include("../../ext/mbedtls/crypto/include");
-        conf.file("../../ext/mbedtls/crypto/library/platform.c");
-        conf.file("../../ext/mbedtls/crypto/library/platform_util.c");
-        conf.file("../../ext/mbedtls/crypto/library/nist_kw.c");
-        conf.file("../../ext/mbedtls/crypto/library/cipher.c");
-        conf.file("../../ext/mbedtls/crypto/library/cipher_wrap.c");
-        conf.file("../../ext/mbedtls/crypto/library/aes.c");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.conf.include("../../ext/mbedtls/library");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/nist_kw.c");
+        conf.file("../../ext/mbedtls/library/cipher.c");
+        conf.file("../../ext/mbedtls/library/cipher_wrap.c");
+        conf.file("../../ext/mbedtls/library/aes.c");
 
         if sig_ecdsa {
-            conf.define("MCUBOOT_USE_TINYCRYPT", None);
+            conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
 
-            conf.include("../../ext/tinycrypt/lib/include");
+            conf.conf.include("../../ext/tinycrypt/lib/include");
 
             conf.file("../../ext/tinycrypt/lib/source/utils.c");
             conf.file("../../ext/tinycrypt/lib/source/sha256.c");
@@ -220,16 +239,16 @@
     }
 
     if enc_ec256 {
-        conf.define("MCUBOOT_ENCRYPT_EC256", None);
-        conf.define("MCUBOOT_ENC_IMAGES", None);
-        conf.define("MCUBOOT_USE_TINYCRYPT", None);
-        conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+        conf.conf.define("MCUBOOT_ENCRYPT_EC256", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
+        conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
 
         conf.file("../../boot/bootutil/src/encrypted.c");
         conf.file("csupport/keys.c");
 
-        conf.include("../../ext/mbedtls-asn1/include");
-        conf.include("../../ext/tinycrypt/lib/include");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.conf.include("../../ext/tinycrypt/lib/include");
 
         /* FIXME: fail with other signature schemes ? */
 
@@ -239,36 +258,59 @@
         conf.file("../../ext/tinycrypt/lib/source/ecc_dsa.c");
         conf.file("../../ext/tinycrypt/lib/source/ecc_platform_specific.c");
 
-        conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
-        conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
 
         conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
         conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
         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 || enc_aes256_ec256 {
+        if enc_aes256_ec256 {
+            conf.conf.define("MCUBOOT_AES_256", None);
+        }
+        conf.conf.define("MCUBOOT_ENCRYPT_EC256", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+
+        conf.conf.include("../../ext/mbedtls/include");
+
+        conf.file("../../boot/bootutil/src/encrypted.c");
+        conf.file("../../ext/mbedtls/library/sha256.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/bignum.c");
+        conf.file("../../ext/mbedtls/library/ecdh.c");
+        conf.file("../../ext/mbedtls/library/md.c");
+        conf.file("../../ext/mbedtls/library/aes.c");
+        conf.file("../../ext/mbedtls/library/ecp.c");
+        conf.file("../../ext/mbedtls/library/ecp_curves.c");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("csupport/keys.c");
     }
 
     if enc_x25519 {
-        conf.define("MCUBOOT_ENCRYPT_X25519", None);
-        conf.define("MCUBOOT_ENC_IMAGES", None);
-        conf.define("MCUBOOT_USE_TINYCRYPT", None);
-        conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+        conf.conf.define("MCUBOOT_ENCRYPT_X25519", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.conf.define("MCUBOOT_USE_TINYCRYPT", None);
+        conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
 
         conf.file("../../boot/bootutil/src/encrypted.c");
         conf.file("csupport/keys.c");
 
-        conf.include("../../ext/mbedtls-asn1/include");
-        conf.include("../../ext/tinycrypt/lib/include");
-        conf.include("../../ext/tinycrypt-sha512/lib/include");
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.conf.include("../../ext/tinycrypt/lib/include");
+        conf.conf.include("../../ext/tinycrypt-sha512/lib/include");
 
         conf.file("../../ext/fiat/src/curve25519.c");
 
         conf.file("../../ext/tinycrypt/lib/source/utils.c");
         conf.file("../../ext/tinycrypt/lib/source/sha256.c");
 
-        conf.file("../../ext/mbedtls-asn1/src/platform_util.c");
-        conf.file("../../ext/mbedtls-asn1/src/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
 
         conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
         conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
@@ -276,24 +318,48 @@
         conf.file("../../ext/tinycrypt/lib/source/hmac.c");
     }
 
+    else if enc_aes256_x25519 {
+        conf.conf.define("MCUBOOT_AES_256", None);
+        conf.conf.define("MCUBOOT_ENCRYPT_X25519", None);
+        conf.conf.define("MCUBOOT_ENC_IMAGES", None);
+        conf.conf.define("MCUBOOT_USE_MBED_TLS", None);
+        conf.conf.define("MCUBOOT_SWAP_SAVE_ENCTLV", None);
+
+        conf.file("../../boot/bootutil/src/encrypted.c");
+        conf.file("csupport/keys.c");
+
+        conf.conf.include("../../ext/mbedtls/include");
+        conf.file("../../ext/fiat/src/curve25519.c");
+        conf.file("../../ext/mbedtls/library/asn1parse.c");
+        conf.file("../../ext/mbedtls/library/platform.c");
+        conf.file("../../ext/mbedtls/library/platform_util.c");
+        conf.file("../../ext/mbedtls/library/aes.c");
+        conf.file("../../ext/mbedtls/library/sha256.c");
+        conf.file("../../ext/mbedtls/library/md.c");
+        conf.file("../../ext/mbedtls/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 {
-        conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
-    } else if sig_ecdsa_mbedtls {
-        conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ecdsa.h>"));
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa-kw.h>"));
+    } else if sig_rsa || sig_rsa3072 || enc_rsa || enc_aes256_rsa {
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
+    } else if sig_ecdsa_mbedtls || enc_ec256_mbedtls || enc_aes256_ec256 {
+        conf.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>"));
+        conf.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 {
-        conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
+    } else if enc_kw || enc_aes256_kw {
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+    } else if enc_aes256_x25519 {
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ed25519.h>"));
     }
 
     conf.file("../../boot/bootutil/src/image_validate.c");
     if sig_rsa || sig_rsa3072 {
         conf.file("../../boot/bootutil/src/image_rsa.c");
     } else if sig_ecdsa || sig_ecdsa_mbedtls {
+        conf.conf.include("../../ext/mbedtls/include");
         conf.file("../../boot/bootutil/src/image_ec256.c");
     } else if sig_ed25519 {
         conf.file("../../boot/bootutil/src/image_ed25519.c");
@@ -301,32 +367,33 @@
     conf.file("../../boot/bootutil/src/loader.c");
     conf.file("../../boot/bootutil/src/swap_misc.c");
     conf.file("../../boot/bootutil/src/swap_scratch.c");
+    conf.file("../../boot/bootutil/src/swap_move.c");
     conf.file("../../boot/bootutil/src/caps.c");
     conf.file("../../boot/bootutil/src/bootutil_misc.c");
     conf.file("../../boot/bootutil/src/bootutil_public.c");
     conf.file("../../boot/bootutil/src/tlv.c");
     conf.file("../../boot/bootutil/src/fault_injection_hardening.c");
     conf.file("csupport/run.c");
-    conf.include("../../boot/bootutil/include");
-    conf.include("csupport");
-    conf.include("../../boot/zephyr/include");
-    conf.debug(true);
-    conf.flag("-Wall");
-    conf.flag("-Werror");
+    conf.conf.include("../../boot/bootutil/include");
+    conf.conf.include("csupport");
+    conf.conf.include("../../boot/zephyr/include");
+    conf.conf.debug(true);
+    conf.conf.flag("-Wall");
+    conf.conf.flag("-Werror");
 
     // FIXME: travis-ci still uses gcc 4.8.4 which defaults to std=gnu90.
     // It has incomplete std=c11 and std=c99 support but std=c99 was checked
     // to build correctly so leaving it here to updated in the future...
-    conf.flag("-std=c99");
+    conf.conf.flag("-std=c99");
 
-    conf.compile("libbootutil.a");
+    conf.conf.compile("libbootutil.a");
 
     walk_dir("../../boot").unwrap();
     walk_dir("../../ext/tinycrypt/lib/source").unwrap();
     walk_dir("../../ext/mbedtls-asn1").unwrap();
     walk_dir("csupport").unwrap();
-    walk_dir("../../ext/mbedtls/crypto/include").unwrap();
-    walk_dir("../../ext/mbedtls/crypto/library").unwrap();
+    walk_dir("../../ext/mbedtls/include").unwrap();
+    walk_dir("../../ext/mbedtls/library").unwrap();
 }
 
 // Output the names of all files within a directory so that Cargo knows when to rebuild.
@@ -347,3 +414,30 @@
 
     Ok(())
 }
+
+/// Wrap the cc::Build type so that we can make sure that files are only added a single time.
+/// Other methods can be passed through as needed.
+struct CachedBuild {
+    conf: cc::Build,
+    seen: BTreeSet<PathBuf>,
+}
+
+impl CachedBuild {
+    fn new() -> CachedBuild {
+        CachedBuild {
+            conf: cc::Build::new(),
+            seen: BTreeSet::new(),
+        }
+    }
+
+    /// Works like `file` in the Build, but doesn't add a file if the same path has already been
+    /// given.
+    fn file<P: AsRef<Path>>(&mut self, p: P) -> &mut CachedBuild {
+        let p = p.as_ref();
+        if !self.seen.contains(p) {
+            self.conf.file(p);
+            self.seen.insert(p.to_owned());
+        }
+        self
+    }
+}
diff --git a/sim/mcuboot-sys/csupport/devicetree.h b/sim/mcuboot-sys/csupport/devicetree.h
index 73c7c83..22a7fe6 100644
--- a/sim/mcuboot-sys/csupport/devicetree.h
+++ b/sim/mcuboot-sys/csupport/devicetree.h
@@ -9,6 +9,8 @@
 #ifndef __DEVICETREE_H__
 #define __DEVICETREE_H__
 
+#define FLASH_AREA_ERROR             255u
+
 #define FLASH_AREA_ID(x) FLASH_AREA_ID_##x
 
 #define FLASH_AREA_ID_image_0 1
@@ -17,11 +19,16 @@
 #define FLASH_AREA_ID_image_2 4
 #define FLASH_AREA_ID_image_3 5
 
-#define FLASH_AREA_IMAGE_0     FLASH_AREA_ID(image_0)
-#define FLASH_AREA_IMAGE_1     FLASH_AREA_ID(image_1)
-#define FLASH_AREA_IMAGE_2     FLASH_AREA_ID(image_2)
-#define FLASH_AREA_IMAGE_3     FLASH_AREA_ID(image_3)
+/*
+ * PSoC6 area defines based on file:
+ * boot/cypress/MCUBootApp/sysflash/sysflash.h
+*/
+#define FLASH_AREA_IMAGE_0 1
+#define FLASH_AREA_IMAGE_1 2
+#define FLASH_AREA_IMAGE_2 4
+#define FLASH_AREA_IMAGE_3 5
+#define FLASH_AREA_IMAGE_SWAP_STATUS 7
 
-#define FLASH_AREA_IMAGE_SWAP_STATUS FLASH_AREA_ID(image_scratch)
+#define BOOT_MAX_SWAP_STATUS_SECTORS 64
 
 #endif /*__DEVICETREE_H__*/
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 fd21bfd..fd6c3ca 100644
--- a/sim/mcuboot-sys/csupport/run.c
+++ b/sim/mcuboot-sys/csupport/run.c
@@ -22,7 +22,9 @@
 #include "mbedtls/nist_kw.h"
 #endif
 
+#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
 #include <bootutil/bootutil_log.h>
+#include "bootutil/crypto/common.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
@@ -90,15 +92,15 @@
         return -6;
     }
 
-    if (mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0) {
+    if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0) {
         return -7;
     }
 
-    if (mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0) {
+    if (mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0) {
         return -8;
     }
 
-    ctx->len = mbedtls_mpi_size(&ctx->N);
+    ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
 
     if (*p != end) {
         return -9;
@@ -140,7 +142,12 @@
 
     mbedtls_platform_set_calloc_free(calloc, free);
 
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+    mbedtls_rsa_init(&ctx);
+    mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+#else
     mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+#endif
 
     cp = (uint8_t *)pubkey;
     cpend = cp + pubkey_len;
@@ -150,8 +157,13 @@
         goto done;
     }
 
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+    rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL,
+            NULL, 0, seckey_len, seckey, encbuf);
+#else
     rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL, MBEDTLS_RSA_PUBLIC,
             NULL, 0, seckey_len, seckey, encbuf);
+#endif
     if (rc) {
         goto done;
     }
@@ -173,6 +185,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;
@@ -181,13 +202,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);
@@ -201,9 +222,9 @@
 #endif
 }
 
-uint16_t flash_area_align(const struct flash_area *area)
+size_t flash_area_align(const struct flash_area *area)
 {
-    return sim_flash_align(area->fa_device_id);
+    return (size_t)sim_flash_align(area->fa_device_id);
 }
 
 uint8_t flash_area_erased_val(const struct flash_area *area)
@@ -223,14 +244,16 @@
     uint32_t num_slots;
 };
 
-int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc)
+int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc,
+                   struct boot_rsp *rsp)
 {
     int res;
-    struct boot_rsp rsp;
     struct boot_loader_state *state;
 
 #if defined(MCUBOOT_SIGN_RSA) || \
-    (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS))
+    (defined(MCUBOOT_SIGN_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
 
@@ -241,7 +264,7 @@
     sim_set_context(ctx);
 
     if (setjmp(ctx->boot_jmpbuf) == 0) {
-        res = context_boot_go(state, &rsp);
+        res = context_boot_go(state, rsp);
         sim_reset_flash_areas();
         sim_reset_context();
         free(state);
@@ -261,53 +284,30 @@
     return malloc(size);
 }
 
-void os_free(void *mem)
-{
-    free(mem);
-}
-
-void *os_realloc(void *ptr, size_t size)
-{
-    return realloc(ptr, size);
-}
-
 int flash_area_id_from_multi_image_slot(int image_index, int slot)
 {
     switch (slot) {
     case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
     case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
     case 2: return FLASH_AREA_IMAGE_SCRATCH;
-
-    // case 7: return FLASH_AREA_IMAGE_SWAP_STATUS;
     }
 
-    printf("Image flash area ID not found, image=%d, slot=%d\n", image_index, slot);
+    printf("Image flash area ID not found\n");
     return -1; /* flash_area_open will fail on that */
 }
 
-int flash_area_id_from_image_slot(int slot)
-{
-    return flash_area_id_from_multi_image_slot(0, slot);
-}
-
 int flash_area_open(uint8_t id, const struct flash_area **area)
 {
     uint32_t i;
     struct area_desc *flash_areas;
 
-    // BOOT_LOG_SIM("%s: area id=%d, num_slots=%d", __func__, id, sim_get_flash_areas()->num_slots);
-
     flash_areas = sim_get_flash_areas();
     for (i = 0; i < flash_areas->num_slots; i++) {
-        // BOOT_LOG_SIM(" * flash_areas->slots[%d].id=%d", i, flash_areas->slots[i].id);
         if (flash_areas->slots[i].id == id)
-        {
-            // BOOT_LOG_SIM(" * found, i=%d, id=%d", i, id);
             break;
-        }
     }
     if (i == flash_areas->num_slots) {
-        printf("Unsupported area id=%d\n", id);
+        printf("Unsupported area\n");
         abort();
     }
 
@@ -354,6 +354,15 @@
         ctx->jumped++;
         longjmp(ctx->boot_jmpbuf, 1);
     }
+
+// Align offset and length to sector size
+#ifdef MCUBOOT_SWAP_USING_STATUS
+    uint32_t sect_off = off / CY_FLASH_ALIGN * CY_FLASH_ALIGN;
+    len = ((off + len - 1) / CY_FLASH_ALIGN + 1) * CY_FLASH_ALIGN - sect_off;
+    off = sect_off;
+    BOOT_LOG_SIM("%s: erase with aligment at area=%d, off=%x, len=%x", __func__, area->fa_id, off, len);
+#endif
+
     return sim_flash_erase(area->fa_device_id, area->fa_off + off, len);
 }
 
@@ -363,22 +372,20 @@
     struct area *slot;
     struct area_desc *flash_areas;
 
-    // BOOT_LOG_SIM("%s: idx=%d", __func__, idx);
-
     flash_areas = sim_get_flash_areas();
     for (i = 0; i < flash_areas->num_slots; i++) {
         if (flash_areas->slots[i].id == idx)
             break;
     }
     if (i == flash_areas->num_slots) {
-        printf("flash_area_to_sectors: Unsupported area = %d\n", idx);
+        printf("Unsupported area\n");
         abort();
     }
 
     slot = &flash_areas->slots[i];
 
     if (slot->num_areas > (uint32_t)*cnt) {
-        printf("Too many areas in slot: %d > %d\n", slot->num_areas, *cnt);
+        printf("Too many areas in slot\n");
         abort();
     }
 
@@ -395,22 +402,20 @@
     struct area *slot;
     struct area_desc *flash_areas;
 
-    // BOOT_LOG_SIM("%s: area id=%d", __func__, fa_id);
-
     flash_areas = sim_get_flash_areas();
     for (i = 0; i < flash_areas->num_slots; i++) {
         if (flash_areas->slots[i].id == fa_id)
             break;
     }
     if (i == flash_areas->num_slots) {
-        printf("flash_area_get_sectors: Unsupported area = %d\n", fa_id);
+        printf("Unsupported area\n");
         abort();
     }
 
     slot = &flash_areas->slots[i];
 
     if (slot->num_areas > *count) {
-        printf("Too many areas in slot: %d > %d\n", slot->num_areas, *count);
+        printf("Too many areas in slot\n");
         abort();
     }
 
@@ -433,10 +438,20 @@
         return 1;
     }
 
-    printf("Unsupported image area ID=%d\n", area_id);
+    printf("Unsupported image area ID\n");
     abort();
 }
 
+uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+    return fa->fa_device_id;
+}
+
+int flash_area_id_from_image_slot(int slot) {
+    /* For single image cases, just use the first image. */
+    return flash_area_id_from_multi_image_slot(0, slot);
+}
+
 void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
 {
     if (!(x)) {
@@ -463,28 +478,3 @@
 {
     return BOOT_MAGIC_SZ;
 }
-
-void mbedtls_platform_zeroize( void *buf, size_t len )
-{
-    memset( buf, 0, len );
-}
-
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
-        void *dst, uint32_t len)
-{
-    uint8_t *mem_dest;
-    int rc;
-
-    mem_dest = (uint8_t *)dst;
-    rc = flash_area_read(fa, off, dst, len);
-    if (rc) {
-        return -1;
-    }
-
-    for (uint8_t i = 0; i < len; i++) {
-        if (mem_dest[i] != flash_area_erased_val(fa)) {
-            return 0;
-        }
-    }
-    return 1;
-}
diff --git a/sim/mcuboot-sys/csupport/storage/flash_map.h b/sim/mcuboot-sys/csupport/storage/flash_map.h
index 2a6fd56..7b20453 100644
--- a/sim/mcuboot-sys/csupport/storage/flash_map.h
+++ b/sim/mcuboot-sys/csupport/storage/flash_map.h
@@ -42,6 +42,7 @@
  * and match the target offset specified in download script.
  */
 #include <inttypes.h>
+#include <stddef.h>
 
 /**
  * @brief Structure describing an area on a flash device.
@@ -123,7 +124,7 @@
 /*
  * Alignment restriction for flash writes.
  */
-uint16_t flash_area_align(const struct flash_area *);
+size_t flash_area_align(const struct flash_area *);
 
 /*
  * What is value is read from erased flash bytes.
diff --git a/sim/mcuboot-sys/src/api.rs b/sim/mcuboot-sys/src/api.rs
index a6acd53..8d1140d 100644
--- a/sim/mcuboot-sys/src/api.rs
+++ b/sim/mcuboot-sys/src/api.rs
@@ -26,6 +26,38 @@
 
 pub type FlashParams = HashMap<u8, FlashParamsStruct>;
 
+/// The `boot_rsp` structure used by boot_go.
+#[repr(C)]
+#[derive(Debug)]
+pub struct BootRsp {
+    pub br_hdr: *const ImageHeader,
+    pub flash_dev_id: u8,
+    pub image_off: u32,
+}
+
+// TODO: Don't duplicate this image header declaration.
+#[repr(C)]
+#[derive(Debug)]
+pub struct ImageHeader {
+    magic: u32,
+    load_addr: u32,
+    hdr_size: u16,
+    protect_tlv_size: u16,
+    img_size: u32,
+    flags: u32,
+    ver: ImageVersion,
+    _pad2: u32,
+}
+
+#[repr(C)]
+#[derive(Debug)]
+pub struct ImageVersion {
+    pub major: u8,
+    pub minor: u8,
+    pub revision: u16,
+    pub build_num: u32,
+}
+
 pub struct CAreaDescPtr {
    pub ptr: *const CAreaDesc,
 }
@@ -89,9 +121,20 @@
     }
 }
 
+/// This struct describes the RAM layout of the current device.  It will be stashed, per test
+/// thread, and queried by the C code.
+#[repr(C)]
+#[derive(Debug, Default)]
+pub struct BootsimRamInfo {
+    pub start: u32,
+    pub size: u32,
+    pub base: usize,
+}
+
 thread_local! {
     pub static THREAD_CTX: RefCell<FlashContext> = RefCell::new(FlashContext::new());
     pub static SIM_CTX: RefCell<CSimContextPtr> = RefCell::new(CSimContextPtr::new());
+    pub static RAM_CTX: RefCell<BootsimRamInfo> = RefCell::new(BootsimRamInfo::default());
 }
 
 /// Set the flash device to be used by the simulation.  The pointer is unsafely stashed away.
@@ -165,6 +208,32 @@
 }
 
 #[no_mangle]
+pub extern "C" fn bootsim_get_ram_info() -> *const BootsimRamInfo {
+    RAM_CTX.with(|ctx| {
+        if ctx.borrow().base == 0 {
+            // Option is messier to get a pointer out of, so just check if the base has been set to
+            // anything.
+            panic!("ram info not set, but being used");
+        }
+        ctx.as_ptr()
+    })
+}
+
+/// Store a copy of this RAM info.
+pub fn set_ram_info(info: BootsimRamInfo) {
+    RAM_CTX.with(|ctx| {
+        ctx.replace(info);
+    });
+}
+
+/// Clear out the ram info.
+pub fn clear_ram_info() {
+    RAM_CTX.with(|ctx| {
+        ctx.borrow_mut().base = 0;
+    });
+}
+
+#[no_mangle]
 pub extern fn sim_flash_erase(dev_id: u8, offset: u32, size: u32) -> libc::c_int {
     let mut rc: libc::c_int = -19;
     THREAD_CTX.with(|ctx| {
diff --git a/sim/mcuboot-sys/src/area.rs b/sim/mcuboot-sys/src/area.rs
index f151fe4..cfbebda 100644
--- a/sim/mcuboot-sys/src/area.rs
+++ b/sim/mcuboot-sys/src/area.rs
@@ -189,8 +189,8 @@
     ImageScratch = 3,
     Image2 = 4,
     Image3 = 5,
-    //ImageSwapStatus = 7,
-    //ImageSwapStatus = 3,
+//    Not_used = 6,
+    ImageSwapStatus = 7,
 }
 
 impl Default for FlashId {
diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs
index 5f518f5..5c791b8 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
 
@@ -10,9 +10,61 @@
 use simflash::SimMultiFlash;
 use crate::api;
 
+/// The result of an invocation of `boot_go`.  This is intentionally opaque so that we can provide
+/// accessors for everything we need from this.
+#[derive(Debug)]
+pub enum BootGoResult {
+    /// This run was stopped by the flash simulation mechanism.
+    Stopped,
+    /// The bootloader ran to completion with the following data.
+    Normal {
+        result: i32,
+        asserts: u8,
+
+        resp: api::BootRsp,
+    },
+}
+
+impl BootGoResult {
+    /// Was this run interrupted.
+    pub fn interrupted(&self) -> bool {
+        matches!(self, BootGoResult::Stopped)
+    }
+
+    /// Was this boot run successful (returned 0)
+    pub fn success(&self) -> bool {
+        matches!(self, BootGoResult::Normal { result: 0, .. })
+    }
+
+    /// Success, but also no asserts.
+    pub fn success_no_asserts(&self) -> bool {
+        matches!(self, BootGoResult::Normal {
+            result: 0,
+            asserts: 0,
+            ..
+        })
+    }
+
+    /// Get the asserts count.  An interrupted run will be considered to have no asserts.
+    pub fn asserts(&self) -> u8 {
+        match self {
+            BootGoResult::Normal { asserts, .. } => *asserts,
+            _ => 0,
+        }
+    }
+
+    /// Retrieve the 'resp' field that is filled in.
+    pub fn resp(&self) -> Option<&api::BootRsp> {
+        match self {
+            BootGoResult::Normal { resp, .. } => Some(resp),
+            _ => None,
+        }
+    }
+}
+
 /// Invoke the bootloader on this flash device.
 pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc,
-               counter: Option<&mut i32>, catch_asserts: bool) -> (i32, u8) {
+               counter: Option<&mut i32>, catch_asserts: bool) -> BootGoResult {
     for (&dev_id, flash) in multiflash.iter_mut() {
         api::set_flash(dev_id, flash);
     }
@@ -26,8 +78,14 @@
         c_catch_asserts: if catch_asserts { 1 } else { 0 },
         boot_jmpbuf: [0; 16],
     };
+    let mut rsp = api::BootRsp {
+        br_hdr: std::ptr::null(),
+        flash_dev_id: 0,
+        image_off: 0,
+    };
     let result = unsafe {
-        raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _) as i32
+        raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _,
+            &mut rsp as *mut _) as i32
     };
     let asserts = sim_ctx.c_asserts;
     if let Some(c) = counter {
@@ -36,7 +94,11 @@
     for &dev_id in multiflash.keys() {
         api::clear_flash(dev_id);
     }
-    (result, asserts)
+    if result == -0x13579 {
+        BootGoResult::Stopped
+    } else {
+        BootGoResult::Normal { result, asserts, resp: rsp }
+    }
 }
 
 pub fn boot_trailer_sz(align: u32) -> u32 {
@@ -67,9 +129,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);
         }
@@ -79,13 +144,14 @@
 
 mod raw {
     use crate::area::CAreaDesc;
-    use crate::api::CSimContext;
+    use crate::api::{BootRsp, CSimContext};
 
     extern "C" {
         // This generates a warning about `CAreaDesc` not being foreign safe.  There doesn't appear to
         // be any way to get rid of this warning.  See https://github.com/rust-lang/rust/issues/34798
         // for information and tracking.
-        pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc) -> libc::c_int;
+        pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc,
+            rsp: *mut BootRsp) -> libc::c_int;
 
         pub fn boot_trailer_sz(min_write_sz: u32) -> u32;
         pub fn boot_status_sz(min_write_sz: u32) -> u32;
diff --git a/sim/mcuboot-sys/src/lib.rs b/sim/mcuboot-sys/src/lib.rs
index 8acb246..bc3fc49 100644
--- a/sim/mcuboot-sys/src/lib.rs
+++ b/sim/mcuboot-sys/src/lib.rs
@@ -10,3 +10,43 @@
 pub mod api;
 
 pub use crate::area::{AreaDesc, FlashId};
+
+/// For testing the ram load feature, we need to emulate a block of RAM and be able to pass that
+/// down to the C code.  The call down to boot_go should go through this object so that the buffer
+/// itself is managed properly.
+pub struct RamBlock {
+    ram: Vec<u8>,
+    offset: u32, // 32-bit offset.
+}
+
+impl RamBlock {
+    pub fn new(size: u32, offset: u32) -> RamBlock {
+        RamBlock {
+            ram: vec![0; size as usize],
+            offset: offset,
+        }
+    }
+
+    /// Borrow the RAM buffer, with 'offset' being the beginning of the buffer.
+    pub fn borrow(&self) -> &[u8] {
+        &self.ram
+    }
+
+    /// Borrow a piece of the ram, with 'offset' being the beginning of the buffer.
+    pub fn borrow_part(&self, base: usize, size: usize) -> &[u8] {
+        &self.ram[base..base+size]
+    }
+
+    pub fn invoke<F, R>(&self, act: F) -> R
+        where F: FnOnce() -> R
+    {
+        api::set_ram_info(api::BootsimRamInfo {
+            start: self.offset,
+            size: self.ram.len() as u32,
+            base: &self.ram[0] as *const u8 as usize - self.offset as usize,
+        });
+        let result = act();
+        api::clear_ram_info();
+        result
+    }
+}