[U-Boot] [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect

From: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
Signed-off-by: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
---
drivers/fpga/zynqpl.c | 73 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 16 deletions(-)
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index fd37d18..6622750 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -17,6 +17,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 @@ -38,18 +39,16 @@ #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ #endif
+#define NOP_WORD 0x20000000 +#define CTRL0_WORD 0x3000a001 +#define MASK_WORD 0x3000c001 #define DUMMY_WORD 0xffffffff
+#define CTRL0_DEC_MASK BIT(6) + /* Xilinx binary format header */ +#define MAX_DUMMY_WORD_COUNT 8 static const u32 bin_format[] = { - DUMMY_WORD, /* Dummy words */ - DUMMY_WORD, - DUMMY_WORD, - DUMMY_WORD, - DUMMY_WORD, - DUMMY_WORD, - DUMMY_WORD, - DUMMY_WORD, 0x000000bb, /* Sync word */ 0x11220044, /* Sync word */ DUMMY_WORD, @@ -85,7 +84,23 @@ static u32 load_word(const void *buf, u32 swap) return word; }
-static u32 check_header(const void *buf) +static void *skip_dummy_words(const void *buf) +{ + u32 *test = (u32 *)buf; + u32 i; + + for (i = 0; i < MAX_DUMMY_WORD_COUNT; i++) { + if (load_word(&test[i], SWAP_NO) != DUMMY_WORD) { + debug("%s: Found no dummy word at position %d/%x\n", + __func__, i, (u32)&test[i]); + return &test[i]; + } + } + + return &test[i]; +} + +static u32 check_header(const void *buf, bool *encrypted) { u32 i, pattern; int swap = SWAP_NO; @@ -93,6 +108,8 @@ static u32 check_header(const void *buf)
debug("%s: Let's check bitstream header\n", __func__);
+ test = (u32 *)skip_dummy_words(buf); + /* Checking that passing bin is not a bitstream */ for (i = 0; i < ARRAY_SIZE(bin_format); i++) { pattern = load_word(&test[i], swap); @@ -112,18 +129,34 @@ static u32 check_header(const void *buf)
debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i, (u32)&test[i], pattern, bin_format[i]); + if (pattern != bin_format[i]) { debug("%s: Bitstream is not recognized\n", __func__); return 0; } } - debug("%s: Found bitstream header at %x %s swapinng\n", __func__, - (u32)buf, swap == SWAP_NO ? "without" : "with"); + + test = &test[i]; + + /* Checking if passing bin is an encrypted bitstream */ + if ((load_word(&test[0], swap) == NOP_WORD) && + (load_word(&test[1], swap) == MASK_WORD) && + (load_word(&test[2], swap) & CTRL0_DEC_MASK) && + (load_word(&test[3], swap) == CTRL0_WORD) && + (load_word(&test[4], swap) & CTRL0_DEC_MASK) && + (load_word(&test[5], swap) == NOP_WORD)) + *encrypted = true; + else + *encrypted = false; + + debug("%s: Found %sencrypted bitstream header at %x %s swapping\n", + __func__, *encrypted ? "" : "un", (u32)buf, + swap == SWAP_NO ? "without" : "with");
return swap; }
-static void *check_data(u8 *buf, size_t bsize, u32 *swap) +static void *check_data(u8 *buf, size_t bsize, u32 *swap, bool *encrypted) { u32 word, p = 0; /* possition */
@@ -136,7 +169,7 @@ static void *check_data(u8 *buf, size_t bsize, u32 *swap) if (word == DUMMY_WORD) { debug("%s: Found dummy word at position %x/%x\n", __func__, p, (u32)&buf[p]); - *swap = check_header(&buf[p]); + *swap = check_header(&buf[p], encrypted); if (*swap) { /* FIXME add full bitstream checking here */ return &buf[p]; @@ -191,7 +224,7 @@ static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) return FPGA_SUCCESS; }
-static int zynq_dma_xfer_init(bitstream_type bstype) +static int zynq_dma_xfer_init(bitstream_type bstype, bool encrypted) { u32 status, control, isr_status; unsigned long ts; @@ -291,6 +324,13 @@ static int zynq_dma_xfer_init(bitstream_type bstype) writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); }
+ control = readl(&devcfg_base->ctrl); + if (encrypted) + control |= DEVCFG_CTRL_PCAP_RATE_EN_MASK; + else + control &= ~DEVCFG_CTRL_PCAP_RATE_EN_MASK; + writel(control, &devcfg_base->ctrl); + return FPGA_SUCCESS; }
@@ -336,10 +376,11 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, size_t bsize, u32 blocksize, u32 *swap, bitstream_type *bstype) { + bool encrypted = false; u32 *buf_start; u32 diff;
- buf_start = check_data((u8 *)buf, blocksize, swap); + buf_start = check_data((u8 *)buf, blocksize, swap, &encrypted);
if (!buf_start) return FPGA_FAIL; @@ -358,7 +399,7 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, return FPGA_FAIL; }
- if (zynq_dma_xfer_init(*bstype)) + if (zynq_dma_xfer_init(*bstype, encrypted)) return FPGA_FAIL;
return 0;

