boot: boot_serial: Fix issue with encrypted second slot images

Fixes issues whereby encrypted images were not properly listed due
to not treating them as encrypted, also removes a piece of wrong
hack code that would never run as the primary slot cannot be
encrypted.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
diff --git a/boot/boot_serial/include/boot_serial/boot_serial_encryption.h b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h
new file mode 100644
index 0000000..b7cf9ff
--- /dev/null
+++ b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2023 Nordic Semiconductor ASA
+ */
+
+#ifndef H_BOOT_SERIAL_ENCRYPTION_
+#define H_BOOT_SERIAL_ENCRYPTION_
+#include "bootutil/fault_injection_hardening.h"
+
+/**
+ * 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
+ * @param[in]   buf       buffer which is used for validating data
+ * @param[in]   buf_size  size of input buffer
+ *
+ * @return                FIH_SUCCESS on success, error code otherwise
+ */
+fih_ret
+boot_image_validate_encrypted(const struct flash_area *fa_p,
+                              struct image_header *hdr, uint8_t *buf,
+                              uint16_t buf_size);
+
+/**
+ * Handle an encrypted firmware in the main flash.
+ * This will decrypt the image inplace
+ */
+int boot_handle_enc_fw(const struct flash_area *flash_area);
+
+#endif
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index 7f6af91..cddf8e2 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -73,7 +73,7 @@
 #endif
 
 #ifdef MCUBOOT_ENC_IMAGES
-#include "single_loader.h"
+#include "boot_serial/boot_serial_encryption.h"
 #endif
 
 #include "bootutil/boot_hooks.h"
@@ -293,18 +293,16 @@
                 if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
                 {
 #ifdef MCUBOOT_ENC_IMAGES
-                    if (slot == 0 && 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
-                        * performed before. We will try to validate the image without
-                        * decryption by clearing the flag in the heder. If
-                        * still encrypted the validation will fail.
-                        */
-                        hdr.ih_flags &= ~(ENCRYPTIONFLAGS);
+                    if (IS_ENCRYPTED(&hdr)) {
+                        FIH_CALL(boot_image_validate_encrypted, fih_rc, fap,
+                                 &hdr, tmpbuf, sizeof(tmpbuf));
+                    } else {
+#endif
+                        FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr,
+                                 fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
+#ifdef MCUBOOT_ENC_IMAGES
                     }
 #endif
-                    FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
-                                    NULL, 0, NULL);
                 }
             }
 
@@ -483,8 +481,17 @@
                                    fih_rc, image_index, 1);
                 if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
                 {
-                    FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap,
-                             tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
+#ifdef MCUBOOT_ENC_IMAGES
+                    if (IS_ENCRYPTED(&hdr)) {
+                        FIH_CALL(boot_image_validate_encrypted, fih_rc, fap,
+                                 &hdr, tmpbuf, sizeof(tmpbuf));
+                    } else {
+#endif
+                        FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr,
+                                 fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
+#ifdef MCUBOOT_ENC_IMAGES
+                    }
+#endif
                 }
 
                 if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
@@ -862,14 +869,23 @@
     zcbor_map_end_encode(cbor_state, 10);
 
     boot_serial_output();
-    flash_area_close(fap);
 
 #ifdef MCUBOOT_ENC_IMAGES
-    if (curr_off == img_size) {
-        /* Last sector received, now start a decryption on the image if it is encrypted*/
-        rc = boot_handle_enc_fw();
+    /* Check if this upload was for the primary slot */
+#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
+    if (flash_area_id_from_multi_image_slot(img_num, 0) == FLASH_AREA_IMAGE_PRIMARY(0))
+#else
+    if (flash_area_id_from_direct_image(img_num) == FLASH_AREA_IMAGE_PRIMARY(0))
+#endif
+    {
+        if (curr_off == img_size) {
+            /* Last sector received, now start a decryption on the image if it is encrypted */
+            rc = boot_handle_enc_fw(fap);
+        }
     }
-#endif //#ifdef MCUBOOT_ENC_IMAGES
+#endif
+
+    flash_area_close(fap);
 }
 
 #ifdef MCUBOOT_BOOT_MGMT_ECHO
diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c
new file mode 100644
index 0000000..6201e6b
--- /dev/null
+++ b/boot/boot_serial/src/boot_serial_encryption.c
@@ -0,0 +1,315 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2020-2023 Nordic Semiconductor ASA
+ * Copyright (c) 2020 Arm Limited
+ */
+
+#include <assert.h>
+#include "bootutil/image.h"
+#include <../src/bootutil_priv.h>
+#include "bootutil/bootutil_log.h"
+#include "bootutil/bootutil_public.h"
+#include "bootutil/fault_injection_hardening.h"
+#include "bootutil/enc_key.h"
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#ifdef MCUBOOT_ENC_IMAGES
+
+BOOT_LOG_MODULE_DECLARE(serial_encryption);
+
+fih_ret
+boot_image_validate_encrypted(const struct flash_area *fa_p,
+                              struct image_header *hdr, uint8_t *buf,
+                              uint16_t buf_size)
+{
+    FIH_DECLARE(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(IS_ENCRYPTED(hdr)) {
+        rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
+        if (rc < 0) {
+            FIH_RET(fih_rc);
+        }
+        rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fa_p));
+        if (rc < 0) {
+            FIH_RET(fih_rc);
+        }
+        rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs);
+        if (rc < 0) {
+            FIH_RET(fih_rc);
+        }
+    }
+    FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
+             hdr, fa_p, buf, buf_size, 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;
+}
+
+/**
+ * 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.
+ */
+static 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;
+
+    uint8_t buf[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_ret
+decrypt_image_inplace(const struct flash_area *fa_p,
+                     struct image_header *hdr)
+{
+    FIH_DECLARE(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_get_sector(fa_p, boot_status_off(fa_p), &sector);
+
+
+    image_index = BOOT_CURR_IMG(state);
+
+    if(IS_ENCRYPTED(hdr)) {
+#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly
+        static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
+         /* First check if the encrypted image is a good image before decrypting */
+        FIH_CALL(boot_image_validate_encrypted,fih_rc,fa_p,&_hdr,tmpbuf,BOOT_TMPBUF_SZ);
+        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);
+    }
+
+    /* TODO: This assumes every sector has an equal size, should instead use
+     * flash_area_get_sectors() to get the size of each sector and iterate
+     * over it.
+     */
+    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(const struct flash_area *flash_area)
+{
+    int rc = -1;
+    struct image_header _hdr = { 0 };
+    FIH_DECLARE(fih_rc, FIH_FAILURE);
+
+    rc = boot_image_load_header(flash_area, &_hdr);
+    if (rc != 0) {
+        goto out;
+    }
+
+    if (IS_ENCRYPTED(&_hdr)) {
+        //encrypted, we need to decrypt in place
+        FIH_CALL(decrypt_image_inplace,fih_rc,flash_area,&_hdr);
+        if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
+            rc = -1;
+            goto out;
+        }
+    }
+    else
+    {
+        rc = 0;
+    }
+
+out:
+    return rc;
+}
+
+#endif
diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h
index 90b1a1c..e8d83a1 100644
--- a/boot/bootutil/include/bootutil/bootutil_public.h
+++ b/boot/bootutil/include/bootutil/bootutil_public.h
@@ -43,6 +43,7 @@
 #include <string.h>
 #include <flash_map_backend/flash_map_backend.h>
 #include <mcuboot_config/mcuboot_config.h>
+#include <bootutil/image.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -294,6 +295,18 @@
 int
 boot_set_next(const struct flash_area *fa, bool active, bool confirm);
 
+/**
+ * Attempts to load image header from flash; verifies flash header fields.
+ *
+ * @param[in]   fa_p    flash area pointer
+ * @param[out]  hdr     buffer for image header
+ *
+ * @return              0 on success, error code otherwise
+ */
+int
+boot_image_load_header(const struct flash_area *fa_p,
+                       struct image_header *hdr);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boot/bootutil/src/bootutil_public.c b/boot/bootutil/src/bootutil_public.c
index f245739..8e70086 100644
--- a/boot/bootutil/src/bootutil_public.c
+++ b/boot/bootutil/src/bootutil_public.c
@@ -643,3 +643,36 @@
 {
     return boot_set_confirmed_multi(0);
 }
+
+int
+boot_image_load_header(const struct flash_area *fa_p,
+                       struct image_header *hdr)
+{
+    uint32_t size;
+    int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
+
+    if (rc != 0) {
+        rc = BOOT_EFLASH;
+        BOOT_LOG_ERR("Failed reading image header");
+	return BOOT_EFLASH;
+    }
+
+    if (hdr->ih_magic != IMAGE_MAGIC) {
+        BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
+
+        return BOOT_EBADIMAGE;
+    }
+
+    if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
+        BOOT_LOG_ERR("Image not bootable");
+
+        return BOOT_EBADIMAGE;
+    }
+
+    if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
+        size >= flash_area_get_size(fa_p)) {
+        return BOOT_EBADIMAGE;
+    }
+
+    return 0;
+}
diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index d9d474e..d15977e 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -130,7 +130,7 @@
   )
 endif()
 
