[U-Boot] [RFC PATCH 1/2] fpga: xilinx: zynq: Add support to decrypt images

Siva Durga Prasad Paladugu siva.durga.paladugu at xilinx.com
Mon Apr 2 06:15:03 UTC 2018


This patch adds support to decrypt an encrypted bitstream
or image. This zynq aes command can either load decrypted
image back to DDR or it can load an encrypted bitsream to
PL directly by decrypting it. The image has to be encrypted
using xilinx bootgen tool and to get only the encrypted
image from tool use -split option while invoking bootgen.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur at xilinx.com>
---
 arch/arm/Kconfig          |   1 +
 board/xilinx/zynq/Kconfig |  14 ++++
 drivers/fpga/zynqpl.c     | 158 ++++++++++++++++++++++++++++++++++++++++++++++
 include/zynqpl.h          |   5 ++
 4 files changed, 178 insertions(+)
 create mode 100644 board/xilinx/zynq/Kconfig

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 068ea1e..e0cd1d8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1360,6 +1360,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/woodburn/Kconfig"
 source "board/work-microwave/work_92105/Kconfig"
+source "board/xilinx/zynq/Kconfig"
 source "board/xilinx/zynqmp/Kconfig"
 source "board/zipitz2/Kconfig"

diff --git a/board/xilinx/zynq/Kconfig b/board/xilinx/zynq/Kconfig
new file mode 100644
index 0000000..f8f8a7f
--- /dev/null
+++ b/board/xilinx/zynq/Kconfig
@@ -0,0 +1,14 @@
+# Copyright (c) 2018, Xilinx, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_ZYNQ
+
+config CMD_ZYNQ_AES
+       bool "Zynq AES"
+       default y
+       help
+         Decrypts the encrypted image present in source address
+         and places the decrypted image at destination address.
+
+endif
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c
index db9bd12..fcffc2d 100644
--- a/drivers/fpga/zynqpl.c
+++ b/drivers/fpga/zynqpl.c
@@ -18,6 +18,7 @@

 #define DEVCFG_CTRL_PCFG_PROG_B                0x40000000
 #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK        0x00001000
+#define DEVCFG_CTRL_PCAP_RATE_EN_MASK  0x02000000
 #define DEVCFG_ISR_FATAL_ERROR_MASK    0x00740040
 #define DEVCFG_ISR_ERROR_FLAGS_MASK    0x00340840
 #define DEVCFG_ISR_RX_FIFO_OV          0x00040000
@@ -498,3 +499,160 @@ struct xilinx_fpga_op zynq_op = {
        .loadfs = zynq_loadfs,
 #endif
 };
