]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
fpga manager: Adopted Authenticated BitStream loading support for Xilinx
authorNava kishore Manne <nava.manne@xilinx.com>
Mon, 13 Feb 2017 15:26:38 +0000 (20:56 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 16 Feb 2017 10:01:58 +0000 (11:01 +0100)
This commit adds Authenticated BitStream Loading support for the Xilinx
ZynqMp chip.

Signed-off-by: Nava kishore Manne <navam@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/fpga/fpga-mgr.c
drivers/fpga/zynqmp-fpga.c
include/linux/fpga/fpga-mgr.h

index d8473ef18ea164c371590169903a8dd4f4d89c8f..cfe2b165f53c63b9b4932dc9b43f50848d7e047f 100644 (file)
@@ -130,6 +130,50 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load);
 
+int fpga_mgr_signature_load(struct fpga_manager *mgr,
+                               const char *image_name)
+{
+       struct device *dev = &mgr->dev;
+       const struct firmware *fw;
+       int ret;
+
+       dev_info(dev, "Loading %s to %s\n", image_name, mgr->name);
+
+       ret = request_firmware(&fw, image_name, dev);
+       if (ret) {
+               dev_err(dev, "Error requesting firmware %s\n", image_name);
+               return ret;
+       }
+
+       memcpy(mgr->signature, fw->data, fw->size);
+
+       release_firmware(fw);
+
+       return ret;
+}
+
+int fpga_mgr_pubkey_load(struct fpga_manager *mgr,
+                               const char *image_name)
+{
+       struct device *dev = &mgr->dev;
+       const struct firmware *fw;
+       int ret;
+
+       dev_info(dev, "Loading %s to %s\n", image_name, mgr->name);
+
+       ret = request_firmware(&fw, image_name, dev);
+       if (ret) {
+               dev_err(dev, "Error requesting firmware %s\n", image_name);
+               return ret;
+       }
+
+       memcpy(mgr->pubkey, fw->data, fw->size);
+
+       release_firmware(fw);
+
+       return ret;
+}
+
 static const char * const state_str[] = {
        [FPGA_MGR_STATE_UNKNOWN] =              "unknown",
        [FPGA_MGR_STATE_POWER_OFF] =            "power off",
@@ -194,6 +238,50 @@ static ssize_t firmware_store(struct device *dev,
        return count;
 }
 
+static ssize_t signature_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct fpga_manager *mgr = to_fpga_manager(dev);
+       unsigned int len;
+       char image_name[NAME_MAX];
+       int ret;
+
+       /* lose terminating \n */
+       strcpy(image_name, buf);
+       len = strlen(image_name);
+       if (image_name[len - 1] == '\n')
+               image_name[len - 1] = 0;
+
+       ret = fpga_mgr_signature_load(mgr, image_name);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static ssize_t pubkey_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct fpga_manager *mgr = to_fpga_manager(dev);
+       unsigned int len;
+       char image_name[NAME_MAX];
+       int ret;
+
+       /* lose terminating \n */
+       strcpy(image_name, buf);
+       len = strlen(image_name);
+       if (image_name[len - 1] == '\n')
+               image_name[len - 1] = 0;
+
+       ret = fpga_mgr_pubkey_load(mgr, image_name);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
 static ssize_t key_show(struct device *dev,
                        struct device_attribute *attr, char *buf)
 {
@@ -257,6 +345,8 @@ static ssize_t flags_store(struct device *dev,
 static DEVICE_ATTR_RO(name);
 static DEVICE_ATTR_RO(state);
 static DEVICE_ATTR_WO(firmware);
+static DEVICE_ATTR_WO(signature);
+static DEVICE_ATTR_WO(pubkey);
 static DEVICE_ATTR_RW(flags);
 static DEVICE_ATTR_RW(key);
 static DEVICE_ATTR_RW(iv);
@@ -265,6 +355,8 @@ static struct attribute *fpga_mgr_attrs[] = {
        &dev_attr_name.attr,
        &dev_attr_state.attr,
        &dev_attr_firmware.attr,
+       &dev_attr_signature.attr,
+       &dev_attr_pubkey.attr,
        &dev_attr_flags.attr,
        &dev_attr_key.attr,
        &dev_attr_iv.attr,
index f8a539ce7a6794f58a9912f5d816b710593d17cf..0304ce5a6327dc9f9c11065b5fdc8b13130dc726 100644 (file)
@@ -24,6 +24,7 @@
 
 /* Constant Definitions */
 #define IXR_FPGA_DONE_MASK     0X00000008U
+#define IXR_FPGA_AUTHENTICATIN 0x00000004U
 #define IXR_FPGA_ENCRYPTION_EN 0x00000008U
 
 struct zynqmp_fpga_priv {
@@ -47,17 +48,17 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
 {
        struct zynqmp_fpga_priv *priv;
        char *kbuf;
-       size_t dma_size;
+       size_t dma_size = size;
        dma_addr_t dma_addr;
        u32 transfer_length;
        int ret;
 
        priv = mgr->priv;
 
+       if (mgr->flags & IXR_FPGA_AUTHENTICATIN)
+               dma_size = dma_size + SIGNATURE_LEN + PUBLIC_KEY_LEN;
        if (mgr->flags & IXR_FPGA_ENCRYPTION_EN)
-               dma_size = size + ENCRYPTED_KEY_LEN + ENCRYPTED_IV_LEN;
-       else
-               dma_size = size;
+               dma_size = dma_size + ENCRYPTED_KEY_LEN + ENCRYPTED_IV_LEN;
 
        kbuf = dma_alloc_coherent(priv->dev, dma_size, &dma_addr, GFP_KERNEL);
        if (!kbuf)
@@ -65,6 +66,11 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
 
        memcpy(kbuf, buf, size);
 
+       if (mgr->flags & IXR_FPGA_AUTHENTICATIN) {
+               memcpy(kbuf + size, mgr->signature, SIGNATURE_LEN);
+               memcpy(kbuf + size + SIGNATURE_LEN, mgr->pubkey,
+                                               PUBLIC_KEY_LEN);
+       }
        if (mgr->flags & IXR_FPGA_ENCRYPTION_EN) {
                memcpy(kbuf + size, mgr->key, ENCRYPTED_KEY_LEN);
                memcpy(kbuf + size + ENCRYPTED_KEY_LEN, mgr->iv,
index 6ed3d6c2f1b10befcd354be7d13d4493cb0c9390..207d9d25d436a2ba4894f75cb4387df26fc22be8 100644 (file)
@@ -23,6 +23,8 @@
 
 #define ENCRYPTED_KEY_LEN      64 /* Bytes */
 #define ENCRYPTED_IV_LEN       24 /* Bytes */
+#define SIGNATURE_LEN          512 /* Bytes */
+#define PUBLIC_KEY_LEN         516 /* Bytes */
 
 struct fpga_manager;
 
@@ -106,6 +108,8 @@ struct fpga_manager {
        long int flags;
        char key[ENCRYPTED_KEY_LEN];
        char iv[ENCRYPTED_IV_LEN];
+       char signature[SIGNATURE_LEN];
+       char pubkey[PUBLIC_KEY_LEN];
        struct device dev;
        struct mutex ref_mutex;
        enum fpga_mgr_states state;