gadged: thor: add board signature check when download 'u-boot-mmc.bin'
authorInha Song <ideal.song@samsung.com>
Mon, 28 Oct 2013 06:52:53 +0000 (15:52 +0900)
committerJaehoon Chung <jh80.chung@samsung.com>
Tue, 20 Oct 2020 00:42:15 +0000 (09:42 +0900)
This patch adds checking the special signature of downloaded U-Boot binary.
The new function check_board_signature() is called before do dfu_write()
in thor gadged code.

The board signature is checked for:
- the running U-Boot
- downloaded 'u-boot-mmc.bin'
at offset of binary start defined by:
- (CONFIG_SIGN_IMAGE_SIZE - HDR_SIZE)

The download can succeed when signatures are equal.

The default U-Boot image size defined by CONFIG_SIGN_IMAGE_SIZE is 1MB.

Other changes:
- print info about running/downloading U-Boot signature
- print info about wrong image signature/size
- don't allow downloading unsigned or signed wrong U-Boot image
- allow download any image if no signature found at running U-Boot

The first version added by:
Signed-off-by: Inha Song <ideal.song@samsung.com>
Upgrade:
Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
board/samsung/common/Makefile
board/samsung/common/sig_header.c [new file with mode: 0644]
drivers/usb/gadget/f_thor.c
include/samsung/sighdr.h [new file with mode: 0644]

index 3593c77..14edd13 100644 (file)
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_USB_GADGET_DOWNLOAD) += gadget.o
 obj-$(CONFIG_MISC_COMMON) += misc.o
+obj-$(CONFIG_SIG) += sig_header.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_BOARD_COMMON)     += board.o
diff --git a/board/samsung/common/sig_header.c b/board/samsung/common/sig_header.c
new file mode 100644 (file)
index 0000000..eb4646e
--- /dev/null
@@ -0,0 +1,60 @@
+#include <common.h>
+#include <errno.h>
+#include <samsung/sighdr.h>
+
+int get_image_signature(struct sig_header *hdr,
+                       phys_addr_t base_addr,
+                       phys_size_t size)
+{
+       memcpy((void *)hdr, (const void *)(base_addr + size - HDR_SIZE),
+               HDR_SIZE);
+
+       if (hdr->magic != HDR_BOOT_MAGIC)
+               return -EFAULT;
+
+       return 0;
+}
+
+int check_board_signature(char *fname, phys_addr_t dn_addr, phys_size_t size)
+{
+       struct sig_header bh_target;
+       struct sig_header bh_addr;
+       int ret;
+
+       /* u-boot-mmc.bin */
+       if (strcmp(fname, "u-boot-mmc.bin"))
+               return 0;
+
+       /* can't found signature in target - download continue */
+       ret = get_image_signature(&bh_target, (phys_addr_t)CONFIG_SYS_TEXT_BASE,
+                                 CONFIG_SIG_IMAGE_SIZE);
+       if (ret)
+               return 0;
+
+       printf("U-Boot signature: \"%.*s\"\n", 16, bh_target.bd_name);
+
+       if (size != CONFIG_SIG_IMAGE_SIZE) {
+               printf("Bad file size for: %s.\n", fname);
+               printf("Expected: %#x bytes, has: %#x bytes.\n",
+                      CONFIG_SIG_IMAGE_SIZE, (unsigned)size);
+               return -EINVAL;
+       }
+
+       printf("%s ", fname);
+       /* can't found signature in address - download stop */
+       ret = get_image_signature(&bh_addr, dn_addr, CONFIG_SIG_IMAGE_SIZE);
+       if (ret) {
+               printf("signature not found.\n");
+               return -EFAULT;
+       }
+       printf("signature: \"%.*s\". ", 16, bh_addr.bd_name);
+
+       if (strncmp(bh_target.bd_name, bh_addr.bd_name,
+                   ARRAY_SIZE(bh_target.bd_name))) {
+               printf("Invalid!\n");
+               return -EPERM;
+       }
+       printf("OK!\n");
+
+       return 0;
+}
index f5748ff..16bfa40 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/usb/cdc.h>
 #include <g_dnl.h>
 #include <dfu.h>
+#include <samsung/sighdr.h>
 #include <libtizen.h>
 #include <samsung/misc.h>
 #include <linux/input.h>
@@ -239,6 +240,14 @@ static int download_tail(long long int left, int cnt)
                return -ENXIO;
        }
 
+#ifdef CONFIG_SIG
+       /* check board signature when download u-boot-mmc.bin */
+       ret = check_board_signature(f_name, (phys_addr_t)transfer_buffer,
+                                   (phys_size_t)thor_file_size);
+       if (ret)
+               return ret;
+#endif
+
        if (left) {
                ret = dfu_write(dfu_entity, transfer_buffer, left, cnt++);
                if (ret) {
diff --git a/include/samsung/sighdr.h b/include/samsung/sighdr.h
new file mode 100644 (file)
index 0000000..f97f51d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __HEADER_H__
+#define __HEADER_H__
+
+#define HDR_BOOT_MAGIC         0x744f6f42      /* BoOt */
+
+#define HDR_SIZE               sizeof(struct sig_header)
+
+/* Size of u-boot-mmc.bin - should be always padded to 1MB */
+#define CONFIG_SIG_IMAGE_SIZE  SZ_1M
+
+/* HDR_SIZE - 512 */
+struct sig_header {
+       uint32_t magic;         /* image magic number */
+       uint32_t size;          /* image data size */
+       uint32_t valid;         /* valid flag */
+       char date[12];          /* image creation timestamp - YYMMDDHH */
+       char version[24];       /* image version */
+       char bd_name[16];       /* target board name */
+       char reserved[448];     /* reserved */
+};
+
+int check_board_signature(char *fname, phys_addr_t dn_addr, phys_size_t size);
+#endif