+
+#ifdef CONFIG_CMD_ZYNQ_AES
+/*
+ * Load the encrypted image from src addr and decrypt the image and
+ * place it back the decrypted image into dstaddr.
+ */
+int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen,
+                     u8 bstype)
+{
+       u32 isr_status, ts;
+
+       if ((srcaddr < SZ_1M) || (dstaddr < SZ_1M)) {
+               printf("%s: src and dst addr should be > 1M\n",
+                      __func__);
+               return FPGA_FAIL;
+       }
+
+       if (zynq_dma_xfer_init(bstype)) {
+               printf("%s: zynq_dma_xfer_init FAIL\n", __func__);
+               return FPGA_FAIL;
+       }
+
+       writel((readl(&devcfg_base->ctrl) | DEVCFG_CTRL_PCAP_RATE_EN_MASK),
+              &devcfg_base->ctrl);
+
+       debug("%s: Source = 0x%08X\n", __func__, (u32)srcaddr);
+       debug("%s: Size = %zu\n", __func__, srclen);
+
+       /* flush(clean & invalidate) d-cache range buf */
+       flush_dcache_range((u32)srcaddr, (u32)srcaddr +
+                       roundup(srclen << 2, ARCH_DMA_MINALIGN));
+       /*
+        * Flush destination address range only if image is not
+        * bitstream.
+        */
+       if (bstype == BIT_NONE)
+               flush_dcache_range((u32)dstaddr, (u32)dstaddr +
+                               roundup(dstlen << 2, ARCH_DMA_MINALIGN));
+
+       if (zynq_dma_transfer(srcaddr | 1, srclen, dstaddr | 1, dstlen))
+               return FPGA_FAIL;
+
+       if (bstype == BIT_FULL) {
+               isr_status = readl(&devcfg_base->int_sts);
+               /* Check FPGA configuration completion */
+               ts = get_timer(0);
+               while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
+                       if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+                               printf("%s: Timeout wait for FPGA to config\n",
+                                      __func__);
+                               return FPGA_FAIL;
+                       }
+                       isr_status = readl(&devcfg_base->int_sts);
+               }
+
+               printf("%s: FPGA config done\n", __func__);
+
+               if (bstype != BIT_PARTIAL)
+                       zynq_slcr_devcfg_enable();
+       }
+
+       return FPGA_SUCCESS;
+}
+
+static int do_zynq_decrypt_image(cmd_tbl_t *cmdtp, int flag, int argc,
+                                char * const argv[])
+{
+       char *endp;
+       u32 srcaddr;
+       u32 srclen;
+       u32 dstaddr;
+       u32 dstlen;
+       u8 imgtype = BIT_NONE;
+       int status;
+       u8 i = 1;
+
+       if (argc < 4 && argc > 5)
+               goto usage;
+
+       if (argc == 4) {
+               if (!strcmp("load", argv[i]))
+                       imgtype = BIT_FULL;
+               else if (!strcmp("loadp", argv[i]))
+                       imgtype = BIT_PARTIAL;
+               else
+                       goto usage;
+               i++;
+       }
+
+       srcaddr = simple_strtoul(argv[i], &endp, 16);
+       if (*argv[i++] == 0 || *endp != 0)
+               goto usage;
+       srclen = simple_strtoul(argv[i], &endp, 16);
+       if (*argv[i++] == 0 || *endp != 0)
+               goto usage;
+       if (argc == 4) {
+               dstaddr = 0xFFFFFFFF;
+               dstlen = srclen;
+       } else {
+               dstaddr = simple_strtoul(argv[i], &endp, 16);
+               if (*argv[i++] == 0 || *endp != 0)
+                       goto usage;
+               dstlen = simple_strtoul(argv[i], &endp, 16);
+               if (*argv[i++] == 0 || *endp != 0)
+                       goto usage;
+       }
+
+       /*
+        * If the image is not bitstream but destination address is
+        * 0xFFFFFFFF
+        */
+       if (imgtype == BIT_NONE && dstaddr == 0xFFFFFFFF) {
+               printf("ERR:use zynqaes load/loadp encrypted bitstream\n");
+               goto usage;
+       }
+
+       /*
+        * Roundup source and destination lengths to
+        * word size
+        */
+       if (srclen % 4)
+               srclen = roundup(srclen, 4);
+       if (dstlen % 4)
+               dstlen = roundup(dstlen, 4);
+
+       status = zynq_decrypt_load(srcaddr, srclen >> 2, dstaddr, dstlen >> 2,
+                                  imgtype);
+       if (status != 0)
+               return -1;
+
+       return 0;
+
+usage:
+       return CMD_RET_USAGE;
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char zynqaes_help_text[] =
+"zynqaes [operation type] <srcaddr> <srclen> <dstaddr> <dstlen>  -\n"
+"Decrypts the encrypted image present in source address\n"
+"and places the decrypted image at destination address\n"
+"zynqaes operations:\n"
+"   zynqaes <srcaddr> <srclen> <dstaddr> <dstlen>\n"
+"   zynqaes load <srcaddr> <srclen>\n"
+"   zynqaes loadp <srcaddr> <srclen>\n"
+"if operation type is load or loadp, it loads the encrypted\n"
+"full or partial bitstream on to PL respectively. If no valid\n"
+"operation type specified then it loads decrypted image back\n"
+"to memory and it doesn't support loading PL bistsream\n";
+#endif
+
+U_BOOT_CMD(
+               zynqaes,        5,      0,      do_zynq_decrypt_image,
+               "Zynq AES decryption ", zynqaes_help_text
+         );
+
+#endif
diff --git a/include/zynqpl.h b/include/zynqpl.h
index 5a34a17..0dd4cf9 100644
--- a/include/zynqpl.h
+++ b/include/zynqpl.h
@@ -12,6 +12,11 @@

 #include <xilinx.h>

+#ifdef CONFIG_CMD_ZYNQ_AES
+int zynq_decrypt_load(u32 srcaddr, u32 dstaddr, u32 srclen, u32 dstlen,
+                            u8 bstype);
+#endif
+
 #if defined(CONFIG_FPGA_ZYNQPL)
 extern struct xilinx_fpga_op zynq_op;
 # define FPGA_ZYNQPL_OPS       &zynq_op
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


More information about the U-Boot mailing list