RE: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-05-08 Thread Igal Liberman
Hi Robin

> -Original Message-
> From: linux-crypto-ow...@vger.kernel.org [mailto:linux-crypto-
> ow...@vger.kernel.org] On Behalf Of Robin Murphy
> Sent: Wednesday, May 03, 2017 20:15
> To: Antoine Tenart; Igal Liberman
> Cc: herb...@gondor.apana.org.au; da...@davemloft.net;
> ja...@lakedaemon.net; and...@lunn.ch; gregory.clement@free-
> electrons.com; sebastian.hesselba...@gmail.com; linux-
> cry...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> thomas.petazz...@free-electrons.com; boris.brezil...@free-electrons.com;
> Ofer Heifetz; Nadav Haklai
> Subject: Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197
> crypto engine driver
> 
> On 24/04/17 09:57, Antoine Tenart wrote:
> > Hi Igal,
> >
> > On Mon, Apr 24, 2017 at 08:50:32AM +, Igal Liberman wrote:
> >> [...]
> >>
> >>> + priv->clk = of_clk_get(dev->of_node, 0);
> >>> + if (!IS_ERR(priv->clk)) {
> >>> + ret = clk_prepare_enable(priv->clk);
> >>> + if (ret) {
> >>> + dev_err(dev, "unable to enable clk (%d)\n", ret);
> >>> + return ret;
> >>> + }
> >>> + } else {
> >>> + /* The clock isn't mandatory */
> >>> + if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
> >>> + return -EPROBE_DEFER;
> >>> + }
> >>> +
> >>> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
> >>
> >> The correct address width of the engine in Marvell SoCs is 40bit.
> 
> Is that what the IP block itself is internally limited to, or just how many 
> bits
> happen to be wired up externally in the particular Marvell integrations?
> 

The IP supports up to 64bit address width (depends on the revision).
The 40bit limitation is related to Marvell integration.

> > Oops. I'll update.
> 
> If the device itself can handle full 64-bit addresses, then the driver should
> reflect that regardless of the integration - describing integration 
> limitations is
> the job of the firmware, e.g. with DT "dma-ranges", assuming they actually
> matter (typically if the whole SoC interconnect and physical memory map is
> the same width then having an even wider DMA mask doesn't make any
> difference - 64 bits still just means "everything").
> 
> If it's the case that the IP is configurable and could be synthesised with
> various internal address widths, then that might warrant a DT property to
> identify the particular configuration if it's not readable from some ID
> register, although it may be reasonable in practice to simply assume the
> chosen configuration to be sane (i.e. not smaller than the rest of the system)
> and that the driver can set the maximal DMA mask as above.
> 
> Robin.
> 
> >
> > Thanks!
> > Antoine
> >



Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-05-03 Thread Robin Murphy
On 24/04/17 09:57, Antoine Tenart wrote:
> Hi Igal,
> 
> On Mon, Apr 24, 2017 at 08:50:32AM +, Igal Liberman wrote:
>> [...]
>>
>>> +   priv->clk = of_clk_get(dev->of_node, 0);
>>> +   if (!IS_ERR(priv->clk)) {
>>> +   ret = clk_prepare_enable(priv->clk);
>>> +   if (ret) {
>>> +   dev_err(dev, "unable to enable clk (%d)\n", ret);
>>> +   return ret;
>>> +   }
>>> +   } else {
>>> +   /* The clock isn't mandatory */
>>> +   if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
>>> +   return -EPROBE_DEFER;
>>> +   }
>>> +
>>> +   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
>>
>> The correct address width of the engine in Marvell SoCs is 40bit.

Is that what the IP block itself is internally limited to, or just how
many bits happen to be wired up externally in the particular Marvell
integrations?

> Oops. I'll update.

If the device itself can handle full 64-bit addresses, then the driver
should reflect that regardless of the integration - describing
integration limitations is the job of the firmware, e.g. with DT
"dma-ranges", assuming they actually matter (typically if the whole SoC
interconnect and physical memory map is the same width then having an
even wider DMA mask doesn't make any difference - 64 bits still just
means "everything").

If it's the case that the IP is configurable and could be synthesised
with various internal address widths, then that might warrant a DT
property to identify the particular configuration if it's not readable
from some ID register, although it may be reasonable in practice to
simply assume the chosen configuration to be sane (i.e. not smaller than
the rest of the system) and that the driver can set the maximal DMA mask
as above.

