Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index 914167e..ec068fc 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -28,7 +28,7 @@
 #include "cbor_encode.h"
 
 #ifdef __ZEPHYR__
-#include <power/reboot.h>
+#include <sys/reboot.h>
 #include <sys/byteorder.h>
 #include <sys/__assert.h>
 #include <drivers/flash.h>
@@ -58,17 +58,17 @@
 #include "bootutil_priv.h"
 #endif
 
+#ifdef MCUBOOT_ENC_IMAGES
+#include "single_loader.h"
+#endif
+
 #include "serial_recovery_cbor.h"
 #include "bootutil/boot_hooks.h"
 
 BOOT_LOG_MODULE_DECLARE(mcuboot);
 
-#ifndef BOOT_IMAGE_NUMBER
-#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
-#endif
-
 #define BOOT_SERIAL_INPUT_MAX   512
-#define BOOT_SERIAL_OUT_MAX     (128 * MCUBOOT_IMAGE_NUMBER)
+#define BOOT_SERIAL_OUT_MAX     (128 * BOOT_IMAGE_NUMBER)
 
 #ifdef __ZEPHYR__
 /* base64 lib encodes data to null-terminated string */
@@ -93,6 +93,7 @@
 static uint32_t curr_off;
 static uint32_t img_size;
 static struct nmgr_hdr *bs_hdr;
+static bool bs_entry;
 
 static char bs_obuf[BOOT_SERIAL_OUT_MAX];
 
@@ -204,6 +205,17 @@
                                    fih_rc, image_index, slot);
                 if (fih_eq(fih_rc, 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);
+                    }
+#endif
                     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
                                     NULL, 0, NULL);
                 }
@@ -322,6 +334,14 @@
         if (data_len > flash_area_get_size(fap)) {
             goto out_invalid_data;
         }
+#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE)
+        /* We are using swap state at end of flash area to store validation
+         * result. Make sure the user cannot write it from an image to skip validation.
+         */
+        if (data_len > (flash_area_get_size(fap) - BOOT_MAGIC_SZ)) {
+            goto out_invalid_data;
+        }
+#endif
 #ifndef MCUBOOT_ERASE_PROGRESSIVELY
         rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
         if (rc) {
@@ -441,17 +461,56 @@
 
     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();
+    }
+#endif //#ifdef MCUBOOT_ENC_IMAGES
 }
 
+#ifdef MCUBOOT_BOOT_MGMT_ECHO
+static bool
+decode_echo(cbor_state_t *state, cbor_string_type_t *result)
+{
+    size_t bsstrdecoded;
+    int ret;
+
+    if (!map_start_decode(state)) {
+        return false;
+    }
+    ret = multi_decode(2, 2, &bsstrdecoded, (void *)tstrx_decode, state, result, sizeof(cbor_string_type_t));
+    map_end_decode(state);
+    return ret;
+}
+
+
+static void
+bs_echo(char *buf, int len)
+{
+    size_t bsstrdecoded;
+    cbor_string_type_t str[2];
+
+    if (entry_function((const uint8_t *)buf, len, str, &bsstrdecoded, (void *)decode_echo, 1, 2)) {
+        map_start_encode(&cbor_state, 10);
+        tstrx_put(&cbor_state, "r");
+        tstrx_encode(&cbor_state, &str[1]);
+        map_end_encode(&cbor_state, 10);
+        boot_serial_output();
+    }
+}
+#endif
+
 /*
- * Console echo control/image erase. Send empty response, don't do anything.
+ * Send rc code only.
  */
 static void
-bs_empty_rsp(char *buf, int len)
+bs_rc_rsp(int rc_code)
 {
     map_start_encode(&cbor_state, 10);
     tstrx_put(&cbor_state, "rc");
-    uintx32_put(&cbor_state, 0);
+    uintx32_put(&cbor_state, rc_code);
     map_end_encode(&cbor_state, 10);
     boot_serial_output();
 }