Hi Stefan,
Interesting, I got your point. First of all, Could you please let me know on how do you created the encrypted bitstream? I hope this is not the Xilinx bootgen flow(may be through other Xilinx flow) because, I don't think bootgen will update these fields while creating encrypted bitstream( need to re confirm on this) and my flow targets the Xilinx bootgen flow. Please let know your comments on this, based on which, will try to review and test your patch.
Thanks, Siva
-----Original Message----- From: stefan@herbrechtsmeier.net [mailto:stefan@herbrechtsmeier.net] Sent: Friday, June 08, 2018 5:29 PM To: Siva Durga Prasad Paladugu sivadur@xilinx.com Cc: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com; u-boot@lists.denx.de; Michal Simek michal.simek@xilinx.com; monstr@monstr.eu Subject: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
From: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
Signed-off-by: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
drivers/fpga/zynqpl.c | 73 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 16 deletions(-)
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index fd37d18..6622750 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -17,6 +17,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 @@ -38,18 +39,16 @@ #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ #endif
+#define NOP_WORD 0x20000000 +#define CTRL0_WORD 0x3000a001 +#define MASK_WORD 0x3000c001 #define DUMMY_WORD 0xffffffff
+#define CTRL0_DEC_MASK BIT(6)
/* Xilinx binary format header */ +#define MAX_DUMMY_WORD_COUNT 8 static const u32 bin_format[] = {
- DUMMY_WORD, /* Dummy words */
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD, 0x000000bb, /* Sync word */ 0x11220044, /* Sync word */ DUMMY_WORD,
@@ -85,7 +84,23 @@ static u32 load_word(const void *buf, u32 swap) return word; }
-static u32 check_header(const void *buf) +static void *skip_dummy_words(const void *buf) {
- u32 *test = (u32 *)buf;
- u32 i;
- for (i = 0; i < MAX_DUMMY_WORD_COUNT; i++) {
if (load_word(&test[i], SWAP_NO) != DUMMY_WORD) {
debug("%s: Found no dummy word at position
%d/%x\n",
__func__, i, (u32)&test[i]);
return &test[i];
}
- }
- return &test[i];
+}
+static u32 check_header(const void *buf, bool *encrypted) { u32 i, pattern; int swap = SWAP_NO; @@ -93,6 +108,8 @@ static u32 check_header(const void *buf)
debug("%s: Let's check bitstream header\n", __func__);
- test = (u32 *)skip_dummy_words(buf);
- /* Checking that passing bin is not a bitstream */ for (i = 0; i < ARRAY_SIZE(bin_format); i++) { pattern = load_word(&test[i], swap);
@@ -112,18 +129,34 @@ static u32 check_header(const void *buf)
debug("%s: %d/%x: pattern %x/%x bin_format\n",
__func__, i, (u32)&test[i], pattern, bin_format[i]);
- if (pattern != bin_format[i]) { debug("%s: Bitstream is not recognized\n",
__func__); return 0; } }
- debug("%s: Found bitstream header at %x %s swapinng\n",
__func__,
(u32)buf, swap == SWAP_NO ? "without" : "with");
- test = &test[i];
- /* Checking if passing bin is an encrypted bitstream */
- if ((load_word(&test[0], swap) == NOP_WORD) &&
(load_word(&test[1], swap) == MASK_WORD) &&
(load_word(&test[2], swap) & CTRL0_DEC_MASK) &&
(load_word(&test[3], swap) == CTRL0_WORD) &&
(load_word(&test[4], swap) & CTRL0_DEC_MASK) &&
(load_word(&test[5], swap) == NOP_WORD))
*encrypted = true;
- else
*encrypted = false;
- debug("%s: Found %sencrypted bitstream header at %x %s
swapping\n",
__func__, *encrypted ? "" : "un", (u32)buf,
swap == SWAP_NO ? "without" : "with");
return swap;
}
-static void *check_data(u8 *buf, size_t bsize, u32 *swap) +static void *check_data(u8 *buf, size_t bsize, u32 *swap, bool +*encrypted) { u32 word, p = 0; /* possition */
@@ -136,7 +169,7 @@ static void *check_data(u8 *buf, size_t bsize, u32 *swap) if (word == DUMMY_WORD) { debug("%s: Found dummy word at position %x/%x\n", __func__, p, (u32)&buf[p]);
*swap = check_header(&buf[p]);
*swap = check_header(&buf[p], encrypted); if (*swap) { /* FIXME add full bitstream checking here */ return &buf[p];
@@ -191,7 +224,7 @@ static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) return FPGA_SUCCESS; }
-static int zynq_dma_xfer_init(bitstream_type bstype) +static int zynq_dma_xfer_init(bitstream_type bstype, bool encrypted) { u32 status, control, isr_status; unsigned long ts; @@ -291,6 +324,13 @@ static int zynq_dma_xfer_init(bitstream_type bstype) writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); }
- control = readl(&devcfg_base->ctrl);
- if (encrypted)
control |= DEVCFG_CTRL_PCAP_RATE_EN_MASK;
- else
control &= ~DEVCFG_CTRL_PCAP_RATE_EN_MASK;
- writel(control, &devcfg_base->ctrl);
- return FPGA_SUCCESS;
}
@@ -336,10 +376,11 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, size_t bsize, u32 blocksize, u32 *swap, bitstream_type *bstype) {
- bool encrypted = false; u32 *buf_start; u32 diff;
- buf_start = check_data((u8 *)buf, blocksize, swap);
buf_start = check_data((u8 *)buf, blocksize, swap, &encrypted);
if (!buf_start) return FPGA_FAIL;
@@ -358,7 +399,7 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, return FPGA_FAIL; }
- if (zynq_dma_xfer_init(*bstype))
if (zynq_dma_xfer_init(*bstype, encrypted)) return FPGA_FAIL;
return 0;
-- 2.7.4

