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

2018-04-19 Thread Stefan Herbrechtsmeier

Am 02.04.2018 um 08:15 schrieb Siva Durga Prasad Paladugu:

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 
---
  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 000..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_B0x4000
  #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK0x1000
+#define DEVCFG_CTRL_PCAP_RATE_EN_MASK  0x0200
  #define DEVCFG_ISR_FATAL_ERROR_MASK0x00740040
  #define DEVCFG_ISR_ERROR_FLAGS_MASK0x00340840
  #define DEVCFG_ISR_RX_FIFO_OV  0x0004
@@ -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;
+}


This function repeats much code of the existing zynq_load function.

Furthermore the existing function could be adapted to auto detect an 
encrypted image. This allows the usage of encrypted FPGA images even in 
fit images and doesn't introduces a second function zynqaes for fpga load.


Best regards
  Stefan

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


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

2018-04-04 Thread Michal Simek
On 2.4.2018 08:15, Siva Durga Prasad Paladugu wrote:
> 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 
> ---
>  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 000..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  0x4000
>  #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK  0x1000
> +#define DEVCFG_CTRL_PCAP_RATE_EN_MASK0x0200
>  #define DEVCFG_ISR_FATAL_ERROR_MASK  0x00740040
>  #define DEVCFG_ISR_ERROR_FLAGS_MASK  0x00340840
>  #define DEVCFG_ISR_RX_FIFO_OV0x0004
> @@ -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)
> + g