Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index b9bf517..026ce2b 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -143,7 +143,7 @@
   )
 endif()
 
-if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256)
+if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
   zephyr_library_include_directories(
     ${MBEDTLS_ASN1_DIR}/include
     )
@@ -158,6 +158,7 @@
     ${BOOT_DIR}/zephyr/include
     ${TINYCRYPT_DIR}/include
     )
+  zephyr_include_directories(${TINYCRYPT_DIR}/include)
 
   zephyr_library_sources(
     ${TINYCRYPT_DIR}/source/ecc.c
@@ -191,6 +192,13 @@
   # Use mbedTLS provided by Zephyr for RSA signatures. (Its config file
   # is set using Kconfig.)
   zephyr_include_directories(include)
+  if(CONFIG_BOOT_ENCRYPT_RSA)
+    set_source_files_properties(
+      ${BOOT_DIR}/bootutil/src/encrypted.c
+      PROPERTIES
+      INCLUDE_DIRECTORIES ${ZEPHYR_MBEDTLS_MODULE_DIR}/library
+      )
+  endif()
 elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519)
   if(CONFIG_BOOT_USE_TINYCRYPT)
     zephyr_library_include_directories(
@@ -224,7 +232,7 @@
   )
 endif()
 
-if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519)
+if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
   zephyr_library_sources(
     ${TINYCRYPT_DIR}/source/aes_encrypt.c
     ${TINYCRYPT_DIR}/source/aes_decrypt.c
@@ -297,6 +305,46 @@
   zephyr_library_sources(${GENERATED_PUBKEY})
 endif()
 
+if(CONFIG_BOOT_ENCRYPTION_KEY_FILE AND NOT CONFIG_BOOT_ENCRYPTION_KEY_FILE STREQUAL "")
+  # CONF_FILE points to the KConfig configuration files of the bootloader.
+  unset(CONF_DIR)
+  foreach(filepath ${CONF_FILE})
+    file(READ ${filepath} temp_text)
+    string(FIND "${temp_text}" ${CONFIG_BOOT_ENCRYPTION_KEY_FILE} match)
+    if(${match} GREATER_EQUAL 0)
+      if(NOT DEFINED CONF_DIR)
+        get_filename_component(CONF_DIR ${filepath} DIRECTORY)
+      else()
+        message(FATAL_ERROR "Encryption key file defined in multiple conf files")
+      endif()
+    endif()
+  endforeach()
+
+  if(IS_ABSOLUTE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
+    set(KEY_FILE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
+  elseif((DEFINED CONF_DIR) AND
+	 (EXISTS ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE}))
+    set(KEY_FILE ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
+  else()
+    set(KEY_FILE ${MCUBOOT_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
+  endif()
+  message("MCUBoot bootloader encryption key file: ${KEY_FILE}")
+
+  set(GENERATED_ENCKEY ${ZEPHYR_BINARY_DIR}/autogen-enckey.c)
+  add_custom_command(
+    OUTPUT ${GENERATED_ENCKEY}
+    COMMAND
+    ${PYTHON_EXECUTABLE}
+    ${MCUBOOT_DIR}/scripts/imgtool.py
+    getpriv
+    -k
+    ${KEY_FILE}
+    > ${GENERATED_ENCKEY}
+    DEPENDS ${KEY_FILE}
+    )
+  zephyr_library_sources(${GENERATED_ENCKEY})
+endif()
+
 if(CONFIG_MCUBOOT_CLEANUP_ARM_CORE)
 zephyr_library_sources(
   ${BOOT_DIR}/zephyr/arm_cleanup.c
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index 5d71cd2..3478234 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -65,7 +65,7 @@
 	  uploading a new application overwrites the one that previously
 	  occupied the area.
 
-choice
+choice BOOT_SIGNATURE_TYPE
 	prompt "Signature type"
 	default BOOT_SIGNATURE_TYPE_RSA
 
@@ -89,7 +89,7 @@
 	bool "Elliptic curve digital signatures with curve P-256"
 
 if BOOT_SIGNATURE_TYPE_ECDSA_P256
-choice
+choice BOOT_ECDSA_IMPLEMENTATION
 	prompt "Ecdsa implementation"
 	default BOOT_ECDSA_TINYCRYPT
 
@@ -111,7 +111,7 @@
 	bool "Edwards curve digital signatures using ed25519"
 
 if BOOT_SIGNATURE_TYPE_ED25519
-choice
+choice BOOT_ED25519_IMPLEMENTATION
 	prompt "Ecdsa implementation"
 	default BOOT_ED25519_TINYCRYPT
 config BOOT_ED25519_TINYCRYPT
@@ -182,8 +182,20 @@
 	  every boot, but can mitigate against some changes that are
 	  able to modify the flash image itself.
 
+config BOOT_VALIDATE_SLOT0_ONCE
+	bool "Validate image in the primary slot just once after after upgrade"
+	depends on !BOOT_VALIDATE_SLOT0 && SINGLE_APPLICATION_SLOT
+	default n
+	help
+	  If y, the bootloader attempts to validate the signature of the
+	  primary slot only once after an upgrade of the main slot.
+	  It caches the result in the magic area, which makes it an unsecure
+	  method. This option is usefull for lowering the boot up time for
+	  low end devices with as a compromise lowering the security level.
+	  If unsure, leave at the default value.
+
 if !SINGLE_APPLICATION_SLOT
-choice
+choice BOOT_IMAGE_UPGRADE_MODE
 	prompt "Image upgrade modes"
 	default BOOT_SWAP_USING_MOVE if SOC_FAMILY_NRF
 	default BOOT_SWAP_USING_SCRATCH
@@ -257,9 +269,14 @@
 	  JTAG/SWD or primary slot in external flash).
 	  If unsure, leave at the default value.
 
+config BOOT_ENCRYPT_IMAGE
+	bool
+	help
+	  Hidden option used to check if any image encryption is enabled.
+
 config BOOT_ENCRYPT_RSA
 	bool "Support for encrypted upgrade images using RSA"
-	default n
+	select BOOT_ENCRYPT_IMAGE
 	help
 	  If y, images in the secondary slot can be encrypted and are decrypted
 	  on the fly when upgrading to the primary slot, as well as encrypted
@@ -268,7 +285,7 @@
 
 config BOOT_ENCRYPT_EC256
 	bool "Support for encrypted upgrade images using ECIES-P256"
-	default n
+	select BOOT_ENCRYPT_IMAGE
 	help
 	  If y, images in the secondary slot can be encrypted and are decrypted
 	  on the fly when upgrading to the primary slot, as well as encrypted
@@ -278,7 +295,7 @@
 
 config BOOT_ENCRYPT_X25519
 	bool "Support for encrypted upgrade images using ECIES-X25519"
-	default n
+	select BOOT_ENCRYPT_IMAGE
 	help
 	  If y, images in the secondary slot can be encrypted and are decrypted
 	  on the fly when upgrading to the primary slot, as well as encrypted
@@ -287,6 +304,21 @@
 	  described under "ECIES-X25519 encryption" in docs/encrypted_images.md.
 endif # !SINGLE_APPLICATION_SLOT
 
+config BOOT_ENCRYPTION_KEY_FILE
+	string "encryption key file"
+    depends on BOOT_ENCRYPT_EC256 || BOOT_SERIAL_ENCRYPT_EC256
+	default "enc-ec256-priv.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256
+	default ""
+	help
+	  You can use either absolute or relative path.
+	  In case relative path is used, the build system assumes that it starts
+	  from the directory where the MCUBoot KConfig configuration file is
+	  located. If the key file is not there, the build system uses relative
+	  path that starts from the MCUBoot repository root directory.
+	  The key file will be parsed by imgtool's getpriv command and a .c source
+	  with the public key information will be written in a format expected by
+	  MCUboot.
+
 config BOOT_MAX_IMG_SECTORS
 	int "Maximum number of sectors per image slot"
 	default 128
@@ -308,7 +340,7 @@
 	bool "Save application specific data in shared memory area"
 	default n
 
-choice
+choice BOOT_FAULT_INJECTION_HARDENING_PROFILE
 	prompt "Fault injection hardening profile"
 	default BOOT_FIH_PROFILE_OFF
 
@@ -465,7 +497,7 @@
 
 if MCUBOOT_SERIAL
 
-choice
+choice BOOT_SERIAL_DEVICE
 	prompt "Serial device"
 	default BOOT_SERIAL_UART if !BOARD_NRF52840DONGLE_NRF52840
 	default BOOT_SERIAL_CDC_ACM if BOARD_NRF52840DONGLE_NRF52840
@@ -551,6 +583,11 @@
 	 on some hardware that has long erase times, to prevent long wait
 	 times at the beginning of the DFU process.
 
+config BOOT_MGMT_ECHO
+	bool "Enable echo command"
+	help
+	  if enabled, support for the mcumgr echo command is being added.
+
 menuconfig ENABLE_MGMT_PERUSER
 	bool "Enable system specific mcumgr commands"
 	help
@@ -576,6 +613,31 @@
 	  statuses (custom property) for all images.
 
 endif # ENABLE_MGMT_PERUSER
+
+config BOOT_SERIAL_ENCRYPT_EC256
+	bool "Support for encrypted upgrade images using ECIES-P256 in serial recovery upload"
+	default n
+	help
+	  If y, uploaded images via serial recovery can be decrypted
+	  on the fly when upgrading to the primary slot. The
+	  encryption mechanism used in this case is ECIES using primitives
+	  described under "ECIES-P256 encryption" in docs/encrypted_images.md.
+
+config BOOT_SERIAL_WAIT_FOR_DFU
+	bool "Wait for a prescribed duration to see if DFU is invoked by receiving a mcumgr comand"
+	depends on BOOT_SERIAL_UART
+	help
+	  If y, MCUboot waits for a prescribed duration of time to allow
+	  for DFU to be invoked. The serial recovery can be entered by receiving any
+	  mcumgr command.
+
+config BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT
+	int "Duration to wait for the serial DFU timeout in ms"
+	default 500
+	depends on BOOT_SERIAL_WAIT_FOR_DFU
+	help
+	  timeout in ms for MCUboot to wait to allow for DFU to be invoked.
+
 endif # MCUBOOT_SERIAL
 
 config BOOT_INTR_VEC_RELOC
@@ -594,7 +656,7 @@
 	help
 	  Enables support of multi image update.
 
-choice
+choice BOOT_DOWNGRADE_PREVENTION_CHOICE
 	prompt "Downgrade prevention"
 	optional
 
@@ -692,4 +754,22 @@
 	bool
 	default n
 
+config MCUBOOT_VERIFY_IMG_ADDRESS
+	bool "Verify reset address of image in secondary slot"
+	depends on UPDATEABLE_IMAGE_NUMBER > 1
+	depends on !BOOT_ENCRYPT_IMAGE
+	depends on ARM
+	default y if BOOT_UPGRADE_ONLY
+	help
+	  Verify that the reset address in the image located in the secondary slot
+	  is contained within the corresponding primary slot. This is recommended
+	  if swapping is not used (that is, BOOT_UPGRADE_ONLY is set). If a user
+	  incorrectly uploads an update for image 1 to image 0's secondary slot
+	  MCUboot will overwrite image 0's primary slot with this image even
+	  though it will not boot. If swapping is enabled this will be handled
+	  since the image will not confirm itself. If, however, swapping is not
+	  enabled then the only mitigation is serial recovery. This feature can
+	  also be useful when BOOT_DIRECT_XIP is enabled, to ensure that the image
+	  linked at the correct address is loaded.
+
 source "Kconfig.zephyr"
diff --git a/boot/zephyr/boards/actinius_icarus.conf b/boot/zephyr/boards/actinius_icarus.conf
index fc67561..f7bb068 100644
--- a/boot/zephyr/boards/actinius_icarus.conf
+++ b/boot/zephyr/boards/actinius_icarus.conf
@@ -1,7 +1,5 @@
 # Disable Zephyr console
 CONFIG_CONSOLE=n
-CONFIG_CONSOLE_HANDLER=n
-CONFIG_UART_CONSOLE=n
 
 # MCUBoot settings
 CONFIG_BOOT_MAX_IMG_SECTORS=256
diff --git a/boot/zephyr/boards/circuitdojo_feather_nrf9160.conf b/boot/zephyr/boards/circuitdojo_feather_nrf9160.conf
index 82aac4b..78d6a31 100644
--- a/boot/zephyr/boards/circuitdojo_feather_nrf9160.conf
+++ b/boot/zephyr/boards/circuitdojo_feather_nrf9160.conf
@@ -1,7 +1,5 @@
 # Disable Zephyr console
 CONFIG_CONSOLE=n
-CONFIG_CONSOLE_HANDLER=n
-CONFIG_UART_CONSOLE=n
 
 # Multithreading
 CONFIG_MULTITHREADING=y
diff --git a/boot/zephyr/boards/conexio_stratus.conf b/boot/zephyr/boards/conexio_stratus.conf
new file mode 100644
index 0000000..6bc5f8c
--- /dev/null
+++ b/boot/zephyr/boards/conexio_stratus.conf
@@ -0,0 +1,21 @@
+# Disable Zephyr console
+CONFIG_CONSOLE=n
+CONFIG_CONSOLE_HANDLER=n
+CONFIG_UART_CONSOLE=n
+
+# Multithreading
+CONFIG_MULTITHREADING=y
+
+# MCUBoot settings
+CONFIG_BOOT_MAX_IMG_SECTORS=256
+
+# MCUboot serial recovery
+CONFIG_MCUBOOT_SERIAL=y
+CONFIG_BOOT_SERIAL_DETECT_PORT="GPIO_0"
+CONFIG_BOOT_SERIAL_DETECT_PIN=12
+CONFIG_BOOT_SERIAL_DETECT_PIN_VAL=0
+CONFIG_BOOT_SERIAL_DETECT_DELAY=450
+CONFIG_MCUBOOT_INDICATION_LED=y
+
+# Size of mcuboot partition
+CONFIG_SIZE_OPTIMIZATIONS=y
diff --git a/boot/zephyr/boards/mimxrt1024_evk.conf b/boot/zephyr/boards/mimxrt1024_evk.conf
new file mode 100644
index 0000000..22e3320
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt1024_evk.conf
@@ -0,0 +1,4 @@
+# Copyright (c) 2021 Prevas A/S
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=512
diff --git a/boot/zephyr/boards/mimxrt685_evk_cm33.conf b/boot/zephyr/boards/mimxrt685_evk_cm33.conf
new file mode 100644
index 0000000..f93c663
--- /dev/null
+++ b/boot/zephyr/boards/mimxrt685_evk_cm33.conf
@@ -0,0 +1,4 @@
+# Copyright 2021 NXP
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_BOOT_MAX_IMG_SECTORS=8192
diff --git a/boot/zephyr/boards/nrf52_minimal_footprint.conf b/boot/zephyr/boards/nrf52_minimal_footprint.conf
index 81c0845..c315b44 100644
--- a/boot/zephyr/boards/nrf52_minimal_footprint.conf
+++ b/boot/zephyr/boards/nrf52_minimal_footprint.conf
@@ -25,7 +25,6 @@
 CONFIG_MAIN_STACK_SIZE=10240
 CONFIG_THREAD_STACK_INFO=n
 # CONFIG_TICKLESS_KERNEL is not set
-CONFIG_SYSTEM_CLOCK_DISABLE=y
 CONFIG_FLASH=y
 
 CONFIG_CONSOLE=n
@@ -60,7 +59,6 @@
 CONFIG_BOOT_DELAY=0
 
 # Console
-CONFIG_UART_CONSOLE=n
 CONFIG_STDOUT_CONSOLE=n
 
 # Build
diff --git a/boot/zephyr/boards/sparkfun_thing_plus_nrf9160.conf b/boot/zephyr/boards/sparkfun_thing_plus_nrf9160.conf
index 82aac4b..78d6a31 100644
--- a/boot/zephyr/boards/sparkfun_thing_plus_nrf9160.conf
+++ b/boot/zephyr/boards/sparkfun_thing_plus_nrf9160.conf
@@ -1,7 +1,5 @@
 # Disable Zephyr console
 CONFIG_CONSOLE=n
-CONFIG_CONSOLE_HANDLER=n
-CONFIG_UART_CONSOLE=n
 
 # Multithreading
 CONFIG_MULTITHREADING=y
diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf
index 754bf7b..8e29a8b 100644
--- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf
+++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf
@@ -1,6 +1,5 @@
 CONFIG_SIZE_OPTIMIZATIONS=y
 
-CONFIG_SYSTEM_CLOCK_DISABLE=y
 CONFIG_SYSTEM_CLOCK_NO_WAIT=y
 CONFIG_PM=n
 
@@ -33,17 +32,10 @@
 CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
 CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
 
-CONFIG_PM_EXTERNAL_FLASH_SUPPORT_LEGACY=y
-CONFIG_PM_EXTERNAL_FLASH=y
-CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R64"
-CONFIG_PM_EXTERNAL_FLASH_BASE=0x0
-CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000
-
 # Required by USB and QSPI
 CONFIG_MULTITHREADING=y
 
 # USB
-CONFIG_USB=y
 CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA"
 CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53"
 CONFIG_USB_DEVICE_VID=0x1915
diff --git a/boot/zephyr/boot_serial_extensions.c b/boot/zephyr/boot_serial_extensions.c
index 49bb4ea..763dedb 100644
--- a/boot/zephyr/boot_serial_extensions.c
+++ b/boot/zephyr/boot_serial_extensions.c
@@ -19,7 +19,7 @@
 #include "bootutil/bootutil_public.h"
 #include "bootutil/boot_hooks.h"
 
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
 
 #ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
 static int bs_custom_storage_erase(cbor_state_t *cs)
@@ -31,11 +31,11 @@
     rc = flash_area_open(FLASH_AREA_ID(storage), &fa);
 
     if (rc < 0) {
-        LOG_ERR("failed to open flash area");
+        BOOT_LOG_ERR("failed to open flash area");
     } else {
         rc = flash_area_erase(fa, 0, FLASH_AREA_SIZE(storage));
         if (rc < 0) {
-            LOG_ERR("failed to erase flash area");
+            BOOT_LOG_ERR("failed to erase flash area");
         }
         flash_area_close(fa);
     }
diff --git a/boot/zephyr/include/config-ec.h b/boot/zephyr/include/config-ec.h
index 3b11295..924d633 100644
--- a/boot/zephyr/include/config-ec.h
+++ b/boot/zephyr/include/config-ec.h
@@ -65,6 +65,7 @@
 #define MBEDTLS_MD_C
 #define MBEDTLS_OID_C
 #define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
 #define MBEDTLS_SHA224_C
 #define MBEDTLS_AES_C
 
diff --git a/boot/zephyr/include/config-ed25519.h b/boot/zephyr/include/config-ed25519.h
index 7e43708..95b299e 100644
--- a/boot/zephyr/include/config-ed25519.h
+++ b/boot/zephyr/include/config-ed25519.h
@@ -60,6 +60,7 @@
 #define MBEDTLS_MD_C
 #define MBEDTLS_OID_C
 #define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
 #define MBEDTLS_SHA224_C
 #define MBEDTLS_SHA512_C
 #define MBEDTLS_AES_C
diff --git a/boot/zephyr/include/config-kw.h b/boot/zephyr/include/config-kw.h
index 168e56e..76d5da7 100644
--- a/boot/zephyr/include/config-kw.h
+++ b/boot/zephyr/include/config-kw.h
@@ -57,6 +57,7 @@
 #define MBEDTLS_CIPHER_MODE_CTR
 
 #define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
 #define MBEDTLS_SHA224_C
 #define MBEDTLS_AES_C
 #define MBEDTLS_CIPHER_C
diff --git a/boot/zephyr/include/config-rsa-kw.h b/boot/zephyr/include/config-rsa-kw.h
index bc3da7d..b5218dd 100644
--- a/boot/zephyr/include/config-rsa-kw.h
+++ b/boot/zephyr/include/config-rsa-kw.h
@@ -63,6 +63,7 @@
 #define MBEDTLS_MD_C
 #define MBEDTLS_OID_C
 #define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
 #define MBEDTLS_SHA224_C
 #define MBEDTLS_AES_C
 #define MBEDTLS_CIPHER_C
diff --git a/boot/zephyr/include/config-rsa.h b/boot/zephyr/include/config-rsa.h
index 0552420..f07c457 100644
--- a/boot/zephyr/include/config-rsa.h
+++ b/boot/zephyr/include/config-rsa.h
@@ -64,6 +64,7 @@
 #define MBEDTLS_MD_C
 #define MBEDTLS_OID_C
 #define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
 #define MBEDTLS_SHA224_C
 #define MBEDTLS_AES_C
 
diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
index 2bab537..02bf0b0 100644
--- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h
+++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
@@ -25,6 +25,7 @@
 #include "config-rsa.h"
 #elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \
       defined(CONFIG_BOOT_ENCRYPT_EC256) || \
+      defined(CONFIG_BOOT_SERIAL_ENCRYPT_EC256) || \
       (defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519))
 #include "config-asn1.h"
 #elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)
diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
index 7061fc1..c2d6672 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -61,6 +61,10 @@
 #define MCUBOOT_VALIDATE_PRIMARY_SLOT
 #endif
 
+#ifdef CONFIG_BOOT_VALIDATE_SLOT0_ONCE
+#define MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE
+#endif
+
 #ifdef CONFIG_BOOT_UPGRADE_ONLY
 #define MCUBOOT_OVERWRITE_ONLY
 #define MCUBOOT_OVERWRITE_ONLY_FAST
@@ -109,6 +113,11 @@
 #define MCUBOOT_ENCRYPT_EC256
 #endif
 
+#ifdef CONFIG_BOOT_SERIAL_ENCRYPT_EC256
+#define MCUBOOT_ENC_IMAGES
+#define MCUBOOT_ENCRYPT_EC256
+#endif
+
 #ifdef CONFIG_BOOT_ENCRYPT_X25519
 #define MCUBOOT_ENC_IMAGES
 #define MCUBOOT_ENCRYPT_X25519
@@ -164,10 +173,18 @@
 #define MCUBOOT_MGMT_CUSTOM_IMG_LIST
 #endif
 
+#ifdef CONFIG_BOOT_MGMT_ECHO
+#define MCUBOOT_BOOT_MGMT_ECHO
+#endif
+
 #ifdef CONFIG_BOOT_IMAGE_ACCESS_HOOKS
 #define MCUBOOT_IMAGE_ACCESS_HOOKS
 #endif
 
+#ifdef CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS
+#define MCUBOOT_VERIFY_IMG_ADDRESS
+#endif
+
 /*
  * The configuration option enables direct image upload with the
  * serial recovery.
@@ -176,6 +193,10 @@
 #define MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
 #endif
 
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+#define MCUBOOT_SERIAL_WAIT_FOR_DFU
+#endif
+
 /*
  * The option enables code, currently in boot_serial, that attempts
  * to erase flash progressively, as update fragments are received,
@@ -185,7 +206,7 @@
  * for the time needed to erase large chunk of flash.
  */
 #ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
-#define MCBOOT_ERASE_PROGRESSIVELY
+#define MCUBOOT_ERASE_PROGRESSIVELY
 #endif
 
 /*
@@ -240,13 +261,24 @@
 #error "No NRFX WDT instances enabled"
 #endif /* defined(CONFIG_NRFX_WDT0) && defined(CONFIG_NRFX_WDT1) */
 
-#else /* CONFIG_NRFX_WDT */
+#elif CONFIG_IWDG_STM32 /* CONFIG_NRFX_WDT */
+#include <drivers/watchdog.h>
+
+#define MCUBOOT_WATCHDOG_FEED() \
+    do {                        \
+        const struct device* wdt =                          \
+            device_get_binding(                             \
+                DT_LABEL(DT_INST(0, st_stm32_watchdog)));   \
+        wdt_feed(wdt, 0);                                   \
+    } while (0)
+
+#else /* CONFIG_IWDG_STM32 */
 #warning "MCUBOOT_WATCHDOG_FEED() is no-op"
 /* No vendor implementation, no-op for historical reasons */
 #define MCUBOOT_WATCHDOG_FEED()         \
     do {                                \
     } while (0)
-#endif /* CONFIG_NRFX_WDT */
+#endif
 #else  /* CONFIG_BOOT_WATCHDOG_FEED */
 /* Not enabled, no feed activity */
 #define MCUBOOT_WATCHDOG_FEED()         \
diff --git a/boot/zephyr/include/single_loader.h b/boot/zephyr/include/single_loader.h
new file mode 100644
index 0000000..e762d15
--- /dev/null
+++ b/boot/zephyr/include/single_loader.h
@@ -0,0 +1,20 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2021-2021 Crodeon Technologies
+ *
+ */
+
+#ifndef H_SINGLE_LOADER_
+#define H_SINGLE_LOADER_
+#include "bootutil/fault_injection_hardening.h"
+
+/**
+ * Handle an encrypted firmware in the main flash.
+ * This will decrypt the image inplace
+ */
+int boot_handle_enc_fw();
+
+fih_int boot_image_validate(const struct flash_area *fa_p,
+                    struct image_header *hdr);
+#endif
diff --git a/boot/zephyr/keys.c b/boot/zephyr/keys.c
index 7214748..b7a9edf 100644
--- a/boot/zephyr/keys.c
+++ b/boot/zephyr/keys.c
@@ -186,15 +186,8 @@
     .len = &enc_priv_key_len,
 };
 #elif defined(MCUBOOT_ENCRYPT_EC256)
-unsigned char enc_priv_key[] = {
-  0x30, 0x81, 0x43, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-  0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-  0x03, 0x01, 0x07, 0x04, 0x29, 0x30, 0x27, 0x02, 0x01, 0x01, 0x04, 0x20,
-  0xf6, 0x1e, 0x51, 0x9d, 0xf8, 0xfa, 0xdd, 0xa1, 0xb7, 0xd9, 0xa9, 0x64,
-  0x64, 0x3b, 0x54, 0xd0, 0x3d, 0xd0, 0x1f, 0xe5, 0x78, 0xd9, 0x17, 0x98,
-  0xa5, 0x28, 0xca, 0xcc, 0x6b, 0x67, 0x9e, 0x06, 0xa1, 0x44,
-};
-static unsigned int enc_priv_key_len = 70;
+extern const unsigned char enc_priv_key[];
+extern unsigned int enc_priv_key_len;
 const struct bootutil_key bootutil_enc_key = {
     .key = enc_priv_key,
     .len = &enc_priv_key_len,
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index ab3b262..cee7505 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -86,17 +86,13 @@
 #endif /* defined(CONFIG_LOG) && !defined(CONFIG_LOG_IMMEDIATE) */
 
 #ifdef CONFIG_SOC_FAMILY_NRF
-#include <hal/nrf_power.h>
+#include <helpers/nrfx_reset_reason.h>
 
 static inline bool boot_skip_serial_recovery()
 {
-#if NRF_POWER_HAS_RESETREAS
-    uint32_t rr = nrf_power_resetreas_get(NRF_POWER);
+    uint32_t rr = nrfx_reset_reason_get();
 
-    return !(rr == 0 || (rr & NRF_POWER_RESETREAS_RESETPIN_MASK));
-#else
-    return false;
-#endif
+    return !(rr == 0 || (rr & NRFX_RESET_REASON_RESETPIN_MASK));
 }
 #else
 static inline bool boot_skip_serial_recovery()
@@ -163,8 +159,6 @@
     uint32_t reset;
 };
 
-extern void sys_clock_disable(void);
-
 static void do_boot(struct boot_rsp *rsp)
 {
     struct arm_vector_table *vt;
@@ -183,9 +177,8 @@
                                      rsp->br_image_off +
                                      rsp->br_hdr->ih_hdr_size);
 
-#ifdef CONFIG_SYS_CLOCK_EXISTS
     sys_clock_disable();
-#endif
+
 #ifdef CONFIG_USB_DEVICE_STACK
     /* Disable the USB to prevent it from firing interrupts */
     usb_disable();
@@ -513,7 +506,28 @@
     }
 #endif
 
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+    /* Initialize the boot console, so we can already fill up our buffers while
+     * waiting for the boot image check to finish. This image check, can take
+     * some time, so it's better to reuse thistime to already receive the
+     * initial mcumgr command(s) into our buffers
+     */
+    rc = boot_console_init();
+    int timeout_in_ms = CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT;
+    uint32_t start = k_uptime_get_32();
+#endif
+
     FIH_CALL(boot_go, fih_rc, &rsp);
+
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+    timeout_in_ms -= (k_uptime_get_32() - start);
+    if( timeout_in_ms <= 0 ) {
+        /* at least one check if time was expired */
+        timeout_in_ms = 1;
+    }
+   boot_serial_check_start(&boot_funcs,timeout_in_ms);
+#endif
+
     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
         BOOT_LOG_ERR("Unable to find bootable image");
         FIH_PANIC;
diff --git a/boot/zephyr/os.c b/boot/zephyr/os.c
index eaa60b4..4721eb1 100644
--- a/boot/zephyr/os.c
+++ b/boot/zephyr/os.c
@@ -41,7 +41,7 @@
 #define CRYPTO_HEAP_SIZE 6144
 #else
 #  if !defined(MBEDTLS_RSA_NO_CRT)
-#  define CRYPTO_HEAP_SIZE 10240
+#  define CRYPTO_HEAP_SIZE 12032
 #  else
 #  define CRYPTO_HEAP_SIZE 16384
 #  endif
diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf
index a9de580..e4c0129 100644
--- a/boot/zephyr/prj.conf
+++ b/boot/zephyr/prj.conf
@@ -1,6 +1,4 @@
-CONFIG_CONSOLE_HANDLER=y
 CONFIG_DEBUG=y
-CONFIG_SYSTEM_CLOCK_DISABLE=y
 CONFIG_PM=n
 
 CONFIG_MAIN_STACK_SIZE=10240
diff --git a/boot/zephyr/single_loader.c b/boot/zephyr/single_loader.c
index af2d398..f6c65f6 100644
--- a/boot/zephyr/single_loader.c
+++ b/boot/zephyr/single_loader.c
@@ -19,7 +19,7 @@
 static const struct flash_area *_fa_p;
 static struct image_header _hdr = { 0 };
 
-#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
+#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) || defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
 /**
  * Validate hash of a primary boot image.
  *
@@ -28,7 +28,7 @@
  *
  * @return		FIH_SUCCESS on success, error code otherwise
  */
-inline static fih_int
+fih_int
 boot_image_validate(const struct flash_area *fa_p,
                     struct image_header *hdr)
 {
@@ -41,14 +41,54 @@
      * the pointer from compilation.
      */
     /* Validate hash */
+    if (IS_ENCRYPTED(hdr))
+    {
+        /* Clear the encrypted flag we didn't supply a key
+         * This flag could be set if there was a decryption in place
+         * was performed. We will try to validate the image, and if still
+         * encrypted the validation will fail, and go in panic mode
+         */
+        hdr->ih_flags &= ~(ENCRYPTIONFLAGS);
+    }
     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, hdr, fa_p, tmpbuf,
              BOOT_TMPBUF_SZ, NULL, 0, NULL);
 
     FIH_RET(fih_rc);
 }
-#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */
+#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
 
 
+inline static fih_int
+boot_image_validate_once(const struct flash_area *fa_p,
+                    struct image_header *hdr)
+{
+    static struct boot_swap_state state;
+    int rc;
+    fih_int fih_rc = FIH_FAILURE;
+
+    memset(&state, 0, sizeof(struct boot_swap_state));
+    rc = boot_read_swap_state(fa_p, &state);
+    if (rc != 0)
+        FIH_RET(FIH_FAILURE);
+    if (state.magic != BOOT_MAGIC_GOOD
+            || state.image_ok != BOOT_FLAG_SET) {
+        /* At least validate the image once */
+        FIH_CALL(boot_image_validate, fih_rc, fa_p, hdr);
+        if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+            FIH_RET(FIH_FAILURE);
+        }
+        if (state.magic != BOOT_MAGIC_GOOD) {
+            rc = boot_write_magic(fa_p);
+            if (rc != 0)
+                FIH_RET(FIH_FAILURE);
+        }
+        rc = boot_write_image_ok(fa_p);
+        if (rc != 0)
+            FIH_RET(FIH_FAILURE);
+    }
+    FIH_RET(FIH_SUCCESS);
+}
+
 /**
  * Attempts to load image header from flash; verifies flash header fields.
  *
@@ -90,6 +130,307 @@
     return 0;
 }
 
+#ifdef MCUBOOT_ENC_IMAGES
+
+/**
+ * Validate hash of a primary boot image doing on the fly decryption as well
+ *
+ * @param[in]	fa_p	flash area pointer
+ * @param[in]	hdr	boot image header pointer
+ *
+ * @return		FIH_SUCCESS on success, error code otherwise
+ */
+inline static fih_int
+boot_image_validate_encrypted(const struct flash_area *fa_p,
+                    struct image_header *hdr)
+{
+    static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
+    fih_int fih_rc = FIH_FAILURE;
+
+    struct boot_loader_state boot_data;
+    struct boot_loader_state *state = &boot_data;
+    struct boot_status _bs;
+    struct boot_status *bs = &_bs;
+    uint8_t image_index;
+    int rc;
+
+    memset(&boot_data, 0, sizeof(struct boot_loader_state));
+    image_index = BOOT_CURR_IMG(state);
+    if (MUST_DECRYPT(fa_p, image_index, hdr)) {
+        rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
+        if (rc < 0) {
+            FIH_RET(fih_rc);
+        }
+        if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
+            FIH_RET(fih_rc);
+        }
+    }
+    FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
+             hdr, fa_p, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL);
+
+    FIH_RET(fih_rc);
+}
+
+/*
+ * Compute the total size of the given image.  Includes the size of
+ * the TLVs.
+ */
+static int
+read_image_size(const struct flash_area *fa_p,
+        struct image_header *hdr,
+        uint32_t *size)
+{
+    struct image_tlv_info info;
+    uint32_t off;
+    uint32_t protect_tlv_size;
+    int rc;
+
+    off = BOOT_TLV_OFF(hdr);
+
+    if (flash_area_read(fa_p, off, &info, sizeof(info))) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    protect_tlv_size = hdr->ih_protect_tlv_size;
+    if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
+        if (protect_tlv_size != info.it_tlv_tot) {
+            rc = BOOT_EBADIMAGE;
+            goto done;
+        }
+
+        if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) {
+            rc = BOOT_EFLASH;
+            goto done;
+        }
+    } else if (protect_tlv_size != 0) {
+        rc = BOOT_EBADIMAGE;
+        goto done;
+    }
+
+    if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
+        rc = BOOT_EBADIMAGE;
+        goto done;
+    }
+
+    *size = off + protect_tlv_size + info.it_tlv_tot;
+    rc = 0;
+
+done:
+    return rc;
+}
+
+
+/* Get the SOC's flash erase block size from the DTS, fallback to 1024. */
+#define SOC_FLASH_ERASE_BLK_SZ \
+         DT_PROP_OR(DT_CHOSEN(zephyr_flash), erase_block_size,1024)
+
+/**
+ * reads, decrypts in RAM & write back the decrypted image in the same region
+ * This function is NOT power failsafe since the image is decrypted in the RAM
+ * buffer.
+ *
+ * @param flash_area            The ID of the source flash area.
+ * @param off_src               The offset within the flash area to
+ *                                  copy from.
+ * @param sz                    The number of bytes to copy. should match erase sector
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+decrypt_region_inplace(struct boot_loader_state *state,
+                 const struct flash_area *fap,
+                 struct image_header *hdr,
+                 uint32_t off, uint32_t sz)
+{
+    uint32_t bytes_copied;
+    int chunk_sz;
+    int rc;
+    uint32_t tlv_off;
+    size_t blk_off;
+    uint16_t idx;
+    uint32_t blk_sz;
+    uint8_t image_index;
+
+    static uint8_t buf[SOC_FLASH_ERASE_BLK_SZ] __attribute__((aligned));
+    assert(sz <= sizeof buf);
+
+    bytes_copied = 0;
+    while (bytes_copied < sz) {
+        if (sz - bytes_copied > sizeof buf) {
+            chunk_sz = sizeof buf;
+        } else {
+            chunk_sz = sz - bytes_copied;
+        }
+
+        rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz);
+        if (rc != 0) {
+            return BOOT_EFLASH;
+        }
+
+        image_index = BOOT_CURR_IMG(state);
+        if (IS_ENCRYPTED(hdr)) {
+            blk_sz = chunk_sz;
+            idx = 0;
+            if (off + bytes_copied < hdr->ih_hdr_size) {
+                /* do not decrypt header */
+                if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) {
+                    /* all bytes in header, skip decryption */
+                    blk_sz = 0;
+                }
+                else {
+                    blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size;
+                }
+
+                blk_off = 0;
+                idx = hdr->ih_hdr_size;
+            } else {
+                blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf;
+            }
+            tlv_off = BOOT_TLV_OFF(hdr);
+            if (off + bytes_copied + chunk_sz > tlv_off) {
+                /* do not decrypt TLVs */
+                if (off + bytes_copied >= tlv_off) {
+                    blk_sz = 0;
+                } else {
+                    blk_sz = tlv_off - (off + bytes_copied);
+                }
+            }
+            boot_encrypt(BOOT_CURR_ENC(state), image_index, fap,
+                    (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
+                    blk_off, &buf[idx]);
+        }
+        rc = flash_area_erase(fap, off + bytes_copied, chunk_sz);
+        if (rc != 0) {
+            return BOOT_EFLASH;
+        }
+        rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz);
+        if (rc != 0) {
+            return BOOT_EFLASH;
+        }
+
+        bytes_copied += chunk_sz;
+
+        MCUBOOT_WATCHDOG_FEED();
+    }
+
+    return 0;
+}
+
+/**
+ * Check if a image was encrypted into the first slot, and decrypt it
+ * in place. this operation is not power failsafe.
+ *
+ * The operation is done by checking the last flash sector, and using it as a
+ * temporarely scratch partition. The
+ *
+ * @param[in]	fa_p	flash area pointer
+ * @param[in]	hdr	boot image header pointer
+ *
+ * @return		FIH_SUCCESS on success, error code otherwise
+ */
+inline static fih_int
+decrypt_image_inplace(const struct flash_area *fa_p,
+                     struct image_header *hdr)
+{
+    fih_int fih_rc = FIH_FAILURE;
+    int rc;
+    struct boot_loader_state boot_data;
+    struct boot_loader_state *state = &boot_data;
+    struct boot_status _bs;
+    struct boot_status *bs = &_bs;
+    size_t size;
+    size_t sect_size;
+    size_t sect_count;
+    size_t sect;
+    uint8_t image_index;
+    struct flash_sector sector;
+
+    memset(&boot_data, 0, sizeof(struct boot_loader_state));
+    memset(&_bs, 0, sizeof(struct boot_status));
+
+    /* Get size from last sector to know page/sector erase size */
+    rc = flash_area_sector_from_off(boot_status_off(fa_p), &sector);
+
+
+    image_index = BOOT_CURR_IMG(state);
+
+    if (MUST_DECRYPT(fa_p, image_index, hdr)) {
+#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly
+         /* First check if the encrypted image is a good image before decrypting */
+        FIH_CALL(boot_image_validate_encrypted,fih_rc,_fa_p,&_hdr);
+        if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+             FIH_RET(fih_rc);
+        }
+#endif
+        memset(&boot_data, 0, sizeof(struct boot_loader_state));
+        /* Load the encryption keys into cache */
+        rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
+        if (rc < 0) {
+            FIH_RET(fih_rc);
+        }
+        if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
+            FIH_RET(fih_rc);
+        }
+    }
+    else
+    {
+        /* Expected encrypted image! */
+        FIH_RET(fih_rc);
+    }
+
+    uint32_t src_size = 0;
+    rc = read_image_size(fa_p,hdr, &src_size);
+    if (rc != 0) {
+        FIH_RET(fih_rc);
+    }
+
+    sect_size = sector.fs_size;
+    sect_count = fa_p->fa_size / sect_size;
+    for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) {
+        rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size);
+        if (rc != 0) {
+            FIH_RET(fih_rc);
+        }
+        size += sect_size;
+    }
+
+    fih_rc = FIH_SUCCESS;
+    FIH_RET(fih_rc);
+}
+
+int
+boot_handle_enc_fw()
+{
+    int rc = -1;
+    fih_int fih_rc = FIH_FAILURE;
+
+    rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
+    assert(rc == 0);
+
+    rc = boot_image_load_header(_fa_p, &_hdr);
+    if (rc != 0) {
+        goto out;
+    }
+
+    if (IS_ENCRYPTED(&_hdr)) {
+        //encrypted, we need to decrypt in place
+        FIH_CALL(decrypt_image_inplace,fih_rc,_fa_p,&_hdr);
+        if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+            rc = -1;
+            goto out;
+        }
+    }
+    else
+    {
+        rc = 0;
+    }
+
+out:
+    flash_area_close(_fa_p);
+    return rc;
+}
+#endif
 
 /**
  * Gather information on image and prepare for booting.
@@ -116,6 +457,11 @@
     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
         goto out;
     }
+#elif defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
+    FIH_CALL(boot_image_validate_once, fih_rc, _fa_p, &_hdr);
+    if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+        goto out;
+    }
 #else
     fih_rc = FIH_SUCCESS;
 #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */