[RFC PATCH V3 2/4] firmware: xilinx: Add ZynqMP sha_hash API for SHA3 functionality

2019-05-02 Thread Kalyani Akula
Add ZynqMP firmware SHA_HASH API to compute SHA3 hash of given data.

Signed-off-by: Kalyani Akula 
---
 drivers/firmware/xilinx/zynqmp.c | 27 +++
 include/linux/firmware/xlnx-zynqmp.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 98f9361..22a062a 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -619,9 +619,36 @@ static int zynqmp_pm_set_requirement(const u32 node, const 
u32 capabilities,
   qos, ack, NULL);
 }
 
+/**
+ * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
+ * @address:   Address of the data/ Address of output buffer where
+ * hash should be stored.
+ * @size:  Size of the data.
+ * @flags:
+ * BIT(0) - for initializing csudma driver and SHA3(Here address
+ *  and size inputs can be NULL).
+ * BIT(1) - to call Sha3_Update API which can be called multiple
+ *  times when data is not contiguous.
+ * BIT(2) - to get final hash of the whole updated data.
+ *  Hash will be overwritten at provided address with
+ *  48 bytes.
+ *
+ * Return: Returns status, either success or error code.
+ */
+static int zynqmp_pm_sha_hash(const u64 address, const u32 size,
+ const u32 flags)
+{
+   u32 lower_32_bits = (u32)address;
+   u32 upper_32_bits = (u32)(address >> 32);
+
+   return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_32_bits, lower_32_bits,
+  size, flags, NULL);
+}
+
 static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
.get_chipid = zynqmp_pm_get_chipid,
+   .sha_hash = zynqmp_pm_sha_hash,
.query_data = zynqmp_pm_query_data,
.clock_enable = zynqmp_pm_clock_enable,
.clock_disable = zynqmp_pm_clock_disable,
diff --git a/include/linux/firmware/xlnx-zynqmp.h 
b/include/linux/firmware/xlnx-zynqmp.h
index 642dab1..124e5f0 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -57,6 +57,7 @@ enum pm_api_id {
PM_RESET_GET_STATUS,
PM_PM_INIT_FINALIZE = 21,
PM_GET_CHIPID = 24,
+   PM_SECURE_SHA = 26,
PM_IOCTL = 34,
PM_QUERY_DATA,
PM_CLOCK_ENABLE,
@@ -283,6 +284,7 @@ struct zynqmp_eemi_ops {
   const u32 capabilities,
   const u32 qos,
   const enum zynqmp_pm_request_ack ack);
+   int (*sha_hash)(const u64 address, const u32 size, const u32 flags);
 };
 
 int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
-- 
1.9.5



[RFC PATCH V3 1/4] dt-bindings: crypto: Add bindings for ZynqMP SHA3 driver

2019-05-02 Thread Kalyani Akula
Add documentation to describe Xilinx ZynqMP SHA3 driver
bindings.

Signed-off-by: Kalyani Akula 
---
 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt

diff --git a/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt 
b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
new file mode 100644
index 000..8b3cc55
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
@@ -0,0 +1,12 @@
+Xilinx ZynqMP SHA3(keccak-384) hw acceleration support.
+
+The ZynqMp PS-SHA hw accelerator is used to calculate the
+SHA3(keccak-384) hash value on the given user data.
+
+Required properties:
+- compatible:  should contain "xlnx,zynqmp-sha3-384"
+
+Example:
+   xlnx_sha3_384: sha384 {
+   compatible = "xlnx,zynqmp-sha3-384";
+   };
-- 
1.9.5



[RFC PATCH 0/5] Add Xilinx's ZynqMP AES driver support

2019-01-16 Thread Kalyani Akula
This patch set adds support for
- dt-binding docs for Xilinx ZynqMP AES driver
- Adds device tree node for ZynqMP SHA3 driver
- Adds communication layer support for aes in zynqmp.c
- Adds user space interface for ALG_SET_KEY_TYPE
- Adds Xilinx ZynqMP driver for AES Algorithm

Kalyani Akula (5):
  dt-bindings: crypto: Add bindings for ZynqMP AES driver
  ARM64: zynqmp: Add Xilinix AES node.
  firmware: xilinx: Add ZynqMP aes API for AES functionality
  crypto: Adds user space interface for ALG_SET_KEY_TYPE
  crypto: Add Xilinx AES driver

 .../devicetree/bindings/crypto/xlnx,zynqmp-aes.txt |  12 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi |   4 +
 crypto/af_alg.c|   7 +
 crypto/algif_skcipher.c|   7 +
 crypto/blkcipher.c |   9 +
 crypto/skcipher.c  |  18 ++
 drivers/crypto/Kconfig |  11 +
 drivers/crypto/Makefile|   1 +
 drivers/crypto/zynqmp-aes.c| 331 +
 drivers/firmware/xilinx/zynqmp.c   |  24 ++
 include/crypto/if_alg.h|   2 +
 include/crypto/skcipher.h  |  10 +
 include/linux/crypto.h |  12 +
 include/linux/firmware/xlnx-zynqmp.h   |   2 +
 include/uapi/linux/if_alg.h|   1 +
 15 files changed, 451 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt
 create mode 100644 drivers/crypto/zynqmp-aes.c

-- 
1.9.5



[RFC PATCH 4/5] crypto: Adds user space interface for ALG_SET_KEY_TYPE

2019-01-16 Thread Kalyani Akula
ALG_SET_KEY_TYPE requires caller to pass the key_type to be used
for AES encryption/decryption.

Sometimes the cipher key will be stored in the
device's hardware. So, there is a need to specify
the information about the key to use for AES operations.

In Xilinx ZynqMP SoC, below key types are available

1. Device key, which is flashed in the HW.

2. PUF KEK, which can be regenerated using the
   helper data programmed in the HW.

3. User supplied key.

So to choose the AES key to be used, this patch adds key-type attribute.

Signed-off-by: Kalyani Akula 
---
 crypto/af_alg.c |  7 +++
 crypto/algif_skcipher.c |  7 +++
 crypto/blkcipher.c  |  9 +
 crypto/skcipher.c   | 18 ++
 include/crypto/if_alg.h |  2 ++
 include/crypto/skcipher.h   | 10 ++
 include/linux/crypto.h  | 12 
 include/uapi/linux/if_alg.h |  1 +
 8 files changed, 66 insertions(+)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 17eb09d..c3c0660 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -261,6 +261,13 @@ static int alg_setsockopt(struct socket *sock, int level, 
int optname,
if (!type->setauthsize)
goto unlock;
err = type->setauthsize(ask->private, optlen);
+   break;
+   case ALG_SET_KEY_TYPE:
+   if (sock->state == SS_CONNECTED)
+   goto unlock;
+   if (!type->setkeytype)
+   goto unlock;
+   err = type->setkeytype(ask->private, optval, optlen);
}
 
 unlock:
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index cfdaab2..9911a56 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -320,6 +320,12 @@ static int skcipher_setkey(void *private, const u8 *key, 
unsigned int keylen)
return crypto_skcipher_setkey(private, key, keylen);
 }
 
+static int skcipher_setkeytype(void *private, const u8 *key,
+  unsigned int keylen)
+{
+   return crypto_skcipher_setkeytype(private, key, keylen);
+}
+
 static void skcipher_sock_destruct(struct sock *sk)
 {
struct alg_sock *ask = alg_sk(sk);
@@ -384,6 +390,7 @@ static int skcipher_accept_parent(void *private, struct 
sock *sk)
.bind   =   skcipher_bind,
.release=   skcipher_release,
.setkey =   skcipher_setkey,
+   .setkeytype =   skcipher_setkeytype,
.accept =   skcipher_accept_parent,
.accept_nokey   =   skcipher_accept_parent_nokey,
.ops=   _skcipher_ops,
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index c5398bd..8922f58 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -408,6 +408,14 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, 
unsigned int keylen)
return cipher->setkey(tfm, key, keylen);
 }
 
+static int setkeytype(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+   struct blkcipher_alg *cipher = >__crt_alg->cra_blkcipher;
+
+   return cipher->setkeytype(tfm, key, keylen);
+}
+
 static int async_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
unsigned int keylen)
 {
@@ -478,6 +486,7 @@ static int crypto_init_blkcipher_ops_sync(struct crypto_tfm 
*tfm)
unsigned long addr;
 
crt->setkey = setkey;
+   crt->setkeytype = setkeytype;
crt->encrypt = alg->encrypt;
crt->decrypt = alg->decrypt;
 
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 2a96929..6a2a0dd 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -605,6 +605,23 @@ static int skcipher_setkey_blkcipher(struct 
crypto_skcipher *tfm,
return 0;
 }
 
+static int skcipher_setkeytype_blkcipher(struct crypto_skcipher *tfm,
+const u8 *key, unsigned int keylen)
+{
+   struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm);
+   struct crypto_blkcipher *blkcipher = *ctx;
+   int err;
+
+   crypto_blkcipher_clear_flags(blkcipher, ~0);
+   crypto_blkcipher_set_flags(blkcipher, crypto_skcipher_get_flags(tfm) &
+   CRYPTO_TFM_REQ_MASK);
+   err = crypto_blkcipher_setkeytype(blkcipher, key, keylen);
+   crypto_skcipher_set_flags(tfm, crypto_blkcipher_get_flags(blkcipher) &
+   CRYPTO_TFM_RES_MASK);
+
+   return err;
+}
+
 static int skcipher_crypt_blkcipher(struct skcipher_request *req,
int (*crypt)(struct blkcipher_desc *,
 struct scatterlist *,
@@ -671,6 +688,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct 
crypto_tfm *tfm)
tfm->exit = crypto_exit_skcipher_ops_blkcipher;
 
skcipher->setkey = skcipher_setkey_blkcipher;
+   skcipher->s

[RFC PATCH 3/5] firmware: xilinx: Add ZynqMP aes API for AES functionality

2019-01-16 Thread Kalyani Akula
Add ZynqMP firmware AES API to perform encryption/decryption
of given data.

Signed-off-by: Kalyani Akula 
---
 drivers/firmware/xilinx/zynqmp.c | 24 
 include/linux/firmware/xlnx-zynqmp.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 9a1c72a..332f98c1 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -469,6 +469,29 @@ static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 
arg1, u32 arg2,
   arg1, arg2, out);
 }
 
+/**
+ * zynqmp_pm_aes - Access AES hardware to encrypt/decrypt the data using
+ * AES-GCM core.
+ * @address:   Address of the AesParams structure.
+ * @out:   Returned output value
+ *
+ * Return: Returns status, either success or error code.
+ */
+static int zynqmp_pm_aes_engine(const u64 address, u32 *out)
+{
+   u32 ret_payload[PAYLOAD_ARG_CNT];
+   int ret;
+
+   if (!out)
+   return -EINVAL;
+
+   ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address),
+ lower_32_bits(address),
+ 0, 0, ret_payload);
+   *out = ret_payload[1];
+   return ret;
+}
+
 static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
.query_data = zynqmp_pm_query_data,
@@ -482,6 +505,7 @@ static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 
arg1, u32 arg2,
.clock_setparent = zynqmp_pm_clock_setparent,
.clock_getparent = zynqmp_pm_clock_getparent,
.ioctl = zynqmp_pm_ioctl,
+   .aes = zynqmp_pm_aes_engine,
 };
 
 /**
diff --git a/include/linux/firmware/xlnx-zynqmp.h 
b/include/linux/firmware/xlnx-zynqmp.h
index 3c3c28e..815fa30 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -45,6 +45,7 @@ enum pm_api_id {
PM_CLOCK_GETRATE,
PM_CLOCK_SETPARENT,
PM_CLOCK_GETPARENT,
+   PM_SECURE_AES = 47,
 };
 
 /* PMU-FW return status codes */
@@ -102,6 +103,7 @@ struct zynqmp_eemi_ops {
int (*clock_setparent)(u32 clock_id, u32 parent_id);
int (*clock_getparent)(u32 clock_id, u32 *parent_id);
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
+   int (*aes)(const u64 address, u32 *out);
 };
 
 #if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
-- 
1.9.5



[RFC PATCH 2/5] ARM64: zynqmp: Add Xilinix AES node.

2019-01-16 Thread Kalyani Akula
This patch adds a AES DT node for Xilinx ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi 
b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index fa4fd77..a3e8332 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -124,6 +124,10 @@
 <1 10 0xf08>;
};
 