@@ -463,7 +522,7 @@
 static void
 bs_reset(char *buf, int len)
 {
-    bs_empty_rsp(buf, len);
+    bs_rc_rsp(0);
 
 #ifdef __ZEPHYR__
 #ifdef CONFIG_MULTITHREADING
@@ -515,25 +574,36 @@
             bs_upload(buf, len);
             break;
         default:
-            bs_empty_rsp(buf, len);
+            bs_rc_rsp(MGMT_ERR_ENOTSUP);
             break;
         }
     } else if (hdr->nh_group == MGMT_GROUP_ID_DEFAULT) {
         switch (hdr->nh_id) {
+        case NMGR_ID_ECHO:
+#ifdef MCUBOOT_BOOT_MGMT_ECHO
+            bs_echo(buf, len);
+#endif
+            break;
         case NMGR_ID_CONS_ECHO_CTRL:
-            bs_empty_rsp(buf, len);
+            bs_rc_rsp(0);
             break;
         case NMGR_ID_RESET:
             bs_reset(buf, len);
             break;
         default:
+            bs_rc_rsp(MGMT_ERR_ENOTSUP);
             break;
         }
     } else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) {
         if (bs_peruser_system_specific(hdr, buf, len, &cbor_state) == 0) {
             boot_serial_output();
         }
+    } else {
+        bs_rc_rsp(MGMT_ERR_ENOTSUP);
     }
+#ifdef MCUBOOT_SERIAL_WAIT_FOR_DFU
+    bs_entry = true;
+#endif
 }
 
 static void
@@ -556,9 +626,8 @@
     bs_hdr->nh_group = htons(bs_hdr->nh_group);
 
 #ifdef __ZEPHYR__
-    crc =  crc16((uint8_t *)bs_hdr, sizeof(*bs_hdr), CRC_CITT_POLYMINAL,
-                 CRC16_INITIAL_CRC, false);
-    crc =  crc16(data, len, CRC_CITT_POLYMINAL, crc, true);
+    crc =  crc16_itu_t(CRC16_INITIAL_CRC, (uint8_t *)bs_hdr, sizeof(*bs_hdr));
+    crc =  crc16_itu_t(crc, data, len);
 #else
     crc = crc16_ccitt(CRC16_INITIAL_CRC, bs_hdr, sizeof(*bs_hdr));
     crc = crc16_ccitt(crc, data, len);
@@ -632,7 +701,7 @@
 
     out += sizeof(uint16_t);
 #ifdef __ZEPHYR__
-    crc = crc16(out, len, CRC_CITT_POLYMINAL, CRC16_INITIAL_CRC, true);
+    crc = crc16_itu_t(CRC16_INITIAL_CRC, out, len);
 #else
     crc = crc16_ccitt(CRC16_INITIAL_CRC, out, len);
 #endif
@@ -649,24 +718,29 @@
  * Task which waits reading console, expecting to get image over
  * serial port.
  */
-void
-boot_serial_start(const struct boot_uart_funcs *f)
+static void
+boot_serial_read_console(const struct boot_uart_funcs *f,int timeout_in_ms)
 {
     int rc;
     int off;
     int dec_off = 0;
     int full_line;
     int max_input;
+    int elapsed_in_ms = 0;
 
     boot_uf = f;
     max_input = sizeof(in_buf);
 
     off = 0;
-    while (1) {
+    while (timeout_in_ms > 0 || bs_entry) {
         MCUBOOT_CPU_IDLE();
+        MCUBOOT_WATCHDOG_FEED();
+#ifdef MCUBOOT_SERIAL_WAIT_FOR_DFU
+        uint32_t start = k_uptime_get_32();
+#endif
         rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
         if (rc <= 0 && !full_line) {
-            continue;
+            goto check_timeout;
         }
         off += rc;
         if (!full_line) {
@@ -676,7 +750,7 @@
                  */
                 off = 0;
             }
-            continue;
+            goto check_timeout;
         }
         if (in_buf[0] == SHELL_NLIP_PKT_START1 &&
           in_buf[1] == SHELL_NLIP_PKT_START2) {
@@ -692,5 +766,36 @@
             boot_serial_input(&dec_buf[2], dec_off - 2);
         }
         off = 0;
+check_timeout:
+        /* Subtract elapsed time */
+#ifdef MCUBOOT_SERIAL_WAIT_FOR_DFU
+        elapsed_in_ms = (k_uptime_get_32() - start);
+#endif
+        timeout_in_ms -= elapsed_in_ms;
     }
 }
+
+/*
+ * Task which waits reading console, expecting to get image over
+ * serial port.
+ */
+void
+boot_serial_start(const struct boot_uart_funcs *f)
+{
+    bs_entry = true;
+    boot_serial_read_console(f,0);
+}
+
+#ifdef MCUBOOT_SERIAL_WAIT_FOR_DFU
+/*
+ * Task which waits reading console for a certain amount of timeout.
+ * If within this timeout no mcumgr command is received, the function is
+ * returning, else the serial boot is never exited
+ */
+void
+boot_serial_check_start(const struct boot_uart_funcs *f, int timeout_in_ms)
+{
+    bs_entry = false;
+    boot_serial_read_console(f,timeout_in_ms);
+}
+#endif