Robin.

> 
> Thanks!
> Antoine
> 



Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-05-03 Thread Antoine Tenart
Hi Robin,

On Wed, May 03, 2017 at 12:57:25PM +0100, Robin Murphy wrote:
> On 24/04/17 08:54, Antoine Tenart wrote:
> > +
> > +#include 
> 
>  everywhere, please.
> 
> Other than that, the DMA aspects all look much nicer now, thanks.

I'll update and resend a series when the next -rc1 is out.

Thanks!
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-05-03 Thread Robin Murphy
Hi Antoine,

On 24/04/17 08:54, Antoine Tenart wrote:
> Add support for Inside Secure SafeXcel EIP197 cryptographic engine,
> which can be found on Marvell Armada 7k and 8k boards. This driver
> currently implements: ecb(aes), cbc(aes), sha1, sha224, sha256 and
> hmac(sah1) algorithms.
> 
> Two firmwares are needed for this engine to work. Their are mostly used
> for more advanced operations than the ones supported (as of now), but we
> still need them to pass the data to the internal cryptographic engine.
> 
> Signed-off-by: Antoine Tenart 

[...]

> diff --git a/drivers/crypto/inside-secure/safexcel.c 
> b/drivers/crypto/inside-secure/safexcel.c
> new file mode 100644
> index ..9cb3d0832835
> --- /dev/null
> +++ b/drivers/crypto/inside-secure/safexcel.c
> @@ -0,0 +1,925 @@
> +/*
> + * Copyright (C) 2017 Marvell
> + *
> + * Antoine Tenart 
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 

 everywhere, please.

Other than that, the DMA aspects all look much nicer now, thanks.

Robin.


Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-04-25 Thread Antoine Tenart
Hi Stephan,

On Mon, Apr 24, 2017 at 02:59:05PM +0200, Stephan Müller wrote:
> Am Montag, 24. April 2017, 09:54:06 CEST schrieb Antoine Tenart:
> 
> > +struct safexcel_cipher_ctx {
> > +   struct safexcel_context base;
> > +   struct safexcel_crypto_priv *priv;
> > +
> > +   enum safexcel_cipher_direction direction;
> > +   u32 mode;
> > +
> > +   __le32 key[8];
> 
> Can you please help me find the location where this memory is zeroized when 
> released?

It's not, I'll fix this.

> > +static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx,
> > + struct crypto_async_request *async,
> > + struct safexcel_command_desc *cdesc,
> > + u32 length)
> > +{
> > +   struct ablkcipher_request *req = ablkcipher_request_cast(async);
> > +   struct safexcel_token *token;
> > +   unsigned offset = 0;
> > +
> > +   if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) {
> > +   offset = AES_BLOCK_SIZE / sizeof(u32);
> > +   memcpy(cdesc->control_data.token, req->info, AES_BLOCK_SIZE);
> > +
> > +   cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
> > +   }
> > +
> > +   token = (struct safexcel_token *)(cdesc->control_data.token + offset);
> > +
> > +   token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
> > +   token[0].packet_length = length;
> > +   token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET;
> > +   token[0].instructions = EIP197_TOKEN_INS_LAST |
> > +   EIP197_TOKEN_INS_TYPE_CRYTO |
> > +   EIP197_TOKEN_INS_TYPE_OUTPUT;
> > +}
> > +
> > +static int safexcel_aes_setkey(struct crypto_ablkcipher *ctfm, const u8
> > *key, +unsigned int len)
> > +{
> 
> You still use ablkcipher. I thought that it is on its way out in favor of the 
> skcipher API. Why do you stick to ablkcipher?
> 
> Note, a change could be as simple as s/ablkcipher/skcipher/g

Because I wasn't aware of this :) I'll update.

> > +   struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ctfm);
> > +   struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
> > +   struct crypto_aes_ctx aes;
> > +   int ret, i;
> > +
> > +   ret = crypto_aes_expand_key(, key, len);
> > +   if (ret) {
> > +   crypto_ablkcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
> > +   return ret;
> > +   }
> > +
> > +   for (i = 0; i < len / sizeof(u32); i++) {
> > +   if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
> > +   ctx->base.needs_inv = true;
> > +   break;
> > +   }
> > +   }
> > +
> > +   for (i = 0; i < len / sizeof(u32); i++)
> > +   ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
> > +
> > +   ctx->key_len = len;
> 
> memzero_explicit(aes)?

OK, I'll update.

> > +static int safexcel_aes_send(struct crypto_async_request *async,
> > +int ring, struct safexcel_request *request,
> > +int *commands, int *results)
> > +{
> > +   struct ablkcipher_request *req = ablkcipher_request_cast(async);
> > +   struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
> > +   struct safexcel_crypto_priv *priv = ctx->priv;
> > +   struct safexcel_command_desc *cdesc;
> > +   struct safexcel_result_desc *rdesc;
> > +   struct scatterlist *sg;
> > +   int nr_src, nr_dst, n_cdesc = 0, n_rdesc = 0, queued = req->nbytes;
> > +   int i, ret = 0;
> > +
> > +   request->req = >base;
> > +
> > +   if (req->src == req->dst) {
> > +   nr_src = dma_map_sg(priv->dev, req->src,
> > +   sg_nents_for_len(req->src, req->nbytes),
> > +   DMA_BIDIRECTIONAL);
> > +   nr_dst = nr_src;
> > +   if (!nr_src)
> > +   return -EINVAL;
> > +   } else {
> > +   nr_src = dma_map_sg(priv->dev, req->src,
> > +   sg_nents_for_len(req->src, req->nbytes),
> > +   DMA_TO_DEVICE);
> > +   if (!nr_src)
> > +   return -EINVAL;
> > +
> > +   nr_dst = dma_map_sg(priv->dev, req->dst,
> > +   sg_nents_for_len(req->dst, req->nbytes),
> > +   DMA_FROM_DEVICE);
> > +   if (!nr_dst) {
> > +   dma_unmap_sg(priv->dev, req->src,
> > +sg_nents_for_len(req->src, req->nbytes),
> > +DMA_TO_DEVICE);
> > +   return -EINVAL;
> > +   }
> > +   }
> > +
> > +   memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);
> 
> Is ctxr->data properly zeroized?

No, I'll update.

Thanks for the review!
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-04-24 Thread Stephan Müller
Am Montag, 24. April 2017, 09:54:06 CEST schrieb Antoine Tenart:

Hi Antoine,

> +struct safexcel_cipher_ctx {
> + struct safexcel_context base;
> + struct safexcel_crypto_priv *priv;
> +
> + enum safexcel_cipher_direction direction;
> + u32 mode;
> +
> + __le32 key[8];

Can you please help me find the location where this memory is zeroized when 
released?


> + unsigned int key_len;
> +};
> +
> +static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx,
> +   struct crypto_async_request *async,
> +   struct safexcel_command_desc *cdesc,
> +   u32 length)
> +{
> + struct ablkcipher_request *req = ablkcipher_request_cast(async);
> + struct safexcel_token *token;
> + unsigned offset = 0;
> +
> + if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) {
> + offset = AES_BLOCK_SIZE / sizeof(u32);
> + memcpy(cdesc->control_data.token, req->info, AES_BLOCK_SIZE);
> +
> + cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
> + }
> +
> + token = (struct safexcel_token *)(cdesc->control_data.token + offset);
> +
> + token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
> + token[0].packet_length = length;
> + token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET;
> + token[0].instructions = EIP197_TOKEN_INS_LAST |
> + EIP197_TOKEN_INS_TYPE_CRYTO |
> + EIP197_TOKEN_INS_TYPE_OUTPUT;
> +}
> +
> +static int safexcel_aes_setkey(struct crypto_ablkcipher *ctfm, const u8
> *key, +  unsigned int len)
> +{

You still use ablkcipher. I thought that it is on its way out in favor of the 
skcipher API. Why do you stick to ablkcipher?

Note, a change could be as simple as s/ablkcipher/skcipher/g

> + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ctfm);
> + struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
> + struct crypto_aes_ctx aes;
> + int ret, i;
> +
> + ret = crypto_aes_expand_key(, key, len);
> + if (ret) {
> + crypto_ablkcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
> + return ret;
> + }
> +
> + for (i = 0; i < len / sizeof(u32); i++) {
> + if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
> + ctx->base.needs_inv = true;
> + break;
> + }
> + }
> +
> + for (i = 0; i < len / sizeof(u32); i++)
> + ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
> +
> + ctx->key_len = len;

memzero_explicit(aes)?

> +
> + return 0;
> +}
> +
> +static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
> + struct safexcel_command_desc *cdesc)
> +{
> + struct safexcel_crypto_priv *priv = ctx->priv;
> + int ctrl_size;
> +
> + if (ctx->direction == SAFEXCEL_ENCRYPT)
> + cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_CRYPTO_OUT;
> + else
> + cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_CRYPTO_IN;
> +
> + cdesc->control_data.control0 |= CONTEXT_CONTROL_KEY_EN;
> + cdesc->control_data.control1 |= ctx->mode;
> +
> + switch (ctx->key_len) {
> + case AES_KEYSIZE_128:
> + cdesc->control_data.control0 |= 
> CONTEXT_CONTROL_CRYPTO_ALG_AES128;
> + ctrl_size = 4;
> + break;
> + case AES_KEYSIZE_192:
> + cdesc->control_data.control0 |= 
> CONTEXT_CONTROL_CRYPTO_ALG_AES192;
> + ctrl_size = 6;
> + break;
> + case AES_KEYSIZE_256:
> + cdesc->control_data.control0 |= 
> CONTEXT_CONTROL_CRYPTO_ALG_AES256;
> + ctrl_size = 8;
> + break;
> + default:
> + dev_err(priv->dev, "aes keysize not supported: %u\n",
> + ctx->key_len);
> + return -EINVAL;
> + }
> + cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(ctrl_size);
> +
> + return 0;
> +}
> +
> +static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int
> ring, + struct crypto_async_request *async,
> +   bool *should_complete, int *ret)
> +{
> + struct ablkcipher_request *req = ablkcipher_request_cast(async);
> + struct safexcel_result_desc *rdesc;
> + int ndesc = 0;
> +
> + *ret = 0;
> +
> + spin_lock_bh(>ring[ring].egress_lock);
> + do {
> + rdesc = safexcel_ring_next_rptr(priv, >ring[ring].rdr);
> + if (IS_ERR(rdesc)) {
> + dev_err(priv->dev,
> + "cipher: result: could not retrieve the result 
> descriptor\n");
> + *ret = PTR_ERR(rdesc);
> + break;
> + }
> +
> + if (rdesc->result_data.error_code) {
> + dev_err(priv->dev,
> + "cipher: 

Re: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-04-24 Thread Antoine Tenart
Hi Igal,

On Mon, Apr 24, 2017 at 08:50:32AM +, Igal Liberman wrote:
> [...]
> 
> > +   priv->clk = of_clk_get(dev->of_node, 0);
> > +   if (!IS_ERR(priv->clk)) {
> > +   ret = clk_prepare_enable(priv->clk);
> > +   if (ret) {
> > +   dev_err(dev, "unable to enable clk (%d)\n", ret);
> > +   return ret;
> > +   }
> > +   } else {
> > +   /* The clock isn't mandatory */
> > +   if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
> > +   return -EPROBE_DEFER;
> > +   }
> > +
> > +   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
> 
> The correct address width of the engine in Marvell SoCs is 40bit.