+   xlnx_aes: zynqmp_aes {
+   compatible = "xlnx,zynqmp-aes";
+   };
+
amba_apu: amba-apu@0 {
compatible = "simple-bus";
#address-cells = <2>;
-- 
1.9.5



[RFC PATCH 5/5] crypto: Add Xilinx AES driver

2019-01-16 Thread Kalyani Akula
This patch adds AES driver support for the Xilinx
ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 drivers/crypto/Kconfig  |  11 ++
 drivers/crypto/Makefile |   1 +
 drivers/crypto/zynqmp-aes.c | 331 
 3 files changed, 343 insertions(+)
 create mode 100644 drivers/crypto/zynqmp-aes.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 5a90075..66d9faa 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -667,6 +667,17 @@ config CRYPTO_DEV_ROCKCHIP
  This driver interfaces with the hardware crypto accelerator.
  Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.
 
+config CRYPTO_DEV_ZYNQMP_AES
+   tristate "Support for Xilinx ZynqMP AES hw accelerator"
+   depends on ARCH_ZYNQMP || COMPILE_TEST
+   select CRYPTO_AES
+   select CRYPTO_BLKCIPHER
+   help
+ Xilinx ZynqMP has AES-GCM engine used for symmetric key
+ encryption and decryption. This driver interfaces with AES hw
+ accelerator. Select this if you want to use the ZynqMP module
+ for AES algorithms.
+
 config CRYPTO_DEV_MEDIATEK
tristate "MediaTek's EIP97 Cryptographic Engine driver"
depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 8e7e225..991b343 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
 obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
 obj-y += hisilicon/
+obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes.o
diff --git a/drivers/crypto/zynqmp-aes.c b/drivers/crypto/zynqmp-aes.c
new file mode 100644
index 000..3a38d2d
--- /dev/null
+++ b/drivers/crypto/zynqmp-aes.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP AES Driver.
+ * Copyright (c) 2018 Xilinx Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZYNQMP_AES_QUEUE_LENGTH1
+#define ZYNQMP_AES_IV_SIZE 12
+#define ZYNQMP_AES_GCM_SIZE16
+#define ZYNQMP_AES_KEY_SIZE32
+
+#define ZYNQMP_AES_DECRYPT 0
+#define ZYNQMP_AES_ENCRYPT 1
+
+#define ZYNQMP_AES_KUP_KEY 0
+
+#define ZYNQMP_AES_GCM_TAG_MISMATCH_ERR0x01
+#define ZYNQMP_AES_SIZE_ERR0x06
+#define ZYNQMP_AES_WRONG_KEY_SRC_ERR   0x13
+#define ZYNQMP_AES_PUF_NOT_PROGRAMMED  0xE300
+
+#define ZYNQMP_AES_BLOCKSIZE   0x04
+
+struct zynqmp_aes_dev {
+   struct list_head list;
+   struct device *dev;
+   /* the lock protects queue and dev list */
+   spinlock_t lock;
+   struct crypto_queue queue;
+};
+
+struct zynqmp_aes_op {
+   struct zynqmp_aes_dev *dd;
+   void *src;
+   void *dst;
+   int len;
+   u8 key[ZYNQMP_AES_KEY_SIZE];
+   u8 *iv;
+   u32 keylen;
+   u32 keytype;
+};
+
+struct zynqmp_aes_data {
+   u64 src;
+   u64 iv;
+   u64 key;
+   u64 dst;
+   u64 size;
+   u64 optype;
+   u64 keysrc;
+};
+
+struct zynqmp_aes_drv {
+   struct list_head dev_list;
+   /* the lock protects dev list */
+   spinlock_t lock;
+};
+
+static struct zynqmp_aes_drv zynqmp_aes = {
+   .dev_list = LIST_HEAD_INIT(zynqmp_aes.dev_list),
+   .lock = __SPIN_LOCK_UNLOCKED(zynqmp_aes.lock),
+};
+
+static struct zynqmp_aes_dev *zynqmp_aes_find_dev(struct zynqmp_aes_op *ctx)
+{
+   struct zynqmp_aes_dev *aes_dd = NULL;
+   struct zynqmp_aes_dev *tmp;
+
+   spin_lock_bh(_aes.lock);
+   if (!ctx->dd) {
+   list_for_each_entry(tmp, _aes.dev_list, list) {
+   aes_dd = tmp;
+   break;
+   }
+   ctx->dd = aes_dd;
+   } else {
+   aes_dd = ctx->dd;
+   }
+   spin_unlock_bh(_aes.lock);
+
+   return aes_dd;
+}
+
+static int zynqmp_setkey_blk(struct crypto_tfm *tfm, const u8 *key,
+unsigned int len)
+{
+   struct zynqmp_aes_op *op = crypto_tfm_ctx(tfm);
+
+   op->keylen = len;
+   memcpy(op->key, key, len);
+
+   return 0;
+}
+
+static int zynqmp_setkeytype(struct crypto_tfm *tfm, const u8 *keytype,
+unsigned int len)
+{
+   struct zynqmp_aes_op *op = crypto_tfm_ctx(tfm);
+
+   op->keytype = (u32)(*keytype);
+
+   return 0;
+}
+
+static int zynqmp_aes_xcrypt(struct blkcipher_desc *desc,
+struct scatterlist *dst,
+struct scatterlist *src,
+unsigned int nbytes,
+unsigned int flags)
+{
+   struct zynqmp_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
+ 

[RFC PATCH 1/5] dt-bindings: crypto: Add bindings for ZynqMP AES driver

2019-01-16 Thread Kalyani Akula
Add documentation to describe Xilinx ZynqMP AES driver
bindings.

Signed-off-by: Kalyani Akula 
---
 Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt

diff --git a/Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt 
b/Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt
new file mode 100644
index 000..226bfb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.txt
@@ -0,0 +1,12 @@
+Xilinx ZynqMP AES hw acceleration support
+
+The ZynqMP PS-AES hw accelerator is used to encrypt/decrypt
+the given user data.
+
+Required properties:
+- compatible: should contain "xlnx,zynqmp-aes"
+
+Example:
+   zynqmp_aes {
+   compatible = "xlnx,zynqmp-aes";
+   };
-- 
1.9.5



[RFC PATCH V2 2/4] firmware: xilinx: Add ZynqMP sha_hash API for SHA3 functionality

2019-01-09 Thread Kalyani Akula
Add ZynqMP firmware SHA_HASH API to compute SHA3 hash of given data.

Signed-off-by: Kalyani Akula 
---
 drivers/firmware/xilinx/zynqmp.c |   27 +++
 include/linux/firmware/xlnx-zynqmp.h |2 ++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 9a1c72a..c51ecce 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -469,8 +469,35 @@ static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 
arg1, u32 arg2,
   arg1, arg2, out);
 }
 
+/**
+ * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
+ * @address:   Address of the data/ Address of output buffer where
+ * hash should be stored.
+ * @size:  Size of the data.
+ * @flags:
+ * BIT(0) - for initializing csudma driver and SHA3(Here address
+ *  and size inputs can be NULL).
+ * BIT(1) - to call Sha3_Update API which can be called multiple
+ *  times when data is not contiguous.
+ * BIT(2) - to get final hash of the whole updated data.
+ *  Hash will be overwritten at provided address with
+ *  48 bytes.
+ *
+ * Return: Returns status, either success or error code.
+ */
+static int zynqmp_pm_sha_hash(const u64 address, const u32 size,
+ const u32 flags)
+{
+   u32 lower_32_bits = (u32)address;
+   u32 upper_32_bits = (u32)(address >> 32);
+
+   return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_32_bits, lower_32_bits,
+  size, flags, NULL);
+}
+
 static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
+   .sha_hash = zynqmp_pm_sha_hash,
.query_data = zynqmp_pm_query_data,
.clock_enable = zynqmp_pm_clock_enable,
.clock_disable = zynqmp_pm_clock_disable,
diff --git a/include/linux/firmware/xlnx-zynqmp.h 
b/include/linux/firmware/xlnx-zynqmp.h
index 3c3c28e..72ffe09 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -34,6 +34,7 @@
 
 enum pm_api_id {
PM_GET_API_VERSION = 1,
+   PM_SECURE_SHA = 26,
PM_IOCTL = 34,
PM_QUERY_DATA,
PM_CLOCK_ENABLE,
@@ -102,6 +103,7 @@ struct zynqmp_eemi_ops {
int (*clock_setparent)(u32 clock_id, u32 parent_id);
int (*clock_getparent)(u32 clock_id, u32 *parent_id);
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
+   int (*sha_hash)(const u64 address, const u32 size, const u32 flags);
 };
 
 #if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
-- 
1.7.1



[RFC PATCH V2 4/4] ARM64: zynqmp: Add Xilinix SHA-384 node.

2019-01-09 Thread Kalyani Akula
This patch adds a SHA3 DT node for Xilinx ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi 
b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index fa4fd77..a3be330 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -124,6 +124,10 @@
 <1 10 0xf08>;
};
 
