bootutil: Define new magic for the updated image trailer layout

The magic value applies to images built with maximum write alignment
values other than 8 bytes, whose trailer region is generated in a
different layout.

Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h
index fcd667e..a2bf9b2 100644
--- a/boot/bootutil/include/bootutil/bootutil_public.h
+++ b/boot/bootutil/include/bootutil/bootutil_public.h
@@ -266,11 +266,6 @@
 boot_read_swap_state(const struct flash_area *fa,
                      struct boot_swap_state *state);
 
-#define BOOT_MAGIC_ARR_SZ \
-    (sizeof boot_img_magic / sizeof boot_img_magic[0])
-
-extern const uint32_t boot_img_magic[4];
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index f0b4a5d..c4f5a06 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -46,11 +46,6 @@
 /* Currently only used by imgmgr */
 int boot_current_slot;
 
-extern const uint32_t boot_img_magic[];
-
-#define BOOT_MAGIC_ARR_SZ \
-    (sizeof boot_img_magic / sizeof boot_img_magic[0])
-
 /**
  * @brief Determine if the data at two memory addresses is equal
  *
@@ -191,9 +186,9 @@
 }
 
 static int
-boot_magic_decode(const uint32_t *magic)
+boot_magic_decode(const uint8_t *magic)
 {
-    if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0) {
+    if (memcmp(magic, BOOT_IMG_MAGIC, BOOT_MAGIC_SZ) == 0) {
         return BOOT_MAGIC_GOOD;
     }
     return BOOT_MAGIC_BAD;
@@ -247,7 +242,7 @@
 static int
 boot_find_status(int image_index, const struct flash_area **fap)
 {
-    uint32_t magic[BOOT_MAGIC_ARR_SZ];
+    uint8_t magic[BOOT_MAGIC_SZ];
     uint32_t off;
     uint8_t areas[2] = {
 #if MCUBOOT_SWAP_USING_SCRATCH
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 24795af..4085b54 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -140,7 +140,26 @@
  *      (`MCUBOOT_ENC_IMAGES`).
  */
 
-extern const uint32_t boot_img_magic[4];
+union boot_img_magic_t
+{
+    struct {
+        uint16_t align;
+        uint8_t magic[14];
+    };
+    uint8_t val[16];
+};
+
+extern const union boot_img_magic_t boot_img_magic;
+
+#define BOOT_IMG_MAGIC  (boot_img_magic.val)
+
+#if BOOT_MAX_ALIGN == 8
+#define BOOT_IMG_ALIGN  (BOOT_MAX_ALIGN)
+#else
+#define BOOT_IMG_ALIGN  (boot_img_magic.align)
+#endif
+
+_Static_assert(sizeof(boot_img_magic) == BOOT_MAGIC_SZ, "Invalid size for image magic");
 
 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
 #define ARE_SLOTS_EQUIVALENT()    0
diff --git a/boot/bootutil/src/bootutil_public.c b/boot/bootutil/src/bootutil_public.c
index 63092f2..f9b086f 100644
--- a/boot/bootutil/src/bootutil_public.c
+++ b/boot/bootutil/src/bootutil_public.c
@@ -51,6 +51,7 @@
 #endif
 
 #include "bootutil/boot_public_hooks.h"
+#include "bootutil_priv.h"
 
 #ifdef CONFIG_MCUBOOT
 BOOT_LOG_MODULE_DECLARE(mcuboot);
@@ -58,15 +59,26 @@
 BOOT_LOG_MODULE_REGISTER(mcuboot_util);
 #endif
 