Oops. I'll update.

Thanks!
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


RE: [PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-04-24 Thread Igal Liberman
[...]

> + priv->clk = of_clk_get(dev->of_node, 0);
> + if (!IS_ERR(priv->clk)) {
> + ret = clk_prepare_enable(priv->clk);
> + if (ret) {
> + dev_err(dev, "unable to enable clk (%d)\n", ret);
> + return ret;
> + }
> + } else {
> + /* The clock isn't mandatory */
> + if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + }
> +
> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));

The correct address width of the engine in Marvell SoCs is 40bit.

> + if (ret)
> + goto err_clk;
> +
> + priv->context_pool = dmam_pool_create("safexcel-context", dev,
> +   sizeof(struct
> safexcel_context_record),
> +   1, 0);
> + if (!priv->context_pool) {
> + ret = -ENOMEM;
> + goto err_clk;
> + }
> +

Thanks,
Igal


[PATCH v3 2/3] crypto: inside-secure: add SafeXcel EIP197 crypto engine driver

2017-04-24 Thread Antoine Tenart
Add support for Inside Secure SafeXcel EIP197 cryptographic engine,
which can be found on Marvell Armada 7k and 8k boards. This driver
currently implements: ecb(aes), cbc(aes), sha1, sha224, sha256 and
hmac(sah1) algorithms.