Hi Siva,
-----Ursprüngliche Nachricht----- Von: Siva Durga Prasad Paladugu [mailto:sivadur@xilinx.com] Gesendet: Montag, 11. Juni 2018 13:40 An: stefan@herbrechtsmeier.net Cc: Herbrechtsmeier Dr.-Ing. , Stefan Stefan.Herbrechtsmeier@weidmueller.com; u-boot@lists.denx.de; Michal Simek michal.simek@xilinx.com; monstr@monstr.eu Betreff: RE: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Interesting, I got your point. First of all, Could you please let me know on how do you created the encrypted bitstream?
I use bootgen with the split option and the following bif file:
bootgen -image u-boot-spl-aes.bif -o i u-boot-spl-aes.bin -w on -encrypt efuse -split bin
image: { [aeskeyfile]efuse.nky [pskfile]psk.pem [sskfile]ssk.pem [bootloader, encryption=aes, authentication=rsa]u-boot-spl.elf [encryption=aes]fpga.bit }
I hope this is not the Xilinx bootgen flow(may be through other Xilinx flow)
To my knowledge you could only use bootgen because Xilinx doesn't documented the encryption even if I would like to integrate the encryption into mkimage.
because, I don't think bootgen will update these fields while creating encrypted bitstream( need to re confirm on this) and my flow targets the Xilinx bootgen flow.
This fields are part of the encrypted binary bitstream and are needed for the fpga configuration via the pcap. They are documented inside the 'ug470_7Series_Config.pdf'.
Please let know your comments on this, based on which, will try to review and test your patch.
Let me know if you need more information or help.
Regards
Stefan Herbrechtsmeier Software Developer Embedded Systems
Weidmüller - Your partner in Industrial Connectivity We look forward to sharing ideas with you - Let's connect.
Weidmueller Interface GmbH & Co. KG Klingenbergstraße 16, 32758 Detmold, Germany Email: Stefan.Herbrechtsmeier@weidmueller.com - Web: www.weidmueller.com
________________________________ Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - Komplementärin: Weidmüller Interface Führungsgesellschaft mbH - Sitz: Detmold - Amtsgericht Lemgo HRB 3924; Geschäftsführer: José Carlos Álvarez Tobar, Elke Eckstein, Jörg Timmermann; USt-ID-Nr. DE124599660