-const uint32_t boot_img_magic[] = {
-    0xf395c277,
-    0x7fefd260,
-    0x0f505235,
-    0x8079b62c,
+#if BOOT_MAX_ALIGN == 8
+const union boot_img_magic_t boot_img_magic = {
+    .val = {
+        0x77, 0xc2, 0x95, 0xf3,
+        0x60, 0xd2, 0xef, 0x7f,
+        0x35, 0x52, 0x50, 0x0f,
+        0x2c, 0xb6, 0x79, 0x80
+    }
 };
-
-#define BOOT_MAGIC_ARR_SZ \
-    (sizeof boot_img_magic / sizeof boot_img_magic[0])
+#else
+const union boot_img_magic_t boot_img_magic = {
+    .align = BOOT_MAX_ALIGN,
+    .magic = {
+        0x2d, 0xe1,
+        0x5d, 0x29, 0x41, 0x0b,
+        0x8d, 0x77, 0x67, 0x9c,
+        0x11, 0x0f, 0x1f, 0x8a
+    }
+};
+#endif
 
 struct boot_swap_table {
     uint8_t magic_primary_slot;
@@ -120,9 +132,9 @@
     (sizeof boot_swap_tables / sizeof boot_swap_tables[0])
 
 static int
-boot_magic_decode(const uint32_t *magic)
+boot_magic_decode(const uint8_t *magic)
 {
-    if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0) {
+    if (memcmp(magic, BOOT_IMG_MAGIC, BOOT_MAGIC_SZ) == 0) {
         return BOOT_MAGIC_GOOD;
     }
     return BOOT_MAGIC_BAD;
@@ -255,7 +267,7 @@
 boot_read_swap_state(const struct flash_area *fap,
                      struct boot_swap_state *state)
 {
-    uint32_t magic[BOOT_MAGIC_ARR_SZ];
+    uint8_t magic[BOOT_MAGIC_SZ];
     uint32_t off;
     uint8_t swap_info;
     int rc;
@@ -334,7 +346,7 @@
     erased_val = flash_area_erased_val(fap);
 
     memset(&magic[0], erased_val, sizeof(magic));
-    memcpy(&magic[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ], boot_img_magic, BOOT_MAGIC_SZ);
+    memcpy(&magic[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ], BOOT_IMG_MAGIC, BOOT_MAGIC_SZ);
 
     BOOT_LOG_DBG("writing magic; fa_id=%d off=0x%lx (0x%lx)",
                  flash_area_get_id(fap), (unsigned long)off,
diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py
index 66cee43..2f0a1fa 100644
--- a/scripts/imgtool/image.py
+++ b/scripts/imgtool/image.py
@@ -81,12 +81,6 @@
 TLV_INFO_MAGIC = 0x6907
 TLV_PROT_INFO_MAGIC = 0x6908
 
-boot_magic = bytes([
-    0x77, 0xc2, 0x95, 0xf3,
-    0x60, 0xd2, 0xef, 0x7f,
-    0x35, 0x52, 0x50, 0x0f,
-    0x2c, 0xb6, 0x79, 0x80, ])
-
 STRUCT_ENDIAN_DICT = {
         'little': '<',
         'big':    '>'
@@ -98,6 +92,9 @@
                     INVALID_SIGNATURE
                     """)
 
+def align_up(num, align):
+    assert (align & (align - 1) == 0) and align != 0
+    return (num + (align - 1)) & ~(align - 1)
 
 class TLV():
     def __init__(self, endian, magic=TLV_INFO_MAGIC):
@@ -160,6 +157,21 @@
         self.enctlv_len = 0
         self.max_align = DEFAULT_MAX_ALIGN if max_align is None else int(max_align)
 
+        if self.max_align == DEFAULT_MAX_ALIGN:
+            self.boot_magic = bytes([
+                0x77, 0xc2, 0x95, 0xf3,
+                0x60, 0xd2, 0xef, 0x7f,
+                0x35, 0x52, 0x50, 0x0f,
+                0x2c, 0xb6, 0x79, 0x80, ])
+        else:
+            align_lsb = self.max_align & 0x00ff
+            align_msb = (self.max_align & 0xff00) >> 8
+            self.boot_magic = bytes([
+                align_lsb, align_msb, 0x2d, 0xe1,
+                0x5d, 0x29, 0x41, 0x0b,
+                0x8d, 0x77, 0x67, 0x9c,
+                0x11, 0x0f, 0x1f, 0x8a, ])
+
         if security_counter == 'auto':
             # Security counter has not been explicitly provided,
             # generate it from the version number
@@ -231,11 +243,11 @@
                                                   self.enctlv_len)
                 trailer_addr = (self.base_addr + self.slot_size) - trailer_size
                 padding = bytearray([self.erased_val] * 
-                                    (trailer_size - len(boot_magic)))
-                padding += boot_magic
+                                    (trailer_size - len(self.boot_magic)))
+                padding += self.boot_magic
                 if self.confirm and not self.overwrite_only:
                     magic_size = 16
-                    magic_align_size = (int((magic_size - 1) / self.max_align) + 1) * self.max_align
+                    magic_align_size = align_up(magic_size, self.max_align)
                     image_ok_idx = -(magic_align_size + self.max_align)
                     padding[image_ok_idx] = 0x01  # image_ok = 0x01
                 h.puts(trailer_addr, bytes(padding))
@@ -521,7 +533,7 @@
                       save_enctlv, enctlv_len):
         # NOTE: should already be checked by the argument parser
         magic_size = 16
-        magic_align_size = (int((magic_size - 1) / self.max_align) + 1) * self.max_align
+        magic_align_size = align_up(magic_size, self.max_align)
         if overwrite_only:
             return self.max_align * 2 + magic_align_size
         else:
@@ -533,9 +545,9 @@
             if enckey is not None:
                 if save_enctlv:
                     # TLV saved by the bootloader is aligned
-                    keylen = (int((enctlv_len - 1) / self.max_align) + 1) * self.max_align
+                    keylen = align_up(enctlv_len, self.max_align)
                 else:
-                    keylen = (int((16 - 1) / self.max_align) + 1) * self.max_align
+                    keylen = align_up(16, self.max_align)
                 trailer += keylen * 2  # encryption keys
             trailer += self.max_align * 4  # image_ok/copy_done/swap_info/swap_size
             trailer += magic_align_size
@@ -548,11 +560,11 @@
                                    self.save_enctlv, self.enctlv_len)
         padding = size - (len(self.payload) + tsize)
         pbytes = bytearray([self.erased_val] * padding)
-        pbytes += bytearray([self.erased_val] * (tsize - len(boot_magic)))
-        pbytes += boot_magic
+        pbytes += bytearray([self.erased_val] * (tsize - len(self.boot_magic)))
+        pbytes += self.boot_magic
         if self.confirm and not self.overwrite_only:
             magic_size = 16
-            magic_align_size = (int((magic_size - 1) / self.max_align) + 1) * self.max_align
+            magic_align_size = align_up(magic_size, self.max_align)
             image_ok_idx = -(magic_align_size + self.max_align)
             pbytes[image_ok_idx] = 0x01  # image_ok = 0x01
         self.payload += pbytes