Two firmwares are needed for this engine to work. Their are mostly used
for more advanced operations than the ones supported (as of now), but we
still need them to pass the data to the internal cryptographic engine.

Signed-off-by: Antoine Tenart 
---
 drivers/crypto/Kconfig |   17 +
 drivers/crypto/Makefile|1 +
 drivers/crypto/inside-secure/Makefile  |2 +
 drivers/crypto/inside-secure/safexcel.c|  925 +
 drivers/crypto/inside-secure/safexcel.h|  579 +
 drivers/crypto/inside-secure/safexcel_cipher.c |  555 +
 drivers/crypto/inside-secure/safexcel_hash.c   | 1045 
 drivers/crypto/inside-secure/safexcel_ring.c   |  157 
 8 files changed, 3281 insertions(+)
 create mode 100644 drivers/crypto/inside-secure/Makefile
 create mode 100644 drivers/crypto/inside-secure/safexcel.c
 create mode 100644 drivers/crypto/inside-secure/safexcel.h
 create mode 100644 drivers/crypto/inside-secure/safexcel_cipher.c
 create mode 100644 drivers/crypto/inside-secure/safexcel_hash.c
 create mode 100644 drivers/crypto/inside-secure/safexcel_ring.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 473d31288ad8..d12a40450858 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -619,4 +619,21 @@ config CRYPTO_DEV_BCM_SPU
  Secure Processing Unit (SPU). The SPU driver registers ablkcipher,
  ahash, and aead algorithms with the kernel cryptographic API.
 