Hi Stefan,
-----Original Message----- From: Stefan.Herbrechtsmeier@weidmueller.com [mailto:Stefan.Herbrechtsmeier@weidmueller.com] Sent: Monday, June 11, 2018 9:33 PM To: Siva Durga Prasad Paladugu sivadur@xilinx.com; stefan@herbrechtsmeier.net Cc: u-boot@lists.denx.de; michal.simek@xilinx.com; monstr@monstr.eu Subject: AW: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Hi Siva,
-----Ursprüngliche Nachricht----- Von: Siva Durga Prasad Paladugu [mailto:sivadur@xilinx.com] Gesendet: Montag, 11. Juni 2018 13:40 An: stefan@herbrechtsmeier.net Cc: Herbrechtsmeier Dr.-Ing. , Stefan Stefan.Herbrechtsmeier@weidmueller.com; u-boot@lists.denx.de;
Michal
Simek michal.simek@xilinx.com; monstr@monstr.eu Betreff: RE: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Interesting, I got your point. First of all, Could you please let me know on how do you created the encrypted bitstream?
I use bootgen with the split option and the following bif file:
bootgen -image u-boot-spl-aes.bif -o i u-boot-spl-aes.bin -w on -encrypt efuse -split bin
image: { [aeskeyfile]efuse.nky [pskfile]psk.pem [sskfile]ssk.pem [bootloader, encryption=aes, authentication=rsa]u-boot-spl.elf [encryption=aes]fpga.bit }
I hope this is not the Xilinx bootgen flow(may be through other Xilinx flow)
To my knowledge you could only use bootgen because Xilinx doesn't documented the encryption even if I would like to integrate the encryption into mkimage.
because, I don't think bootgen will update these fields while creating encrypted bitstream( need to re confirm on this) and my flow targets the Xilinx bootgen flow.
This fields are part of the encrypted binary bitstream and are needed for the fpga configuration via the pcap. They are documented inside the 'ug470_7Series_Config.pdf'.
Please let know your comments on this, based on which, will try to review and test your patch.
Let me know if you need more information or help.
Thanks for the clarity, let me check on it and come back. Let me also look in to modify secure patch if required as per this.
Thanks, Siva
Regards
Stefan Herbrechtsmeier Software Developer Embedded Systems
Weidmüller - Your partner in Industrial Connectivity We look forward to sharing ideas with you - Let's connect.
Weidmueller Interface GmbH & Co. KG Klingenbergstraße 16, 32758 Detmold, Germany Email: Stefan.Herbrechtsmeier@weidmueller.com - Web: www.weidmueller.com
Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - Komplementärin: Weidmüller Interface Führungsgesellschaft mbH - Sitz: Detmold - Amtsgericht Lemgo HRB 3924; Geschäftsführer: José Carlos Álvarez Tobar, Elke Eckstein, Jörg Timmermann; USt-ID-Nr. DE124599660