+   xlnx_keccak_384: sha384 {
+   compatible = "xlnx,zynqmp-keccak-384";
+   };
+
amba_apu: amba-apu@0 {
compatible = "simple-bus";
#address-cells = <2>;
-- 
1.7.1



[RFC PATCH V2 3/4] crypto: Add Xilinx SHA3 driver

2019-01-09 Thread Kalyani Akula
This patch adds SHA3 driver support for the Xilinx
ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 drivers/crypto/Kconfig  |   10 ++
 drivers/crypto/Makefile |1 +
 drivers/crypto/zynqmp-sha.c |  305 +++
 3 files changed, 316 insertions(+), 0 deletions(-)
 create mode 100644 drivers/crypto/zynqmp-sha.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 5a90075..b723e23 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -667,6 +667,16 @@ config CRYPTO_DEV_ROCKCHIP
  This driver interfaces with the hardware crypto accelerator.
  Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.
 
+config CRYPTO_DEV_ZYNQMP_SHA3
+   tristate "Support for Xilinx ZynqMP SHA3 hw accelerator"
+   depends on ARCH_ZYNQMP || COMPILE_TEST
+   select CRYPTO_HASH
+   help
+ Xilinx ZynqMP has SHA3 engine used for secure hash calculation.
+ This driver interfaces with SHA3 hw engine.
+ Select this if you want to use the ZynqMP module
+ for SHA3 hash computation.
+
 config CRYPTO_DEV_MEDIATEK
tristate "MediaTek's EIP97 Cryptographic Engine driver"
depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 8e7e225..64c29fe 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
 obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
 obj-y += hisilicon/
+obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o
diff --git a/drivers/crypto/zynqmp-sha.c b/drivers/crypto/zynqmp-sha.c
new file mode 100644
index 000..56e83cf
--- /dev/null
+++ b/drivers/crypto/zynqmp-sha.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cryptographic API.
+ *
+ * Support for Xilinx ZynqMP SHA3 HW Acceleration.
+ *
+ * Copyright (c) 2018 Xilinx Inc.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZYNQMP_SHA3_INIT   1
+#define ZYNQMP_SHA3_UPDATE 2
+#define ZYNQMP_SHA3_FINAL  4
+
+#define ZYNQMP_SHA_QUEUE_LENGTH1
+
+struct zynqmp_sha_dev;
+
+/*
+ * .statesize = sizeof(struct zynqmp_sha_reqctx) must be <= PAGE_SIZE / 8 as
+ *  tested by the ahash_prepare_alg() function.
+ */
+struct zynqmp_sha_reqctx {
+   struct zynqmp_sha_dev   *dd;
+   unsigned long   flags;
+};
+
+struct zynqmp_sha_ctx {
+   struct zynqmp_sha_dev   *dd;
+   unsigned long   flags;
+};
+
+struct zynqmp_sha_dev {
+   struct list_headlist;
+   struct device   *dev;
+   /* the lock protects queue and dev list*/
+   spinlock_t  lock;
+   int err;
+
+   unsigned long   flags;
+   struct crypto_queue queue;
+   struct ahash_request*req;
+};
+
+struct zynqmp_sha_drv {
+   struct list_headdev_list;
+   /* the lock protects dev list*/
+   spinlock_t  lock;
+};
+
+static struct zynqmp_sha_drv zynqmp_sha = {
+   .dev_list = LIST_HEAD_INIT(zynqmp_sha.dev_list),
+   .lock = __SPIN_LOCK_UNLOCKED(zynqmp_sha.lock),
+};
+
+static int zynqmp_sha_init(struct ahash_request *req)
+{
+   const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+   struct zynqmp_sha_reqctx *ctx = ahash_request_ctx(req);
+   struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+   struct zynqmp_sha_ctx *tctx = crypto_ahash_ctx(tfm);
+   struct zynqmp_sha_dev *dd = NULL;
+   struct zynqmp_sha_dev *tmp;
+   int ret;
+
+   if (!eemi_ops || !eemi_ops->sha_hash)
+   return -ENOTSUPP;
+
+   spin_lock_bh(_sha.lock);
+   if (!tctx->dd) {
+   list_for_each_entry(tmp, _sha.dev_list, list) {
+   dd = tmp;
+   break;
+   }
+   tctx->dd = dd;
+   } else {
+   dd = tctx->dd;
+   }
+   spin_unlock_bh(_sha.lock);
+
+   ctx->dd = dd;
+   dev_dbg(dd->dev, "init: digest size: %d\n",
+   crypto_ahash_digestsize(tfm));
+
+   ret = eemi_ops->sha_hash(0, 0, ZYNQMP_SHA3_INIT);
+
+   return ret;
+}
+
+static int zynqmp_sha_update(struct ahash_request *req)
+{
+   const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+   struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
+   struct zynqmp_sha_dev *dd = tctx->dd;
+   size_t dma_size = req->nbytes;
+   dma_addr_t dma_addr;
+   char *kbuf;
+   int ret;
+
+   if (!req->nbytes)
+   return 0;
+
+   if (!eemi_ops || !eemi_ops->sha_hash)
+   return -ENOTS

[RFC PATCH V2 1/4] dt-bindings: crypto: Add bindings for ZynqMP SHA3 driver

2019-01-09 Thread Kalyani Akula
Add documentation to describe Xilinx ZynqMP SHA3 driver
bindings.

Signed-off-by: Kalyani Akula 
---
 .../devicetree/bindings/crypto/zynqmp-sha.txt  |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt

diff --git a/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt 
b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
new file mode 100644
index 000..c7be6e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
@@ -0,0 +1,12 @@
+Xilinx ZynqMP SHA3(keccak-384) hw acceleration support.
+
+The ZynqMp PS-SHA hw accelerator is used to calculate the
+SHA3(keccak-384) hash value on the given user data.
+
+Required properties:
+- compatible:  should contain "xlnx,zynqmp-keccak-384"
+
+Example:
+   xlnx_keccak_384: sha384 {
+   compatible = "xlnx,zynqmp-keccak-384";
+   };
-- 
1.7.1



[RFC PATCH V2 0/4] Add Xilinx's ZynqMP SHA3 driver support

2019-01-09 Thread Kalyani Akula
This patch set adds support for
- dt-binding docs for Xilinx ZynqMP SHA3 driver
- Adds communication layer support for sha_hash in zynqmp.c
- Adds Xilinx ZynqMP driver for SHA3 Algorithm
- Adds device tree node for ZynqMP SHA3 driver

V2 Changes :
- Added new patch (2/4) for sha_hash zynqmp API support
- Incorporated code review comments from v1 patch series. Discussed below:
https://lore.kernel.org/patchwork/patch/1029433/

Kalyani Akula (4):
  dt-bindings: crypto: Add bindings for ZynqMP SHA3 driver
  firmware: xilinx: Add ZynqMP sha_hash API for SHA3 functionality
  crypto: Add Xilinx SHA3 driver
  ARM64: zynqmp: Add Xilinix SHA-384 node.

 .../devicetree/bindings/crypto/zynqmp-sha.txt  |   12 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi |4 +
 drivers/crypto/Kconfig |   10 +
 drivers/crypto/Makefile|1 +
 drivers/crypto/zynqmp-sha.c|  305 
 drivers/firmware/xilinx/zynqmp.c   |   27 ++
 include/linux/firmware/xlnx-zynqmp.h   |2 +
 7 files changed, 361 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
 create mode 100644 drivers/crypto/zynqmp-sha.c



RE: [RFC PATCH 2/3] crypto: Add Xilinx SHA3 driver

2019-01-09 Thread Kalyani Akula
Hi Corentin,

Thanks for the review,
Please find my response inline.

> -Original Message-
> From: Corentin Labbe [mailto:clabbe.montj...@gmail.com]
> Sent: Monday, January 7, 2019 3:43 PM
> To: Kalyani Akula 
> Cc: herb...@gondor.apana.org.au; da...@davemloft.net; linux-
> cry...@vger.kernel.org; linux-kernel@vger.kernel.org; Kalyani Akula
> ; Sarat Chand Savitala 
> Subject: Re: [RFC PATCH 2/3] crypto: Add Xilinx SHA3 driver
> 
> On Mon, Jan 07, 2019 at 02:32:55PM +0530, Kalyani Akula wrote:
> > This patch adds SHA3 driver suuport for the Xilinx ZynqMP SoC.
> >
> > Signed-off-by: Kalyani Akula 
> 
> Hello
> 
> I have some comment below
> 
> > +static int zynqmp_sha_init(struct ahash_request *req) {
> > +   const struct zynqmp_eemi_ops *eemi_ops =
> zynqmp_pm_get_eemi_ops();
> > +   struct zynqmp_sha_reqctx *ctx = ahash_request_ctx(req);
> > +   struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
> > +   struct zynqmp_sha_ctx *tctx = crypto_ahash_ctx(tfm);
> > +   struct zynqmp_sha_dev *dd = NULL;
> > +   struct zynqmp_sha_dev *tmp;
> > +   int ret;
> > +
> > +   if (!eemi_ops || !eemi_ops->sha_hash)
> > +   return -ENOTSUPP;
> > +
> 
> Where can I find sha_hash() ?
> It seems that your serie miss some patchs.

This API should go into drivers/firmware/xilinx/zynqmp.c file. Will send fix 
and send next version.
I was in assumption that the above driver is not in main-line as it was sent as 
drivers/firmware/Xilinx/zynqmp/firmware.c initially and renamed later to 
zynqmp.c.

> 
> > +   spin_lock_bh(_sha.lock);
> > +   if (!tctx->dd) {
> > +   list_for_each_entry(tmp, _sha.dev_list, list) {
> > +   dd = tmp;
> > +   break;
> > +   }
> > +   tctx->dd = dd;
> > +   } else {
> > +   dd = tctx->dd;
> > +   }
> > +   spin_unlock_bh(_sha.lock);
> > +
> > +   ctx->dd = dd;
> > +   dev_dbg(dd->dev, "init: digest size: %d\n",
> > +   crypto_ahash_digestsize(tfm));
> > +
> > +   ret = eemi_ops->sha_hash(0, 0, ZYNQMP_SHA3_INIT);
> > +
> > +   return ret;
> > +}
> > +
> > +static int zynqmp_sha_update(struct ahash_request *req) {
> > +   const struct zynqmp_eemi_ops *eemi_ops =
> zynqmp_pm_get_eemi_ops();
> > +   struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
> > +   struct zynqmp_sha_dev *dd = tctx->dd;
> > +   size_t dma_size = req->nbytes;
> > +   dma_addr_t dma_addr;
> > +   char *kbuf;
> > +   int ret;
> > +
> > +   if (!req->nbytes)
> > +   return 0;
> > +
> > +   if (!eemi_ops || !eemi_ops->sha_hash)
> > +   return -ENOTSUPP;
> > +
> > +   kbuf = dma_alloc_coherent(dd->dev, dma_size, _addr,
> GFP_KERNEL);
> > +   if (!kbuf)
> > +   return -ENOMEM;
> > +
> > +   scatterwalk_map_and_copy(kbuf, req->src, 0, req->nbytes, 0);
> > +__flush_cache_user_range((unsigned long)kbuf,
> > + (unsigned long)kbuf + dma_size);
> > +   ret = eemi_ops->sha_hash(dma_addr, req->nbytes,
> ZYNQMP_SHA3_UPDATE);
> 
> Even with the sha_hash prototype missing, I think your driver have a
> problem:
> You support having more than one device, but sha_hash lacks any reference
> on the device doing the request.

Actually this is taken care using PM API id's by which the request is 
identified in the firmware (platform management unit (PMU-FW)) and sent to 
specific HW engine. 
The ID specific to SHA3 engine will be added 
include/linux/firmware/xlnx-zynqmp.h in the next version. 

> 
> > +static int zynqmp_sha_final(struct ahash_request *req) {
> > +   const struct zynqmp_eemi_ops *eemi_ops =
> zynqmp_pm_get_eemi_ops();
> > +   struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
> > +   struct zynqmp_sha_dev *dd = tctx->dd;
> > +   size_t dma_size = SHA384_DIGEST_SIZE;
> > +   dma_addr_t dma_addr;
> > +   char *kbuf;
> > +   int ret;
> > +
> > +   if (!eemi_ops || !eemi_ops->sha_hash)
> > +   return -ENOTSUPP;
> > +
> > +   kbuf = dma_alloc_coherent(dd->dev, dma_size, _addr,
> GFP_KERNEL);
> > +   if (!kbuf)
> > +   return -ENOMEM;
> > +
> > +   ret = eemi_ops->sha_hash(dma_addr, dma_size,
> ZYNQMP_SHA3_FINAL);
> > +   memcpy(req->result, kbuf, 48);
> 
> It is better to use SHA384_DIGEST_SIZE instead of 48

Will fix in the next version.

> 
> [...]
> > +static int zynqmp_sha_probe(struct platform_device *pde

[RFC PATCH 1/3] dt-bindings: crypto: Add bindings for ZynqMP SHA3 driver

2019-01-07 Thread Kalyani Akula
Add documentation to describe Xilinx ZynqMP SHA3 driver
bindings.

Signed-off-by: Kalyani Akula 
---
 .../devicetree/bindings/crypto/zynqmp-sha.txt  |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)
 create mode 100755 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt

diff --git a/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt 
b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
new file mode 100755
index 000..c7be6e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
@@ -0,0 +1,12 @@
+Xilinx ZynqMP SHA3(keccak-384) hw acceleration support.
+
+The ZynqMp PS-SHA hw accelerator is used to calculate the
+SHA3(keccak-384) hash value on the given user data.
+
+Required properties:
+- compatible:  should contain "xlnx,zynqmp-keccak-384"
+
+Example:
+   xlnx_keccak_384: sha384 {
+   compatible = "xlnx,zynqmp-keccak-384";
+   };
-- 
1.7.1



[RFC PATCH 3/3] ARM64: zynqmp: Add Xilinix SHA-384 node.

2019-01-07 Thread Kalyani Akula
This patch adds a SHA3 DT node for Xilinx ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi 
b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index fa4fd77..a3be330 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -124,6 +124,10 @@
 <1 10 0xf08>;
};
 
+   xlnx_keccak_384: sha384 {
+   compatible = "xlnx,zynqmp-keccak-384";
+   };
+
amba_apu: amba-apu@0 {
compatible = "simple-bus";
#address-cells = <2>;
-- 
1.7.1



[RFC PATCH 0/3] Add Xilinx's ZynqMP SHA3 driver support

2019-01-07 Thread Kalyani Akula
This patch set adds support for 
- dt-binding docs for Xilinx ZynqMP SHA3 driver
- Adds Xilinx ZynqMP driver for SHA3 Algorithm
- Adds device tree node for ZynqMP SHA3 driver

Kalyani Akula (3):
  dt-bindings: crypto: Add bindings for ZynqMP SHA3 driver
  crypto: Add Xilinx SHA3 driver
  ARM64: zynqmp: Add Xilinix SHA-384 node.

 .../devicetree/bindings/crypto/zynqmp-sha.txt  |   12 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi |4 +
 drivers/crypto/Kconfig |   10 +
 drivers/crypto/Makefile|1 +
 drivers/crypto/zynqmp-sha.c|  303 
 5 files changed, 330 insertions(+), 0 deletions(-)
 create mode 100755 Documentation/devicetree/bindings/crypto/zynqmp-sha.txt
 create mode 100755 drivers/crypto/zynqmp-sha.c



[RFC PATCH 2/3] crypto: Add Xilinx SHA3 driver

2019-01-07 Thread Kalyani Akula
This patch adds SHA3 driver suuport for the Xilinx
ZynqMP SoC.

Signed-off-by: Kalyani Akula 
---
 drivers/crypto/Kconfig  |   10 ++
 drivers/crypto/Makefile |1 +
 drivers/crypto/zynqmp-sha.c |  303 +++
 3 files changed, 314 insertions(+), 0 deletions(-)
 create mode 100755 drivers/crypto/zynqmp-sha.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 5a90075..b723e23 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -667,6 +667,16 @@ config CRYPTO_DEV_ROCKCHIP
  This driver interfaces with the hardware crypto accelerator.
  Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.
 
+config CRYPTO_DEV_ZYNQMP_SHA3
+   tristate "Support for Xilinx ZynqMP SHA3 hw accelerator"
+   depends on ARCH_ZYNQMP || COMPILE_TEST
+   select CRYPTO_HASH
+   help
+ Xilinx ZynqMP has SHA3 engine used for secure hash calculation.
+ This driver interfaces with SHA3 hw engine.
+ Select this if you want to use the ZynqMP module
+ for SHA3 hash computation.
+
 config CRYPTO_DEV_MEDIATEK
tristate "MediaTek's EIP97 Cryptographic Engine driver"
depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 8e7e225..64c29fe 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
 obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
 obj-y += hisilicon/
+obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o
diff --git a/drivers/crypto/zynqmp-sha.c b/drivers/crypto/zynqmp-sha.c
new file mode 100755
index 000..016f826
--- /dev/null
+++ b/drivers/crypto/zynqmp-sha.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cryptographic API.
+ *
+ * Support for Xilinx ZynqMP SHA3 HW Acceleration.
+ *
+ * Copyright (c) 2018 Xilinx Inc.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZYNQMP_SHA3_INIT   1
+#define ZYNQMP_SHA3_UPDATE 2
+#define ZYNQMP_SHA3_FINAL  4
+
+#define ZYNQMP_SHA_QUEUE_LENGTH1
+
+struct zynqmp_sha_dev;
+
+/*
+ * .statesize = sizeof(struct zynqmp_sha_reqctx) must be <= PAGE_SIZE / 8 as
+ *  tested by the ahash_prepare_alg() function.
+ */
+struct zynqmp_sha_reqctx {
+   struct zynqmp_sha_dev   *dd;
+   unsigned long   flags;
+};
+
+struct zynqmp_sha_ctx {
+   struct zynqmp_sha_dev   *dd;
+   unsigned long   flags;
+};
+
+struct zynqmp_sha_dev {
+   struct list_headlist;
+   struct device   *dev;
+   /* the lock protects queue and dev list*/
+   spinlock_t  lock;
+   int err;
+
+   unsigned long   flags;
+   struct crypto_queue queue;
+   struct ahash_request*req;
+};
+
+struct zynqmp_sha_drv {
+   struct list_headdev_list;
+   /* the lock protects dev list*/
+   spinlock_t  lock;
+};
+
+static struct zynqmp_sha_drv zynqmp_sha = {
+   .dev_list = LIST_HEAD_INIT(zynqmp_sha.dev_list),
+   .lock = __SPIN_LOCK_UNLOCKED(zynqmp_sha.lock),
+};
+
+static int zynqmp_sha_init(struct ahash_request *req)
+{
+   const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+   struct zynqmp_sha_reqctx *ctx = ahash_request_ctx(req);
+   struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+   struct zynqmp_sha_ctx *tctx = crypto_ahash_ctx(tfm);
+   struct zynqmp_sha_dev *dd = NULL;
+   struct zynqmp_sha_dev *tmp;
+   int ret;
+
+   if (!eemi_ops || !eemi_ops->sha_hash)
+   return -ENOTSUPP;
+
+   spin_lock_bh(_sha.lock);
+   if (!tctx->dd) {
+   list_for_each_entry(tmp, _sha.dev_list, list) {
+   dd = tmp;
+   break;
+   }
+   tctx->dd = dd;
+   } else {
+   dd = tctx->dd;
+   }
+   spin_unlock_bh(_sha.lock);
+
+   ctx->dd = dd;
+   dev_dbg(dd->dev, "init: digest size: %d\n",
+   crypto_ahash_digestsize(tfm));
+
+   ret = eemi_ops->sha_hash(0, 0, ZYNQMP_SHA3_INIT);
+
+   return ret;
+}
+
+static int zynqmp_sha_update(struct ahash_request *req)
+{
+   const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+   struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
+   struct zynqmp_sha_dev *dd = tctx->dd;
+   size_t dma_size = req->nbytes;
+   dma_addr_t dma_addr;
+   char *kbuf;
+   int ret;
+
+   if (!req->nbytes)
+   return 0;
+
+   if (!eemi_ops || !eemi_ops->sha_hash)
+   return -ENOTS