+config CRYPTO_DEV_SAFEXCEL
+   tristate "Inside Secure's SafeXcel cryptographic engine driver"
+   depends on HAS_DMA && OF
+   depends on (ARM64 && ARCH_MVEBU) || (COMPILE_TEST && 64BIT)
+   select CRYPTO_AES
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_HASH
+   select CRYPTO_HMAC
+   select CRYPTO_SHA1
+   select CRYPTO_SHA256
+   select CRYPTO_SHA512
+   help
+ This driver interfaces with the SafeXcel EIP-197 cryptographic engine
+ designed by Inside Secure. Select this if you want to use CBC/ECB
+ chain mode, AES cipher mode and SHA1/SHA224/SHA256/SHA512 hash
+ algorithms.
+
 endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 739609471169..7ed3e7940f76 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -36,3 +36,4 @@ obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
 obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio/
 obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/
 obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
+obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
diff --git a/drivers/crypto/inside-secure/Makefile 
b/drivers/crypto/inside-secure/Makefile
new file mode 100644
index ..302f07dde98c
--- /dev/null
+++ b/drivers/crypto/inside-secure/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += crypto_safexcel.o
+crypto_safexcel-objs := safexcel.o safexcel_ring.o safexcel_cipher.o 
safexcel_hash.o
diff --git a/drivers/crypto/inside-secure/safexcel.c 
b/drivers/crypto/inside-secure/safexcel.c
new file mode 100644
index ..9cb3d0832835
--- /dev/null
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -0,0 +1,925 @@
+/*
+ * Copyright (C) 2017 Marvell
+ *
+ * Antoine Tenart 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "safexcel.h"
+
+static u32 max_rings = EIP197_MAX_RINGS;
+module_param(max_rings, uint, 0644);
+MODULE_PARM_DESC(max_rings, "Maximum number of rings to use.");
+
+static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
+{
+   u32 val, htable_offset;
+   int i;
+
+   /* Enable the record cache memory access */
+   val = readl(priv->base + EIP197_CS_RAM_CTRL);
+   val &= ~EIP197_TRC_ENABLE_MASK;
+   val |= EIP197_TRC_ENABLE_0;
+   writel(val, priv->base + EIP197_CS_RAM_CTRL);
+
+   /* Clear all ECC errors */
+   writel(0, priv->base + EIP197_TRC_ECCCTRL);
+
+   /*
+* Make sure the cache memory is accessible by taking record cache into
+* reset.
+*/
+   val = readl(priv->base + EIP197_TRC_PARAMS);
+   val |= EIP197_TRC_PARAMS_SW_RESET;
+   val &= ~EIP197_TRC_PARAMS_DATA_ACCESS;
+   writel(val, priv->base + EIP197_TRC_PARAMS);
+
+   /* Clear all records */
+   for (i = 0; i < EIP197_CS_RC_MAX; i++) {
+   u32 val, offset = EIP197_CLASSIFICATION_RAMS + i *