Hi Stefan,
Yes, I checked and it looks fine functionally, I even tested it. Otherthan this, I have few comments on this which I am going to reply to your RFC patch mail.
Thanks, Siva
-----Original Message----- From: Siva Durga Prasad Paladugu Sent: Tuesday, June 12, 2018 9:18 AM To: Stefan.Herbrechtsmeier@weidmueller.com; stefan@herbrechtsmeier.net Cc: u-boot@lists.denx.de; michal.simek@xilinx.com; monstr@monstr.eu Subject: RE: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Hi Stefan,
-----Original Message----- From: Stefan.Herbrechtsmeier@weidmueller.com [mailto:Stefan.Herbrechtsmeier@weidmueller.com] Sent: Monday, June 11, 2018 9:33 PM To: Siva Durga Prasad Paladugu sivadur@xilinx.com; stefan@herbrechtsmeier.net Cc: u-boot@lists.denx.de; michal.simek@xilinx.com; monstr@monstr.eu Subject: AW: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Hi Siva,
-----Ursprüngliche Nachricht----- Von: Siva Durga Prasad Paladugu [mailto:sivadur@xilinx.com] Gesendet: Montag, 11. Juni 2018 13:40 An: stefan@herbrechtsmeier.net Cc: Herbrechtsmeier Dr.-Ing. , Stefan Stefan.Herbrechtsmeier@weidmueller.com; u-boot@lists.denx.de;
Michal
Simek michal.simek@xilinx.com; monstr@monstr.eu Betreff: RE: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Interesting, I got your point. First of all, Could you please let me know on how do you created the encrypted bitstream?
I use bootgen with the split option and the following bif file:
bootgen -image u-boot-spl-aes.bif -o i u-boot-spl-aes.bin -w on -encrypt efuse -split bin
image: { [aeskeyfile]efuse.nky [pskfile]psk.pem [sskfile]ssk.pem [bootloader, encryption=aes, authentication=rsa]u-boot-spl.elf [encryption=aes]fpga.bit }
I hope this is not the Xilinx bootgen flow(may be through other Xilinx flow)
To my knowledge you could only use bootgen because Xilinx doesn't documented the encryption even if I would like to integrate the encryption into mkimage.
because, I don't think bootgen will update these fields while creating encrypted bitstream( need to re confirm on this) and my flow targets the Xilinx bootgen flow.
This fields are part of the encrypted binary bitstream and are needed for the fpga configuration via the pcap. They are documented inside the 'ug470_7Series_Config.pdf'.
Please let know your comments on this, based on which, will try to review and test your patch.
Let me know if you need more information or help.
Thanks for the clarity, let me check on it and come back. Let me also look in to modify secure patch if required as per this.
Thanks, Siva
Regards
Stefan Herbrechtsmeier Software Developer Embedded Systems
Weidmüller - Your partner in Industrial Connectivity We look forward to sharing ideas with you - Let's connect.
Weidmueller Interface GmbH & Co. KG Klingenbergstraße 16, 32758 Detmold, Germany Email: Stefan.Herbrechtsmeier@weidmueller.com - Web: www.weidmueller.com
Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - Komplementärin: Weidmüller Interface Führungsgesellschaft mbH - Sitz: Detmold - Amtsgericht Lemgo HRB 3924; Geschäftsführer: José Carlos Álvarez Tobar, Elke Eckstein, Jörg Timmermann; USt-ID-Nr. DE124599660