-if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
+if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256)
   zephyr_library_include_directories(
     ${MBEDTLS_ASN1_DIR}/include
     )
@@ -219,7 +219,7 @@
   )
 endif()
 
-if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
+if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519)
   zephyr_library_sources(
     ${TINYCRYPT_DIR}/source/aes_encrypt.c
     ${TINYCRYPT_DIR}/source/aes_decrypt.c
@@ -248,6 +248,12 @@
     CONFIG_BOOT_ERASE_PROGRESSIVELY
     ${BOOT_DIR}/bootutil/src
     )
+
+  if(CONFIG_BOOT_ENCRYPT_IMAGE)
+    zephyr_library_sources(
+      ${BOOT_DIR}/boot_serial/src/boot_serial_encryption.c
+    )
+  endif()
 endif()
 
 if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery
index 63306ac..52ec3b0 100644
--- a/boot/zephyr/Kconfig.serial_recovery
+++ b/boot/zephyr/Kconfig.serial_recovery
@@ -136,15 +136,6 @@
 
 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.
-
 menu "Entrance methods"
 
 menuconfig BOOT_SERIAL_ENTRANCE_GPIO
diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
index 02bf0b0..2bab537 100644
--- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h
+++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
@@ -25,7 +25,6 @@
 #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 31cd916..e20003b 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -117,11 +117,6 @@
 #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
diff --git a/boot/zephyr/include/single_loader.h b/boot/zephyr/include/single_loader.h
deleted file mode 100644
index 347fa09..0000000
--- a/boot/zephyr/include/single_loader.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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_ret boot_image_validate(const struct flash_area *fa_p,
-                    struct image_header *hdr);
-#endif
diff --git a/boot/zephyr/single_loader.c b/boot/zephyr/single_loader.c
index 86d5052..5d1e76f 100644
--- a/boot/zephyr/single_loader.c
+++ b/boot/zephyr/single_loader.c
@@ -9,6 +9,7 @@
 #include "bootutil/image.h"
 #include "bootutil_priv.h"
 #include "bootutil/bootutil_log.h"
+#include "bootutil/bootutil_public.h"
 #include "bootutil/fault_injection_hardening.h"
 
 #include "mcuboot_config/mcuboot_config.h"
@@ -57,7 +58,6 @@
 }
 #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
 
-
 inline static fih_ret
 boot_image_validate_once(const struct flash_area *fa_p,
                     struct image_header *hdr)
@@ -90,349 +90,6 @@
 }
 
 /**
- * Attempts to load image header from flash; verifies flash header fields.
- *
- * @param[in]	fa_p	flash area pointer
- * @param[out] 	hdr	buffer for image header
- *
- * @return		0 on success, error code otherwise
- */
-static int
-boot_image_load_header(const struct flash_area *fa_p,
-                       struct image_header *hdr)
-{
-    uint32_t size;
-    int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
-
-    if (rc != 0) {
-        rc = BOOT_EFLASH;
-        BOOT_LOG_ERR("Failed reading image header");
-	return BOOT_EFLASH;
-    }
-
-    if (hdr->ih_magic != IMAGE_MAGIC) {
-        BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
-
-        return BOOT_EBADIMAGE;
-    }
-
-    if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
-        BOOT_LOG_ERR("Image not bootable");
-
-        return BOOT_EBADIMAGE;
-    }
-
-    if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
-        size >= flash_area_get_size(fa_p)) {
-        return BOOT_EBADIMAGE;
-    }
-
-    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_ret
-boot_image_validate_encrypted(const struct flash_area *fa_p,
-                    struct image_header *hdr)
-{
-    static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
-    FIH_DECLARE(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_ret
-decrypt_image_inplace(const struct flash_area *fa_p,
-                     struct image_header *hdr)
-{
-    FIH_DECLARE(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_get_sector(fa_p, 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_DECLARE(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.
  *
  * @parami[out]	rsp	Parameters for booting image, on success
diff --git a/docs/readme-zephyr.md b/docs/readme-zephyr.md
index 2acc63d..a8f351d 100644
--- a/docs/readme-zephyr.md
+++ b/docs/readme-zephyr.md
@@ -251,12 +251,6 @@
 * Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
 * Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
 
-### In-place image decryption
-
-Images uploaded by the serial recovery can be decrypted on the fly by using ECIES primitives described in the [ECIES encryption](encrypted_images.md#ecies-encryption) section.
-
-Enable support for this feature by using ``CONFIG_BOOT_SERIAL_ENCRYPT_EC256=y``.
-
 ### More configuration
 
 For details on other available configuration options for the serial recovery protocol, check the Kconfig options  (for example by using ``menuconfig``).