Hi Stefan,
-----Original Message----- From: stefan@herbrechtsmeier.net [mailto:stefan@herbrechtsmeier.net] Sent: Friday, June 08, 2018 5:29 PM To: Siva Durga Prasad Paladugu sivadur@xilinx.com Cc: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com; u-boot@lists.denx.de; Michal Simek michal.simek@xilinx.com; monstr@monstr.eu Subject: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with auto detect
Patch description here please.
From: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
Signed-off-by: Stefan Herbrechtsmeier stefan.herbrechtsmeier@weidmueller.com
drivers/fpga/zynqpl.c | 73 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 16 deletions(-)
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index fd37d18..6622750 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -17,6 +17,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 @@ -38,18 +39,16 @@ #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ #endif
+#define NOP_WORD 0x20000000 +#define CTRL0_WORD 0x3000a001 +#define MASK_WORD 0x3000c001 #define DUMMY_WORD 0xffffffff
+#define CTRL0_DEC_MASK BIT(6)
/* Xilinx binary format header */ +#define MAX_DUMMY_WORD_COUNT 8 static const u32 bin_format[] = {
- DUMMY_WORD, /* Dummy words */
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD,
- DUMMY_WORD, 0x000000bb, /* Sync word */ 0x11220044, /* Sync word */ DUMMY_WORD,
@@ -85,7 +84,23 @@ static u32 load_word(const void *buf, u32 swap) return word; }
-static u32 check_header(const void *buf) +static void *skip_dummy_words(const void *buf) {
- u32 *test = (u32 *)buf;
- u32 i;
- for (i = 0; i < MAX_DUMMY_WORD_COUNT; i++) {
if (load_word(&test[i], SWAP_NO) != DUMMY_WORD) {
debug("%s: Found no dummy word at position
%d/%x\n",
__func__, i, (u32)&test[i]);
return &test[i];
}
- }
- return &test[i];
+}
+static u32 check_header(const void *buf, bool *encrypted) { u32 i, pattern; int swap = SWAP_NO; @@ -93,6 +108,8 @@ static u32 check_header(const void *buf)
debug("%s: Let's check bitstream header\n", __func__);
- test = (u32 *)skip_dummy_words(buf);
- /* Checking that passing bin is not a bitstream */ for (i = 0; i < ARRAY_SIZE(bin_format); i++) { pattern = load_word(&test[i], swap);
@@ -112,18 +129,34 @@ static u32 check_header(const void *buf)
debug("%s: %d/%x: pattern %x/%x bin_format\n",
__func__, i, (u32)&test[i], pattern, bin_format[i]);
- if (pattern != bin_format[i]) { debug("%s: Bitstream is not recognized\n",
__func__); return 0; } }
- debug("%s: Found bitstream header at %x %s swapinng\n",
__func__,
(u32)buf, swap == SWAP_NO ? "without" : "with");
- test = &test[i];
- /* Checking if passing bin is an encrypted bitstream */
- if ((load_word(&test[0], swap) == NOP_WORD) &&
(load_word(&test[1], swap) == MASK_WORD) &&
(load_word(&test[2], swap) & CTRL0_DEC_MASK) &&
(load_word(&test[3], swap) == CTRL0_WORD) &&
(load_word(&test[4], swap) & CTRL0_DEC_MASK) &&
(load_word(&test[5], swap) == NOP_WORD))
*encrypted = true;
- else
*encrypted = false;
- debug("%s: Found %sencrypted bitstream header at %x %s
swapping\n",
__func__, *encrypted ? "" : "un", (u32)buf,
swap == SWAP_NO ? "without" : "with");
return swap;
}
-static void *check_data(u8 *buf, size_t bsize, u32 *swap) +static void *check_data(u8 *buf, size_t bsize, u32 *swap, bool +*encrypted) { u32 word, p = 0; /* possition */
@@ -136,7 +169,7 @@ static void *check_data(u8 *buf, size_t bsize, u32 *swap) if (word == DUMMY_WORD) { debug("%s: Found dummy word at position %x/%x\n", __func__, p, (u32)&buf[p]);
*swap = check_header(&buf[p]);
*swap = check_header(&buf[p], encrypted); if (*swap) { /* FIXME add full bitstream checking here */ return &buf[p];
@@ -191,7 +224,7 @@ static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) return FPGA_SUCCESS; }
-static int zynq_dma_xfer_init(bitstream_type bstype) +static int zynq_dma_xfer_init(bitstream_type bstype, bool encrypted) { u32 status, control, isr_status; unsigned long ts; @@ -291,6 +324,13 @@ static int zynq_dma_xfer_init(bitstream_type bstype) writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); }
- control = readl(&devcfg_base->ctrl);
- if (encrypted)
control |= DEVCFG_CTRL_PCAP_RATE_EN_MASK;
- else
control &= ~DEVCFG_CTRL_PCAP_RATE_EN_MASK;
Clearing here is fine. Can we do the same at the end of bitstream programming because we should clear it once we are done, just to be in proper state for next component.
- writel(control, &devcfg_base->ctrl);
- return FPGA_SUCCESS;
}
@@ -336,10 +376,11 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, size_t bsize, u32 blocksize, u32 *swap, bitstream_type *bstype) {
- bool encrypted = false; u32 *buf_start; u32 diff;
- buf_start = check_data((u8 *)buf, blocksize, swap);
buf_start = check_data((u8 *)buf, blocksize, swap, &encrypted);
if (!buf_start) return FPGA_FAIL;
@@ -358,7 +399,7 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, return FPGA_FAIL; }
I think here we should add condition to check if AES engine is enabled in case of encrypted bitstream and return error if not enabled.
AES engine enablement can be checked using PCFG_AES_EN bits 9-11 of control register.
Thanks, Siva
- if (zynq_dma_xfer_init(*bstype))
if (zynq_dma_xfer_init(*bstype, encrypted)) return FPGA_FAIL;
return 0;
-- 2.7.4
participants (3)
-
Siva Durga Prasad Paladugu
-
Stefan.Herbrechtsmeier@weidmueller.com
-
stefan@herbrechtsmeier.net