[PATCH v3] crypto: omap-aes: Add support for GCM mode

2015-09-15 Thread Lokesh Vutla
OMAP AES hw supports AES-GCM mode.
Adding support for GCM and RFC4106 GCM mode in omap-aes driver.

Signed-off-by: Lokesh Vutla <lokeshvu...@ti.com>
---
Tested on BeagleBone-Black: http://pastebin.ubuntu.com/12417512/
Changes since v1:
- Addressed comments by Herbert.
  Previously posted here: 
https://www.mail-archive.com/linux-omap@vger.kernel.org/msg117573.html
 drivers/crypto/Kconfig|   1 +
 drivers/crypto/Makefile   |   3 +-
 drivers/crypto/omap-aes-gcm.c | 434 ++
 drivers/crypto/omap-aes.c | 335 
 drivers/crypto/omap-aes.h | 219 +
 5 files changed, 818 insertions(+), 174 deletions(-)
 create mode 100644 drivers/crypto/omap-aes-gcm.c
 create mode 100644 drivers/crypto/omap-aes.h

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index d234719..bc78c91 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -293,6 +293,7 @@ config CRYPTO_DEV_OMAP_AES
depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP2PLUS
select CRYPTO_AES
select CRYPTO_BLKCIPHER
+   select CRYPTO_AEAD
help
  OMAP processors have AES module accelerator. Select this if you
  want to use the OMAP module for AES algorithms.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index c3ced6f..d7a3181 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
 obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
 n2_crypto-y := n2_core.o n2_asm.o
 obj-$(CONFIG_CRYPTO_DEV_NX) += nx/
-obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes-driver.o
+omap-aes-driver-objs := omap-aes.o omap-aes-gcm.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
 obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
new file mode 100644
index 000..8fbab23
--- /dev/null
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -0,0 +1,434 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for OMAP AES GCM HW acceleration.
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "omap-aes.h"
+
+static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
+struct aead_request *req);
+
+static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, int ret)
+{
+   struct aead_request *req = dd->aead_req;
+
+   dd->flags &= ~FLAGS_BUSY;
+   dd->in_sg = NULL;
+   dd->out_sg = NULL;
+
+   req->base.complete(>base, ret);
+}
+
+static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
+{
+   void *buf;
+   u8 *tag;
+   int pages, alen, clen, i, ret = 0, nsg;
+   struct omap_aes_reqctx *rctx;
+
+   alen = ALIGN(dd->assoc_len, AES_BLOCK_SIZE);
+   clen = ALIGN(dd->total, AES_BLOCK_SIZE);
+   rctx = aead_request_ctx(dd->aead_req);
+
+   nsg = !!(dd->assoc_len && dd->total);
+
+   dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len,
+  DMA_FROM_DEVICE);
+   dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE);
+   dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, DMA_FROM_DEVICE);
+   omap_aes_crypt_dma_stop(dd);
+
+   if (dd->sgs_copied & AES_OUT_DATA_COPIED) {
+   buf = sg_virt(>out_sgl);
+   scatterwalk_map_and_copy(buf, dd->orig_out,
+dd->aead_req->assoclen, dd->total, 1);
+
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
+   if (dd->flags & FLAGS_ENCRYPT)
+   scatterwalk_map_and_copy(rctx->auth_tag,
+dd->aead_req->dst,
+dd->total + dd->aead_req->assoclen,
+dd->authsize, 1);
+
+   if (dd->sgs_copied & AES_ASSOC_DATA_COPIED) {
+   buf = sg_virt(>in_sgl[0]);
+   pages = get_order(alen);
+   free_pages((unsigned long)buf, pages);
+   }
+   if (dd->sgs_copied & AES_IN_DATA_COPIED) {
+   buf = sg_virt(>in_sgl[nsg]);
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
+   if (!(dd->flags & FLAGS_ENCRYPT)) {
+   tag = (u8 *)rctx->auth_tag;
+   

Re: [PATCH v2 6/7] crypto: omap-aes: Add support for GCM mode

2015-07-10 Thread Lokesh Vutla
Hi Herbert,
On Wednesday 08 July 2015 09:48 AM, Herbert Xu wrote:
 On Tue, Jul 07, 2015 at 09:01:48PM +0530, Lokesh Vutla wrote:

 +static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
 + struct aead_request *req)

[..snip..]

 +static int do_encrypt_iv(struct aead_request *req, u32 *tag)
 +{
 +struct scatterlist iv_sg;
 +struct ablkcipher_request *ablk_req;
 +struct crypto_ablkcipher *tfm;
 +struct tcrypt_result result;
 +struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
 +int ret = 0;
 +
 +tfm = crypto_alloc_ablkcipher(ctr(aes), 0, 0);
 
 Ugh, you cannot allocate crypto transforms in the data path.  You
 should allocate it in init instead.  Also using ctr(aes) is overkill.
 Just use aes and do the xor by hand.
 
 +static int omap_aes_gcm_crypt(struct aead_request *req, unsigned long mode)
 +{
 +struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
 +struct omap_aes_reqctx *rctx = aead_request_ctx(req);
 +struct crypto_aead *aead = crypto_aead_reqtfm(req);
 +unsigned int authlen = crypto_aead_authsize(aead);
 +struct omap_aes_dev *dd;
 +__be32 counter = cpu_to_be32(1);
 +int err;
 +
 +memset(ctx-auth_tag, 0, sizeof(ctx-auth_tag));
 
 The ctx is shared memory and you must not write to it as multiple
 requests can be called on the same tfm.  Use rctx instead.

May be a dumb question. 
If you don't mind can you elaborate more on the usage of rctx and ctx
in the driver?

Thanks and regards,
Lokesh
 
 +memcpy(req-iv + 12, counter, 4);
 
 The IV is only 12 bytes long so you're corrupting memory here.
 You should use rctx here too.
 
 +if (req-assoclen + req-cryptlen == 0) {
 +scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
 + 1);
 +return 0;
 +}
 
 How can this be right? Did you enable the selftest?
 
 Cheers,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/7] crypto: omap-aes: Add support for GCM mode

2015-07-08 Thread Lokesh Vutla
On Wednesday 08 July 2015 01:23 PM, Herbert Xu wrote:
 On Wed, Jul 08, 2015 at 03:48:05PM +0800, Herbert Xu wrote:
 On Wed, Jul 08, 2015 at 12:29:47PM +0530, Lokesh Vutla wrote:

 + if (req-assoclen + req-cryptlen == 0) {
 + scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
 +  1);
 + return 0;
 + }

 How can this be right? Did you enable the selftest?
 Why not? Self tests are passed for this case.

 As per the equation given in GCM spec[1], we can see that
 if assoclen and cryptlen is 0, then output of GCM  is just E(K, Y0)
 where Y0 = IV||(0^31)1
 I have E(K, Y0) calculated in previous step. And copying it
 to destination if assoclen and cryptlen is 0.

 Correct me if I am wrong.

 It should be E(K, Y0) ^ GHASH(0).  So unless GHASH(0) == 0, your
 code doesn't work.
 
 OK, GHASH(0) is indeed zero so I guess your code does work after
 all.
Sorry. I did not see this message and replied on the other thread.

Thanks and regards,
Lokesh
 
 Cheers,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/7] crypto: omap-aes: Add support for GCM mode

2015-07-08 Thread Lokesh Vutla
On Wednesday 08 July 2015 01:18 PM, Herbert Xu wrote:
 On Wed, Jul 08, 2015 at 12:29:47PM +0530, Lokesh Vutla wrote:

 +  if (req-assoclen + req-cryptlen == 0) {
 +  scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
 +   1);
 +  return 0;
 +  }

 How can this be right? Did you enable the selftest?
 Why not? Self tests are passed for this case.

 As per the equation given in GCM spec[1], we can see that
 if assoclen and cryptlen is 0, then output of GCM  is just E(K, Y0)
 where Y0 = IV||(0^31)1
 I have E(K, Y0) calculated in previous step. And copying it
 to destination if assoclen and cryptlen is 0.

 Correct me if I am wrong.
 
 It should be E(K, Y0) ^ GHASH(0).  So unless GHASH(0) == 0, your
 code doesn't work.
Yes, thats right. I have considered that.
So, we need GHASH(H, {}, {}).
As per the spec, 
GHASH(H, A, C) = X(m + n + 1). 
m = n = 0 in our case.

X0 = 0
X1 = (X(m  + n) ^ (len(A) || len(C)) . H
X1 = 0 . H  (GF(128) Multiplication)
X1 = 0  

The same thing is given in the Test case 1 of the spec. GHASH(H, {}, {}) = 0

Thanks and regards,
Lokesh

 
 Cheers,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/7] crypto: omap-aes: Add support for GCM mode

2015-07-08 Thread Lokesh Vutla
On Wednesday 08 July 2015 09:48 AM, Herbert Xu wrote:
 On Tue, Jul 07, 2015 at 09:01:48PM +0530, Lokesh Vutla wrote:

 +static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
 + struct aead_request *req)
 +{
 +void *buf_in;
 +int pages, alen, clen, cryptlen, nsg;
 +struct crypto_aead *aead = crypto_aead_reqtfm(req);
 +unsigned int authlen = crypto_aead_authsize(aead);
 +u32 dec = !(dd-flags  FLAGS_ENCRYPT);
 +struct scatterlist *input, *assoc, tmp[2];
 +
 +alen = ALIGN(req-assoclen, AES_BLOCK_SIZE);
 +cryptlen = req-cryptlen - (dec * authlen);
 +clen = ALIGN(cryptlen, AES_BLOCK_SIZE);
 +
 +dd-sgs_copied = 0;
 +
 +nsg = !!(req-assoclen  req-cryptlen);
 +
 +assoc = req-src[0];
 +sg_init_table(dd-in_sgl, nsg + 1);
 +if (req-assoclen) {
 +if (omap_aes_check_aligned(assoc, req-assoclen)) {
 +dd-sgs_copied |= AES_ASSOC_DATA_COPIED;
 +pages = get_order(alen);
 +buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
 +if (!buf_in) {
 +pr_err(Couldn't allocate for unaligncases.\n);
 +return -1;
 +}
 +
 +scatterwalk_map_and_copy(buf_in, assoc, 0,
 + req-assoclen, 0);
 +memset(buf_in + req-assoclen, 0, alen - req-assoclen);
 +} else {
 +buf_in = sg_virt(req-assoc);
 
 req-assoc is now obsolete. Did you test this code?
Sorry, I missed it. Ill update.

 
 +static int do_encrypt_iv(struct aead_request *req, u32 *tag)
 +{
 +struct scatterlist iv_sg;
 +struct ablkcipher_request *ablk_req;
 +struct crypto_ablkcipher *tfm;
 +struct tcrypt_result result;
 +struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
 +int ret = 0;
 +
 +tfm = crypto_alloc_ablkcipher(ctr(aes), 0, 0);
 
 Ugh, you cannot allocate crypto transforms in the data path.  You
 should allocate it in init instead.  Also using ctr(aes) is overkill.
 Just use aes and do the xor by hand.
Ill take care of this.
 
 +static int omap_aes_gcm_crypt(struct aead_request *req, unsigned long mode)
 +{
 +struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
 +struct omap_aes_reqctx *rctx = aead_request_ctx(req);
 +struct crypto_aead *aead = crypto_aead_reqtfm(req);
 +unsigned int authlen = crypto_aead_authsize(aead);
 +struct omap_aes_dev *dd;
 +__be32 counter = cpu_to_be32(1);
 +int err;
 +
 +memset(ctx-auth_tag, 0, sizeof(ctx-auth_tag));
 
 The ctx is shared memory and you must not write to it as multiple
 requests can be called on the same tfm.  Use rctx instead.
 
 +memcpy(req-iv + 12, counter, 4);
 
 The IV is only 12 bytes long so you're corrupting memory here.
 You should use rctx here too.
Ok, Ill use rctx. Thanks for pointing.

 
 +if (req-assoclen + req-cryptlen == 0) {
 +scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
 + 1);
 +return 0;
 +}
 
 How can this be right? Did you enable the selftest?
Why not? Self tests are passed for this case.

As per the equation given in GCM spec[1], we can see that
if assoclen and cryptlen is 0, then output of GCM  is just E(K, Y0)
where Y0 = IV||(0^31)1
I have E(K, Y0) calculated in previous step. And copying it
to destination if assoclen and cryptlen is 0.

Correct me if I am wrong.

Thanks and regards,
Lokesh

[1] 
http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf

 
 Cheers,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 5/7] crypto: aead: Add aead_request_cast() api

2015-07-08 Thread Lokesh Vutla
On Wednesday 08 July 2015 09:26 AM, Herbert Xu wrote:
 On Tue, Jul 07, 2015 at 09:01:47PM +0530, Lokesh Vutla wrote:
 Add aead_request_cast() api to get pointer to aead_request
 from cryto_async_request.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  include/crypto/internal/aead.h | 6 ++
  1 file changed, 6 insertions(+)

 diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h
 index 4b25471..0423fa5 100644
 --- a/include/crypto/internal/aead.h
 +++ b/include/crypto/internal/aead.h
 @@ -157,6 +157,12 @@ static inline unsigned int 
 crypto_aead_maxauthsize(struct crypto_aead *aead)
  return crypto_aead_alg_maxauthsize(crypto_aead_alg(aead));
  }
  
 +static inline struct aead_request *aead_request_cast(
 +struct crypto_async_request *req)
 +{
 +return container_of(req, struct aead_request, base);
 +}
 
 Please drop this and use the aead_queue interface I just posted.
Okay will update in next version

Thanks and regards,
Lokesh
 
 Thanks,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/7] crypto: omap-aes: Add support for GCM mode

2015-07-07 Thread Lokesh Vutla
This series does some basic cleanup and adds support for
AES GCM mode for omap aes driver.

Changes since v1:
- Switched GCM to new AEAD interface

Lokesh Vutla (7):
  crypto: omap-aes: Fix CTR mode
  crypto: omap-aes: Increase priority of hw accelerator
  crypto: omap-aes: Fix configuring of AES mode
  crypto: omap-aes: Use BIT() macro
  crypto: aead: Add aead_request_cast() api
  crypto: omap-aes: Add support for GCM mode
  crypto: tcrypt: Fix AEAD speed tests

 crypto/tcrypt.c|  65 ---
 drivers/crypto/Kconfig |   1 +
 drivers/crypto/Makefile|   3 +-
 drivers/crypto/omap-aes-gcm.c  | 376 +
 drivers/crypto/omap-aes.c  | 346 -
 drivers/crypto/omap-aes.h  | 212 +++
 include/crypto/internal/aead.h |   6 +
 7 files changed, 788 insertions(+), 221 deletions(-)
 create mode 100644 drivers/crypto/omap-aes-gcm.c
 create mode 100644 drivers/crypto/omap-aes.h

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/7] crypto: omap-aes: Fix configuring of AES mode

2015-07-07 Thread Lokesh Vutla
AES_CTRL_REG is used to configure AES mode. Before configuring
any mode we need to make sure all other modes are reset or else
driver will misbehave. So mask all modes before configuring
any AES mode.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 54925d9..35521b8 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -63,6 +63,7 @@
 #define AES_REG_CTRL_DIRECTION (1  2)
 #define AES_REG_CTRL_INPUT_READY   (1  1)
 #define AES_REG_CTRL_OUTPUT_READY  (1  0)
+#define AES_REG_CTRL_MASK  GENMASK(24, 2)
 
 #define AES_REG_DATA_N(dd, x)  ((dd)-pdata-data_ofs + ((x) * 0x04))
 
@@ -254,7 +255,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
 {
unsigned int key32;
int i, err;
-   u32 val, mask = 0;
+   u32 val;
 
err = omap_aes_hw_init(dd);
if (err)
@@ -274,17 +275,13 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
val = FLD_VAL(((dd-ctx-keylen  3) - 1), 4, 3);
if (dd-flags  FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
-   if (dd-flags  FLAGS_CTR) {
+   if (dd-flags  FLAGS_CTR)
val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
-   mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK;
-   }
+
if (dd-flags  FLAGS_ENCRYPT)
val |= AES_REG_CTRL_DIRECTION;
 
-   mask |= AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
-   AES_REG_CTRL_KEY_SIZE;
-
-   omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask);
+   omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, AES_REG_CTRL_MASK);
 
return 0;
 }
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 7/7] crypto: tcrypt: Fix AEAD speed tests

2015-07-07 Thread Lokesh Vutla
The AEAD speed tests doesn't do a wait_for_completition,
if the return value is EINPROGRESS or EBUSY.
Fixing it here.
Also add a test case for gcm(aes).

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 crypto/tcrypt.c | 65 ++---
 1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 9f6f10b..3603c7c 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -73,6 +73,22 @@ static char *check[] = {
lzo, cts, zlib, NULL
 };
 
+struct tcrypt_result {
+   struct completion completion;
+   int err;
+};
+
+static void tcrypt_complete(struct crypto_async_request *req, int err)
+{
+   struct tcrypt_result *res = req-data;
+
+   if (err == -EINPROGRESS)
+   return;
+
+   res-err = err;
+   complete(res-completion);
+}
+
 static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
   struct scatterlist *sg, int blen, int secs)
 {
@@ -143,6 +159,20 @@ out:
return ret;
 }
 
+static inline int do_one_aead_op(struct aead_request *req, int ret)
+{
+   if (ret == -EINPROGRESS || ret == -EBUSY) {
+   struct tcrypt_result *tr = req-base.data;
+
+   ret = wait_for_completion_interruptible(tr-completion);
+   if (!ret)
+   ret = tr-err;
+   reinit_completion(tr-completion);
+   }
+
+   return ret;
+}
+
 static int test_aead_jiffies(struct aead_request *req, int enc,
int blen, int secs)
 {
@@ -153,9 +183,9 @@ static int test_aead_jiffies(struct aead_request *req, int 
enc,
for (start = jiffies, end = start + secs * HZ, bcount = 0;
 time_before(jiffies, end); bcount++) {
if (enc)
-   ret = crypto_aead_encrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
else
-   ret = crypto_aead_decrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
 
if (ret)
return ret;
@@ -177,9 +207,9 @@ static int test_aead_cycles(struct aead_request *req, int 
enc, int blen)
/* Warm-up run. */
for (i = 0; i  4; i++) {
if (enc)
-   ret = crypto_aead_encrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
else
-   ret = crypto_aead_decrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
 
if (ret)
goto out;
@@ -191,9 +221,9 @@ static int test_aead_cycles(struct aead_request *req, int 
enc, int blen)
 
start = get_cycles();
if (enc)
-   ret = crypto_aead_encrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
else
-   ret = crypto_aead_decrypt(req);
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
end = get_cycles();
 
if (ret)
@@ -286,6 +316,7 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
char *axbuf[XBUFSIZE];
unsigned int *b_size;
unsigned int iv_len;
+   struct tcrypt_result result;
 
iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
if (!iv)
@@ -321,6 +352,7 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
goto out_notfm;
}
 
+   init_completion(result.completion);
printk(KERN_INFO \ntesting speed of %s (%s) %s\n, algo,
get_driver_name(crypto_aead, tfm), e);
 
@@ -331,6 +363,9 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
goto out_noreq;
}
 
+   aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
i = 0;
do {
b_size = aead_sizes;
@@ -749,22 +784,6 @@ out:
crypto_free_hash(tfm);
 }
 
-struct tcrypt_result {
-   struct completion completion;
-   int err;
-};
-
-static void tcrypt_complete(struct crypto_async_request *req, int err)
-{
-   struct tcrypt_result *res = req-data;
-
-   if (err == -EINPROGRESS)
-   return;
-
-   res-err = err;
-   complete(res-completion);
-}
-
 static inline int do_one_ahash_op(struct ahash_request *req, int ret)
 {
if (ret == -EINPROGRESS || ret == -EBUSY) {
@@ -1760,6 +1779,8 @@ static int do_test(const char *alg, u32 type, u32 mask, 
int m)
case 211:
test_aead_speed(rfc4106(gcm(aes)), ENCRYPT, sec,
NULL, 0, 16, 8, aead_speed_template_20);
+   test_aead_speed(gcm(aes), ENCRYPT, sec,
+   NULL, 0, 16

[PATCH v2 1/7] crypto: omap-aes: Fix CTR mode

2015-07-07 Thread Lokesh Vutla
Algo self tests are failing for CTR mode with omap-aes driver,
giving the following error:

[  150.053644]   omap_aes_crypt: request size is not exact amount of AES 
blocks
[  150.061262] alg: skcipher: encryption failed on test 5 for ctr-aes-omap: 
ret=22

This is because the input length is not aligned with AES_BLOCK_SIZE.
Adding support for omap-aes driver for inputs with length not aligned
with AES_BLOCK_SIZE.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 9a28b7e..4a0e808 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -558,6 +558,9 @@ static int omap_aes_check_aligned(struct scatterlist *sg, 
int total)
 {
int len = 0;
 
+   if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
+   return -EINVAL;
+
while (sg) {
if (!IS_ALIGNED(sg-offset, 4))
return -1;
@@ -577,9 +580,10 @@ static int omap_aes_check_aligned(struct scatterlist *sg, 
int total)
 static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
 {
void *buf_in, *buf_out;
-   int pages;
+   int pages, total;
 
-   pages = get_order(dd-total);
+   total = ALIGN(dd-total, AES_BLOCK_SIZE);
+   pages = get_order(total);
 
buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);
@@ -594,11 +598,11 @@ static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
sg_copy_buf(buf_in, dd-in_sg, 0, dd-total, 0);
 
sg_init_table(dd-in_sgl, 1);
-   sg_set_buf(dd-in_sgl, buf_in, dd-total);
+   sg_set_buf(dd-in_sgl, buf_in, total);
dd-in_sg = dd-in_sgl;
 
sg_init_table(dd-out_sgl, 1);
-   sg_set_buf(dd-out_sgl, buf_out, dd-total);
+   sg_set_buf(dd-out_sgl, buf_out, total);
dd-out_sg = dd-out_sgl;
 
return 0;
@@ -611,7 +615,7 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
struct omap_aes_ctx *ctx;
struct omap_aes_reqctx *rctx;
unsigned long flags;
-   int err, ret = 0;
+   int err, ret = 0, len;
 
spin_lock_irqsave(dd-lock, flags);
if (req)
@@ -650,8 +654,9 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
dd-sgs_copied = 0;
}
 
-   dd-in_sg_len = scatterwalk_bytes_sglen(dd-in_sg, dd-total);
-   dd-out_sg_len = scatterwalk_bytes_sglen(dd-out_sg, dd-total);
+   len = ALIGN(dd-total, AES_BLOCK_SIZE);
+   dd-in_sg_len = scatterwalk_bytes_sglen(dd-in_sg, len);
+   dd-out_sg_len = scatterwalk_bytes_sglen(dd-out_sg, len);
BUG_ON(dd-in_sg_len  0 || dd-out_sg_len  0);
 
rctx = ablkcipher_request_ctx(req);
@@ -678,7 +683,7 @@ static void omap_aes_done_task(unsigned long data)
 {
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
void *buf_in, *buf_out;
-   int pages;
+   int pages, len;
 
pr_debug(enter done_task\n);
 
@@ -697,7 +702,8 @@ static void omap_aes_done_task(unsigned long data)
 
sg_copy_buf(buf_out, dd-orig_out, 0, dd-total_save, 1);
 
-   pages = get_order(dd-total_save);
+   len = ALIGN(dd-total_save, AES_BLOCK_SIZE);
+   pages = get_order(len);
free_pages((unsigned long)buf_in, pages);
free_pages((unsigned long)buf_out, pages);
}
@@ -726,11 +732,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, 
unsigned long mode)
  !!(mode  FLAGS_ENCRYPT),
  !!(mode  FLAGS_CBC));
 
-   if (!IS_ALIGNED(req-nbytes, AES_BLOCK_SIZE)) {
-   pr_err(request size is not exact amount of AES blocks\n);
-   return -EINVAL;
-   }
-
dd = omap_aes_find_dev(ctx);
if (!dd)
return -ENODEV;
@@ -1046,9 +1047,7 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
}
}
 
-   dd-total -= AES_BLOCK_SIZE;
-
-   BUG_ON(dd-total  0);
+   dd-total -= min_t(size_t, AES_BLOCK_SIZE, dd-total);
 
/* Clear IRQ status */
status = ~AES_REG_IRQ_DATA_OUT;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/7] crypto: omap-aes: Increase priority of hw accelerator

2015-07-07 Thread Lokesh Vutla
Increasing the priority of omap-aes hw algos, in order to take
precedence over sw algos.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 4a0e808..54925d9 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -834,7 +834,7 @@ static struct crypto_alg algs_ecb_cbc[] = {
 {
.cra_name   = ecb(aes),
.cra_driver_name= ecb-aes-omap,
-   .cra_priority   = 100,
+   .cra_priority   = 300,
.cra_flags  = CRYPTO_ALG_TYPE_ABLKCIPHER |
  CRYPTO_ALG_KERN_DRIVER_ONLY |
  CRYPTO_ALG_ASYNC,
@@ -856,7 +856,7 @@ static struct crypto_alg algs_ecb_cbc[] = {
 {
.cra_name   = cbc(aes),
.cra_driver_name= cbc-aes-omap,
-   .cra_priority   = 100,
+   .cra_priority   = 300,
.cra_flags  = CRYPTO_ALG_TYPE_ABLKCIPHER |
  CRYPTO_ALG_KERN_DRIVER_ONLY |
  CRYPTO_ALG_ASYNC,
@@ -882,7 +882,7 @@ static struct crypto_alg algs_ctr[] = {
 {
.cra_name   = ctr(aes),
.cra_driver_name= ctr-aes-omap,
-   .cra_priority   = 100,
+   .cra_priority   = 300,
.cra_flags  = CRYPTO_ALG_TYPE_ABLKCIPHER |
  CRYPTO_ALG_KERN_DRIVER_ONLY |
  CRYPTO_ALG_ASYNC,
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/7] crypto: aead: Add aead_request_cast() api

2015-07-07 Thread Lokesh Vutla
Add aead_request_cast() api to get pointer to aead_request
from cryto_async_request.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 include/crypto/internal/aead.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h
index 4b25471..0423fa5 100644
--- a/include/crypto/internal/aead.h
+++ b/include/crypto/internal/aead.h
@@ -157,6 +157,12 @@ static inline unsigned int crypto_aead_maxauthsize(struct 
crypto_aead *aead)
return crypto_aead_alg_maxauthsize(crypto_aead_alg(aead));
 }
 
+static inline struct aead_request *aead_request_cast(
+   struct crypto_async_request *req)
+{
+   return container_of(req, struct aead_request, base);
+}
+
 int crypto_register_aead(struct aead_alg *alg);
 void crypto_unregister_aead(struct aead_alg *alg);
 int crypto_register_aeads(struct aead_alg *algs, int count);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 4/7] crypto: omap-aes: Use BIT() macro

2015-07-07 Thread Lokesh Vutla
Use BIT()/GENMASK() macros for all register definitions instead of
hand-writing bit masks.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 35521b8..eba2314 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -52,17 +52,17 @@
 #define AES_REG_IV(dd, x)  ((dd)-pdata-iv_ofs + ((x) * 0x04))
 
 #define AES_REG_CTRL(dd)   ((dd)-pdata-ctrl_ofs)
-#define AES_REG_CTRL_CTR_WIDTH_MASK(3  7)
-#define AES_REG_CTRL_CTR_WIDTH_32  (0  7)
-#define AES_REG_CTRL_CTR_WIDTH_64  (1  7)
-#define AES_REG_CTRL_CTR_WIDTH_96  (2  7)
-#define AES_REG_CTRL_CTR_WIDTH_128 (3  7)
-#define AES_REG_CTRL_CTR   (1  6)
-#define AES_REG_CTRL_CBC   (1  5)
-#define AES_REG_CTRL_KEY_SIZE  (3  3)
-#define AES_REG_CTRL_DIRECTION (1  2)
-#define AES_REG_CTRL_INPUT_READY   (1  1)
-#define AES_REG_CTRL_OUTPUT_READY  (1  0)
+#define AES_REG_CTRL_CTR_WIDTH_MASKGENMASK(8, 7)
+#define AES_REG_CTRL_CTR_WIDTH_32  0
+#define AES_REG_CTRL_CTR_WIDTH_64  BIT(7)
+#define AES_REG_CTRL_CTR_WIDTH_96  BIT(8)
+#define AES_REG_CTRL_CTR_WIDTH_128 GENMASK(8, 7)
+#define AES_REG_CTRL_CTR   BIT(6)
+#define AES_REG_CTRL_CBC   BIT(5)
+#define AES_REG_CTRL_KEY_SIZE  GENMASK(4, 3)
+#define AES_REG_CTRL_DIRECTION BIT(2)
+#define AES_REG_CTRL_INPUT_READY   BIT(1)
+#define AES_REG_CTRL_OUTPUT_READY  BIT(0)
 #define AES_REG_CTRL_MASK  GENMASK(24, 2)
 
 #define AES_REG_DATA_N(dd, x)  ((dd)-pdata-data_ofs + ((x) * 0x04))
@@ -70,12 +70,12 @@
 #define AES_REG_REV(dd)((dd)-pdata-rev_ofs)
 
 #define AES_REG_MASK(dd)   ((dd)-pdata-mask_ofs)
-#define AES_REG_MASK_SIDLE (1  6)
-#define AES_REG_MASK_START (1  5)
-#define AES_REG_MASK_DMA_OUT_EN(1  3)
-#define AES_REG_MASK_DMA_IN_EN (1  2)
-#define AES_REG_MASK_SOFTRESET (1  1)
-#define AES_REG_AUTOIDLE   (1  0)
+#define AES_REG_MASK_SIDLE BIT(6)
+#define AES_REG_MASK_START BIT(5)
+#define AES_REG_MASK_DMA_OUT_ENBIT(3)
+#define AES_REG_MASK_DMA_IN_EN BIT(2)
+#define AES_REG_MASK_SOFTRESET BIT(1)
+#define AES_REG_AUTOIDLE   BIT(0)
 
 #define AES_REG_LENGTH_N(x)(0x54 + ((x) * 0x04))
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 6/7] crypto: omap-aes: Add support for GCM mode

2015-07-07 Thread Lokesh Vutla
OMAP AES hw supports AES-GCM mode.
Adding support for GCM mode in omap-aes driver.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/Kconfig|   1 +
 drivers/crypto/Makefile   |   3 +-
 drivers/crypto/omap-aes-gcm.c | 376 ++
 drivers/crypto/omap-aes.c | 300 ++---
 drivers/crypto/omap-aes.h | 212 
 5 files changed, 718 insertions(+), 174 deletions(-)
 create mode 100644 drivers/crypto/omap-aes-gcm.c
 create mode 100644 drivers/crypto/omap-aes.h

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 4044125..6e67271 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -293,6 +293,7 @@ config CRYPTO_DEV_OMAP_AES
depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP2PLUS
select CRYPTO_AES
select CRYPTO_BLKCIPHER
+   select CRYPTO_AEAD
help
  OMAP processors have AES module accelerator. Select this if you
  want to use the OMAP module for AES algorithms.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index e35c07a..73115bd 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
 obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
 n2_crypto-y := n2_core.o n2_asm.o
 obj-$(CONFIG_CRYPTO_DEV_NX) += nx/
-obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes-driver.o
+omap-aes-driver-objs := omap-aes.o omap-aes-gcm.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
 obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
new file mode 100644
index 000..f0faa72
--- /dev/null
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -0,0 +1,376 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for OMAP AES GCM HW acceleration.
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include linux/errno.h
+#include linux/scatterlist.h
+#include linux/dma-mapping.h
+#include linux/dmaengine.h
+#include linux/omap-dma.h
+#include linux/interrupt.h
+#include crypto/scatterwalk.h
+#include crypto/aes.h
+#include crypto/internal/aead.h
+#include omap-aes.h
+
+static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
+struct aead_request *req);
+
+static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, int ret)
+{
+   struct aead_request *req = dd-aead_req;
+
+   dd-flags = ~FLAGS_BUSY;
+   dd-in_sg = NULL;
+   dd-out_sg = NULL;
+
+   req-base.complete(req-base, ret);
+}
+
+static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
+{
+   void *buf;
+   u8 *tag;
+   int pages, alen, clen, i, ret = 0, nsg;
+
+   alen = ALIGN(dd-assoc_len, AES_BLOCK_SIZE);
+   clen = ALIGN(dd-total, AES_BLOCK_SIZE);
+
+   nsg = !!(dd-assoc_len  dd-total);
+
+   dma_sync_sg_for_device(dd-dev, dd-out_sg, dd-out_sg_len,
+  DMA_FROM_DEVICE);
+   dma_unmap_sg(dd-dev, dd-in_sg, dd-in_sg_len, DMA_TO_DEVICE);
+   dma_unmap_sg(dd-dev, dd-out_sg, dd-out_sg_len, DMA_FROM_DEVICE);
+   omap_aes_crypt_dma_stop(dd);
+
+   if (dd-sgs_copied  AES_OUT_DATA_COPIED) {
+   buf = sg_virt(dd-out_sgl);
+   scatterwalk_map_and_copy(buf, dd-orig_out, dd-assoc_len,
+dd-total, 1);
+
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
+   if (dd-flags  FLAGS_ENCRYPT)
+   scatterwalk_map_and_copy(dd-ctx-auth_tag,
+dd-aead_req-dst,
+dd-total + dd-assoc_len,
+dd-authsize, 1);
+
+   if (dd-sgs_copied  AES_ASSOC_DATA_COPIED) {
+   buf = sg_virt(dd-in_sgl[0]);
+   pages = get_order(alen);
+   free_pages((unsigned long)buf, pages);
+   }
+   if (dd-sgs_copied  AES_IN_DATA_COPIED) {
+   buf = sg_virt(dd-in_sgl[nsg]);
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
+   if (!(dd-flags  FLAGS_ENCRYPT)) {
+   tag = (u8 *)dd-ctx-auth_tag;
+   for (i = 0; i  dd-authsize; i++) {
+   if (tag[i]) {
+   dev_err(dd-dev, GCM decryption: Tag Message 
is wrong\n);
+   ret = -EBADMSG;
+   }
+   }
+   }
+
+   omap_aes_gcm_finish_req(dd, ret);
+   omap_aes_gcm_handle_queue(dd, NULL);
+}
+
+static int

Re: [PATCH 08/10] crypto: omap-aes: gmc: Add algo info

2015-07-06 Thread Lokesh Vutla
Hi,
On Monday 06 July 2015 01:05 PM, Herbert Xu wrote:
 On Thu, Jul 02, 2015 at 10:48:38AM +0530, Lokesh Vutla wrote:
 Now the driver supports gcm mode, add omap-aes-gcm
 algo info to omap-aes driver.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 
 You're using the old AEAD interface.  We are now moving to the
 new AEAD interface so I will not be accepting any new implementations
 using the old interface.
 
 Please convert your driver over to the new interface.
Will convert omap-aes driver to new interface and repost.

Thanks and regards,
Lokesh
 
 Also please merge your GCM patches into a single patch.  Splitting
 out bug fixes makes no sense.
 
 Thanks,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 05/10] crypto: omap-aes: Add support for GCM mode

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:34 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:35AM +0530, Lokesh Vutla wrote:
 OMAP AES hw supports aes gcm mode.
 
 here you refer to it as 'gcm'
Will update it in next revision.
 
 Adding support for GCM mode in omap-aes driver.
 
 while here and in subject as 'GCM'.
 
 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  drivers/crypto/Makefile   |3 +-
  drivers/crypto/omap-aes-gcm.c |  304 
 +
 
 why does this have to be a separate source file ? Patch gets really
 large with all the macro and structure definition being shuffled around.
GCM is an aead(authenticated encryption and decryption) but
other modes are just block ciphers(encryption and decryption).
Crypto library defines differ structures and routines for aead and normal
block ciphers.
So I started off with a new driver, and later able to combine common parts.
Since GCM is a bit different from all other modes, I left it in a new file.
If I combine into same file, it will be difficult to track all these fucntions
at a time.   

Thanks and regards,
Lokesh

 
  drivers/crypto/omap-aes.c |  238 +---
  drivers/crypto/omap-aes.h |  205 +++
  4 files changed, 575 insertions(+), 175 deletions(-)
  create mode 100644 drivers/crypto/omap-aes-gcm.c
  create mode 100644 drivers/crypto/omap-aes.h

 diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
 index fb84be7..3afad7b 100644
 --- a/drivers/crypto/Makefile
 +++ b/drivers/crypto/Makefile
 @@ -13,7 +13,8 @@ obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
  obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
  n2_crypto-y := n2_core.o n2_asm.o
  obj-$(CONFIG_CRYPTO_DEV_NX) += nx/
 -obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
 +obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes-driver.o
 +omap-aes-driver-objs := omap-aes.o omap-aes-gcm.o
 
 ... I mean, considering you unconditionally link these two together...
 
 diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
 new file mode 100644
 index 000..1be9d91
 --- /dev/null
 +++ b/drivers/crypto/omap-aes-gcm.c
 @@ -0,0 +1,304 @@
 +/*
 + * Cryptographic API.
 + *
 + * Support for OMAP AES GCM HW acceleration.
 + *
 + * Copyright (c) 2015 Texas Instruments Incorporated
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as 
 published
 + * by the Free Software Foundation.
 + *
 + */
 +
 +#include linux/err.h
 +#include linux/module.h
 +#include linux/init.h
 +#include linux/errno.h
 +#include linux/kernel.h
 +#include linux/platform_device.h
 +#include linux/scatterlist.h
 +#include linux/dma-mapping.h
 +#include linux/dmaengine.h
 +#include linux/omap-dma.h
 +#include linux/pm_runtime.h
 +#include linux/of.h
 +#include linux/of_device.h
 +#include linux/of_address.h
 +#include linux/io.h
 +#include linux/crypto.h
 +#include linux/interrupt.h
 +#include crypto/scatterwalk.h
 +#include crypto/aes.h
 +#include omap-aes.h
 +
 +static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
 + struct aead_request *req);
 +
 +static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, int ret)
 +{
 +struct aead_request *req = dd-aead_req;
 +
 +dd-flags = ~FLAGS_BUSY;
 +dd-in_sg = NULL;
 +dd-out_sg = NULL;
 +
 +req-base.complete(req-base, ret);
 +}
 +
 +static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
 +{
 +u8 *tag;
 +int alen, clen, i, ret = 0, nsg;
 +
 +alen = ALIGN(dd-assoc_len, AES_BLOCK_SIZE);
 +clen = ALIGN(dd-total, AES_BLOCK_SIZE);
 +
 +nsg = 1 + !!(dd-assoc_len  dd-total);
 +
 +if (!dd-pio_only) {
 +dma_sync_sg_for_device(dd-dev, dd-out_sg, dd-out_sg_len,
 +   DMA_FROM_DEVICE);
 +dma_unmap_sg(dd-dev, dd-in_sg, dd-in_sg_len, DMA_TO_DEVICE);
 +dma_unmap_sg(dd-dev, dd-out_sg, dd-out_sg_len,
 + DMA_FROM_DEVICE);
 +omap_aes_crypt_dma_stop(dd);
 +}
 +
 +if (dd-flags  FLAGS_ENCRYPT)
 +scatterwalk_map_and_copy(dd-ctx-auth_tag, dd-aead_req-dst,
 + dd-total, dd-authsize, 1);
 +
 +if (!(dd-flags  FLAGS_ENCRYPT)) {
 +tag = (u8 *)dd-ctx-auth_tag;
 +for (i = 0; i  dd-authsize; i++) {
 +if (tag[i]) {
 +dev_err(dd-dev, GCM decryption: Tag Message 
 is wrong\n);
 +ret = -EBADMSG;
 +}
 +}
 +}
 +
 +omap_aes_gcm_finish_req(dd, ret);
 +omap_aes_gcm_handle_queue(dd, NULL);
 +}
 +
 +static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
 + struct aead_request *req)
 +{
 +void *buf_in;
 +int alen, clen;
 +struct crypto_aead *aead = crypto_aead_reqtfm(req);
 +unsigned int

Re: [PATCH 06/10] crypto: omap-aes: gcm: Handle inputs properly

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:34 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:36AM +0530, Lokesh Vutla wrote:
 Its not necessary that assoc data and plain text is passed always.
 Add these checks before processing the input.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 
 why can't this be combined with patch which added GCM in the first
 place ?
Yes, my initial patch is all combined. But it was very big.
I tried my best in breaking down into different patches inorder to
help reviewer.
So, I kept the functionality part in one patch, and handled corner case
like these in separate patches.

Thanks and regards,
Lokesh

 
 ---
  drivers/crypto/omap-aes-gcm.c |   26 --
  1 file changed, 20 insertions(+), 6 deletions(-)

 diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
 index 1be9d91..72815af 100644
 --- a/drivers/crypto/omap-aes-gcm.c
 +++ b/drivers/crypto/omap-aes-gcm.c
 @@ -87,7 +87,7 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
 *dd,
   struct aead_request *req)
  {
  void *buf_in;
 -int alen, clen;
 +int alen, clen, nsg;
  struct crypto_aead *aead = crypto_aead_reqtfm(req);
  unsigned int authlen = crypto_aead_authsize(aead);
  u32 dec = !(dd-flags  FLAGS_ENCRYPT);
 @@ -97,12 +97,18 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
 *dd,
  
  dd-sgs_copied = 0;
  
 -sg_init_table(dd-in_sgl, 2);
 -buf_in = sg_virt(req-assoc);
 -sg_set_buf(dd-in_sgl, buf_in, alen);
 +nsg = 1 + !!(req-assoclen  req-cryptlen);
  
 -buf_in = sg_virt(req-src);
 -sg_set_buf(dd-in_sgl[1], buf_in, clen);
 +sg_init_table(dd-in_sgl, nsg);
 +if (req-assoclen) {
 +buf_in = sg_virt(req-assoc);
 +sg_set_buf(dd-in_sgl, buf_in, alen);
 +}
 +
 +if (req-cryptlen) {
 +buf_in = sg_virt(req-src);
 +sg_set_buf(dd-in_sgl[nsg - 1], buf_in, clen);
 +}
  
  dd-in_sg = dd-in_sgl;
  dd-total = clen;
 @@ -258,6 +264,8 @@ static int omap_aes_gcm_crypt(struct aead_request *req, 
 unsigned long mode)
  {
  struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
  struct omap_aes_reqctx *rctx = aead_request_ctx(req);
 +struct crypto_aead *aead = crypto_aead_reqtfm(req);
 +unsigned int authlen = crypto_aead_authsize(aead);
  struct omap_aes_dev *dd;
  __be32 counter = cpu_to_be32(1);
  int err;
 @@ -270,6 +278,12 @@ static int omap_aes_gcm_crypt(struct aead_request *req, 
 unsigned long mode)
  if (err)
  return err;
  
 +if (req-assoclen + req-cryptlen == 0) {
 +scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
 + 1);
 +return 0;
 +}
 +
  dd = omap_aes_find_dev(ctx);
  if (!dd)
  return -ENODEV;
 -- 
 1.7.9.5

 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/10] crypto: omap-aes: Fix configuring of AES mode

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:27 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:32AM +0530, Lokesh Vutla wrote:
 AES_CTRL_REG is used to configure AES mode. Before configuring
 any mode we need to make sure all other modes are reset or else
 driver will misbehave. So mask all modes before configuring
 any AES mode.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  drivers/crypto/omap-aes.c |   13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

 diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
 index a923101..96fc7f7 100644
 --- a/drivers/crypto/omap-aes.c
 +++ b/drivers/crypto/omap-aes.c
 @@ -63,6 +63,7 @@
  #define AES_REG_CTRL_DIRECTION  (1  2)
  #define AES_REG_CTRL_INPUT_READY(1  1)
  #define AES_REG_CTRL_OUTPUT_READY   (1  0)
 +#define AES_REG_CTRL_MASK   FLD_MASK(24, 2)
 
 you end up masking bits which aren't even defined in this driver. What
 are those bits ? Perhaps add macros for them and define
 AES_REG_CTRL_MASK by explicitly ORing those macros ? That would, at
 least, be clearer
Hardware supports ECB, CBC, CTR, CFB, F8, CBC_MAC, F9, GCM, CCM, XTS modes.
But current driver has only ECB, CBC, CTR modes support.
That is why the other fields are not yet defined.
So, defining these is fine, but ORing all these will be very big and looks a 
bit ugly.
So I kept it as mask of all these bits.
Ill move it to GEN_MASK here only.

Thanks and regards,
Lokesh

 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/10] crypto: aead: Add aead_request_cast() api

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:28 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:33AM +0530, Lokesh Vutla wrote:
 Add aead_request_cast() api to get pointer to aead_request
 from cryto_async_request.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  include/linux/crypto.h |6 ++
  1 file changed, 6 insertions(+)

 diff --git a/include/linux/crypto.h b/include/linux/crypto.h
 index 10df5d2..20fac3d 100644
 --- a/include/linux/crypto.h
 +++ b/include/linux/crypto.h
 @@ -1460,6 +1460,12 @@ static inline void aead_request_set_tfm(struct 
 aead_request *req,
  req-base.tfm = crypto_aead_tfm(crypto_aead_crt(tfm)-base);
  }
  
 +static inline struct aead_request *aead_request_cast(
 +struct crypto_async_request *req)
 +{
 +return container_of(req, struct aead_request, base);
 
 container_of() ensures type safety, this can be a macro just fine.
There are many similar definitions for ablkcipher.. etc,in
crypto library. So I tried to make it uniform for the entire library.

Thanks and regards,
Lokesh 
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 08/10] crypto: omap-aes: gmc: Add algo info

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:30 PM, Stephan Mueller wrote:
 Am Donnerstag, 2. Juli 2015, 10:48:38 schrieb Lokesh Vutla:
 
 Hi Lokesh,
 
 Now the driver supports gcm mode, add omap-aes-gcm
 algo info to omap-aes driver.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
 drivers/crypto/omap-aes.c |   22 ++
 1 file changed, 22 insertions(+)

 diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
 index e5e9a19..11f3850 100644
 --- a/drivers/crypto/omap-aes.c
 +++ b/drivers/crypto/omap-aes.c
 @@ -789,6 +789,28 @@ static struct crypto_alg algs_ctr[] = {
  .decrypt= omap_aes_ctr_decrypt,
  }
 },
 +{
 +.cra_name   = gcm(aes),
 +.cra_driver_name= gcm-aes-omap,
 +.cra_priority   = 100,
 
 Why did you choose the priority 100? The software implementations commonly 
 use 
 100. crypto/gcm.c uses the prio of the underlying cipher. In case of ARM, 
 there seem to be assembler implementations of AES which have the prio of 200 
 or 300. So, such software implementation of gcm(aes) would have a higher 
 precedence than your hw implementation.
Yes, you are right.
Other hw algos in omap-aes also uses priority 100.
Only sw and hw implementations are enabled right now and both are at same 
priority.
And till now its lucky enough that hw algo gets picked.

Ill change the priority to 300 for all the modes.
Thanks for pointing it.

Regards,
Lokesh
 
 So, if a user would use gcm(aes), isn't it more likely that he gets the 
 software implementation?
 
 +.cra_flags  = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC |
 +  CRYPTO_ALG_KERN_DRIVER_ONLY,
 +.cra_blocksize  = AES_BLOCK_SIZE,
 +.cra_ctxsize= sizeof(struct omap_aes_ctx),
 +.cra_alignmask  = 0xf,
 +.cra_type   = crypto_aead_type,
 +.cra_module = THIS_MODULE,
 +.cra_init   = omap_aes_gcm_cra_init,
 +.cra_exit   = omap_aes_cra_exit,
 +.cra_u.aead = {
 +.maxauthsize= AES_BLOCK_SIZE,
 +.geniv  = eseqiv,
 +.ivsize = AES_BLOCK_SIZE,
 +.setkey = omap_aes_gcm_setkey,
 +.encrypt= omap_aes_gcm_encrypt,
 +.decrypt= omap_aes_gcm_decrypt,
 +}
 +},
 };

 static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc[] = {
 
 
 Ciao
 Stephan
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/10] crypto: omap-aes: gcm: Add support for PIO mode

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:36 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:39AM +0530, Lokesh Vutla wrote:
 Add support for PIO mode for GCM mode.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 
 why do you require PIO ? Is there any situation where DMA can't be
 used? What would that case be ?

Cannot think of any case where DMA can't be used.
But the current driver already supports PIO for all other AES modes.
I do not want to break it, so added support for PIO  for GCM :)

Thanks and regards,
Lokesh

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 01/10] crypto: omap-aes: Add support for lengths not aligned with AES_BLOCK_SIZE

2015-07-02 Thread Lokesh Vutla
On Thursday 02 July 2015 01:23 PM, Felipe Balbi wrote:
 On Thu, Jul 02, 2015 at 10:48:31AM +0530, Lokesh Vutla wrote:
 OMAP AES driver returns an error if the data is not aligned with
 AES_BLOCK_SIZE bytes.
 But OMAP AES hw allows data input upto 1 byte aligned, but still
 zeros are to be appended and complete AES_BLOCK_SIZE has to be written.
 And correct length has to be passed in LENGTH field.
 Adding support for inputs not aligned with AES_BLOCK_SIZE.

 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  drivers/crypto/omap-aes.c |   33 -
  1 file changed, 16 insertions(+), 17 deletions(-)

 diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
 index 9a28b7e..a923101 100644
 --- a/drivers/crypto/omap-aes.c
 +++ b/drivers/crypto/omap-aes.c
 @@ -558,6 +558,9 @@ static int omap_aes_check_aligned(struct scatterlist 
 *sg, int total)
  {
  int len = 0;
  
 +if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
 +return -1;
 
 -EINVAL?
Okay, will update it.

Thanks and regards,
Lokesh
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: omap-des: Fix unmapping of dma channels

2015-07-02 Thread Lokesh Vutla
dma_unmap_sg() is being called twice after completing the
task. Looks like this is a copy paste error when creating
des driver.
With this the following warn appears during boot:

[4.210457] [ cut here ]
[4.215114] WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:1080 
check_unmap+0x710/0x9a0()
[4.222899] omap-des 480a5000.des: DMA-API: device driver tries to free DMA 
memory it has not allocated [device address=0xab2ce000] [size=8 bytes]
[4.236785] Modules linked in:
[4.239860] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 
3.14.39-02999-g1bc045a-dirty #182
[4.247918] [c001678c] (unwind_backtrace) from [c0012574] 
(show_stack+0x10/0x14)
[4.255710] [c0012574] (show_stack) from [c05a37e8] 
(dump_stack+0x84/0xb8)
[4.262977] [c05a37e8] (dump_stack) from [c0046464] 
(warn_slowpath_common+0x68/0x8c)
[4.271107] [c0046464] (warn_slowpath_common) from [c004651c] 
(warn_slowpath_fmt+0x30/0x40)
[4.279854] [c004651c] (warn_slowpath_fmt) from [c02d50a4] 
(check_unmap+0x710/0x9a0)
[4.287991] [c02d50a4] (check_unmap) from [c02d5478] 
(debug_dma_unmap_sg+0x90/0x19c)
[4.296128] [c02d5478] (debug_dma_unmap_sg) from [c04a77d8] 
(omap_des_done_task+0x1cc/0x3e4)
[4.304963] [c04a77d8] (omap_des_done_task) from [c004a090] 
(tasklet_action+0x84/0x124)
[4.313370] [c004a090] (tasklet_action) from [c004a4ac] 
(__do_softirq+0xf0/0x20c)
[4.321235] [c004a4ac] (__do_softirq) from [c004a840] 
(irq_exit+0x98/0xec)
[4.328500] [c004a840] (irq_exit) from [c000f9ac] (handle_IRQ+0x50/0xb0)
[4.335589] [c000f9ac] (handle_IRQ) from [c0008688] 
(gic_handle_irq+0x28/0x5c)

Removing the duplicate call to dma_unmap_sg().

Reported-by: Tomi Valkeinen tomi.valkei...@ti.com
Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-des.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c
index 4630709..0a70e46 100644
--- a/drivers/crypto/omap-des.c
+++ b/drivers/crypto/omap-des.c
@@ -536,9 +536,6 @@ static int omap_des_crypt_dma_stop(struct omap_des_dev *dd)
dmaengine_terminate_all(dd-dma_lch_in);
dmaengine_terminate_all(dd-dma_lch_out);
 
-   dma_unmap_sg(dd-dev, dd-in_sg, dd-in_sg_len, DMA_TO_DEVICE);
-   dma_unmap_sg(dd-dev, dd-out_sg, dd-out_sg_len, DMA_FROM_DEVICE);
-
return err;
 }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/10] crypto: omap-aes: Add support for GCM mode

2015-07-01 Thread Lokesh Vutla
OMAP AES hw supports aes gcm mode.
Adding support for GCM mode in omap-aes driver.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/Makefile   |3 +-
 drivers/crypto/omap-aes-gcm.c |  304 +
 drivers/crypto/omap-aes.c |  238 +---
 drivers/crypto/omap-aes.h |  205 +++
 4 files changed, 575 insertions(+), 175 deletions(-)
 create mode 100644 drivers/crypto/omap-aes-gcm.c
 create mode 100644 drivers/crypto/omap-aes.h

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index fb84be7..3afad7b 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -13,7 +13,8 @@ obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
 obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
 n2_crypto-y := n2_core.o n2_asm.o
 obj-$(CONFIG_CRYPTO_DEV_NX) += nx/
-obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes-driver.o
+omap-aes-driver-objs := omap-aes.o omap-aes-gcm.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
 obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
new file mode 100644
index 000..1be9d91
--- /dev/null
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -0,0 +1,304 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for OMAP AES GCM HW acceleration.
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include linux/err.h
+#include linux/module.h
+#include linux/init.h
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/platform_device.h
+#include linux/scatterlist.h
+#include linux/dma-mapping.h
+#include linux/dmaengine.h
+#include linux/omap-dma.h
+#include linux/pm_runtime.h
+#include linux/of.h
+#include linux/of_device.h
+#include linux/of_address.h
+#include linux/io.h
+#include linux/crypto.h
+#include linux/interrupt.h
+#include crypto/scatterwalk.h
+#include crypto/aes.h
+#include omap-aes.h
+
+static int omap_aes_gcm_handle_queue(struct omap_aes_dev *dd,
+struct aead_request *req);
+
+static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, int ret)
+{
+   struct aead_request *req = dd-aead_req;
+
+   dd-flags = ~FLAGS_BUSY;
+   dd-in_sg = NULL;
+   dd-out_sg = NULL;
+
+   req-base.complete(req-base, ret);
+}
+
+static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
+{
+   u8 *tag;
+   int alen, clen, i, ret = 0, nsg;
+
+   alen = ALIGN(dd-assoc_len, AES_BLOCK_SIZE);
+   clen = ALIGN(dd-total, AES_BLOCK_SIZE);
+
+   nsg = 1 + !!(dd-assoc_len  dd-total);
+
+   if (!dd-pio_only) {
+   dma_sync_sg_for_device(dd-dev, dd-out_sg, dd-out_sg_len,
+  DMA_FROM_DEVICE);
+   dma_unmap_sg(dd-dev, dd-in_sg, dd-in_sg_len, DMA_TO_DEVICE);
+   dma_unmap_sg(dd-dev, dd-out_sg, dd-out_sg_len,
+DMA_FROM_DEVICE);
+   omap_aes_crypt_dma_stop(dd);
+   }
+
+   if (dd-flags  FLAGS_ENCRYPT)
+   scatterwalk_map_and_copy(dd-ctx-auth_tag, dd-aead_req-dst,
+dd-total, dd-authsize, 1);
+
+   if (!(dd-flags  FLAGS_ENCRYPT)) {
+   tag = (u8 *)dd-ctx-auth_tag;
+   for (i = 0; i  dd-authsize; i++) {
+   if (tag[i]) {
+   dev_err(dd-dev, GCM decryption: Tag Message 
is wrong\n);
+   ret = -EBADMSG;
+   }
+   }
+   }
+
+   omap_aes_gcm_finish_req(dd, ret);
+   omap_aes_gcm_handle_queue(dd, NULL);
+}
+
+static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
+struct aead_request *req)
+{
+   void *buf_in;
+   int alen, clen;
+   struct crypto_aead *aead = crypto_aead_reqtfm(req);
+   unsigned int authlen = crypto_aead_authsize(aead);
+   u32 dec = !(dd-flags  FLAGS_ENCRYPT);
+
+   alen = req-assoclen;
+   clen = req-cryptlen - (dec * authlen);
+
+   dd-sgs_copied = 0;
+
+   sg_init_table(dd-in_sgl, 2);
+   buf_in = sg_virt(req-assoc);
+   sg_set_buf(dd-in_sgl, buf_in, alen);
+
+   buf_in = sg_virt(req-src);
+   sg_set_buf(dd-in_sgl[1], buf_in, clen);
+
+   dd-in_sg = dd-in_sgl;
+   dd-total = clen;
+   dd-assoc_len = req-assoclen;
+   dd-authsize = authlen;
+   dd-out_sg = req-dst;
+
+   dd-in_sg_len = scatterwalk_bytes_sglen(dd-in_sg, alen + clen);
+   dd-out_sg_len = scatterwalk_bytes_sglen(dd-out_sg, clen);
+
+   return 0;
+}
+
+static void tcrypt_complete(struct crypto_async_request *req, int err

[PATCH 10/10] crypto: tcrypt: Added speed tests for Async AEAD crypto alogrithms

2015-07-01 Thread Lokesh Vutla
Adding simple speed tests for a range of block sizes for Async AEAD crypto
algorithms.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 crypto/tcrypt.c |  233 +++
 crypto/tcrypt.h |1 +
 2 files changed, 234 insertions(+)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 1a28001..b37f3f4 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -992,6 +992,234 @@ out:
crypto_free_ahash(tfm);
 }
 
+static inline int do_one_aead_op(struct aead_request *req, int ret)
+{
+   if (ret == -EINPROGRESS || ret == -EBUSY) {
+   struct tcrypt_result *tr = req-base.data;
+
+   ret = wait_for_completion_interruptible(tr-completion);
+   if (!ret)
+   ret = tr-err;
+   reinit_completion(tr-completion);
+   }
+
+   return ret;
+}
+
+static int test_aaead_jiffies(struct aead_request *req, int enc,
+ int blen, int sec)
+{
+   unsigned long start, end;
+   int bcount;
+   int ret;
+
+   for (start = jiffies, end = start + sec * HZ, bcount = 0;
+time_before(jiffies, end); bcount++) {
+   if (enc)
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
+   else
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
+
+   if (ret)
+   return ret;
+   }
+
+   pr_cont(%d operations in %d seconds (%ld bytes)\n,
+   bcount, sec, (long)bcount * blen);
+   return 0;
+}
+
+static int test_aaead_cycles(struct aead_request *req, int enc, int blen)
+{
+   unsigned long cycles = 0;
+   int ret = 0;
+   int i;
+
+   /* Warm-up run. */
+   for (i = 0; i  4; i++) {
+   if (enc)
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
+   else
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
+
+   if (ret)
+   goto out;
+   }
+
+   /* The real thing. */
+   for (i = 0; i  8; i++) {
+   cycles_t start, end;
+
+   start = get_cycles();
+   if (enc)
+   ret = do_one_aead_op(req, crypto_aead_encrypt(req));
+   else
+   ret = do_one_aead_op(req, crypto_aead_decrypt(req));
+
+   end = get_cycles();
+
+   if (ret)
+   goto out;
+
+   cycles += end - start;
+   }
+
+out:
+   if (ret == 0)
+   pr_cont(1 operation in %lu cycles (%d bytes)\n,
+   (cycles + 4) / 8, blen);
+
+   return ret;
+}
+
+static void test_aaead_speed(const char *algo, int enc, unsigned int sec,
+struct aead_speed_template *template,
+unsigned int tcount, u8 authsize,
+unsigned int aad_size, u8 *keysize)
+{
+   unsigned int i, j;
+   struct crypto_aead *tfm;
+   int ret = -ENOMEM;
+   const char *key;
+   struct aead_request *req;
+   struct scatterlist *sg;
+   struct scatterlist *asg;
+   struct scatterlist *sgout;
+   const char *e;
+   void *assoc;
+   char iv[MAX_IVLEN];
+   char *xbuf[XBUFSIZE];
+   char *xoutbuf[XBUFSIZE];
+   char *axbuf[XBUFSIZE];
+   unsigned int *b_size;
+   unsigned int iv_len;
+   struct tcrypt_result result;
+
+   if (enc == ENCRYPT)
+   e = encryption;
+   else
+   e = decryption;
+
+   if (testmgr_alloc_buf(xbuf))
+   goto out_noxbuf;
+   if (testmgr_alloc_buf(axbuf))
+   goto out_noaxbuf;
+   if (testmgr_alloc_buf(xoutbuf))
+   goto out_nooutbuf;
+
+   sg = kmalloc(sizeof(*sg) * 8 * 3, GFP_KERNEL);
+   if (!sg)
+   goto out_nosg;
+   asg = sg[8];
+   sgout = asg[8];
+
+   init_completion(result.completion);
+   pr_info(\ntesting speed of %s %s\n, algo, e);
+
+   tfm = crypto_alloc_aead(algo, 0, 0);
+
+   if (IS_ERR(tfm)) {
+   pr_err(alg: aead: Failed to load transform for %s: %ld\n,
+  algo, PTR_ERR(tfm));
+   return;
+   }
+
+   req = aead_request_alloc(tfm, GFP_KERNEL);
+   if (!req) {
+   pr_err(alg: aead: Failed to allocate request for %s\n,
+  algo);
+   goto out;
+   }
+
+   aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
+   i = 0;
+   do {
+   b_size = aead_sizes;
+   do {
+   assoc = axbuf[0];
+
+   if (aad_size  PAGE_SIZE) {
+   memset(assoc, 0xff, aad_size);
+   } else {
+   pr_err(associate data length

[PATCH 03/10] crypto: aead: Add aead_request_cast() api

2015-07-01 Thread Lokesh Vutla
Add aead_request_cast() api to get pointer to aead_request
from cryto_async_request.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 include/linux/crypto.h |6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 10df5d2..20fac3d 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -1460,6 +1460,12 @@ static inline void aead_request_set_tfm(struct 
aead_request *req,
req-base.tfm = crypto_aead_tfm(crypto_aead_crt(tfm)-base);
 }
 
+static inline struct aead_request *aead_request_cast(
+   struct crypto_async_request *req)
+{
+   return container_of(req, struct aead_request, base);
+}
+
 /**
  * aead_request_alloc() - allocate request data structure
  * @tfm: cipher handle to be registered with the request
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/10] crypto: omap-aes: gmc: Add algo info

2015-07-01 Thread Lokesh Vutla
Now the driver supports gcm mode, add omap-aes-gcm
algo info to omap-aes driver.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c |   22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index e5e9a19..11f3850 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -789,6 +789,28 @@ static struct crypto_alg algs_ctr[] = {
.decrypt= omap_aes_ctr_decrypt,
}
 },
+{
+   .cra_name   = gcm(aes),
+   .cra_driver_name= gcm-aes-omap,
+   .cra_priority   = 100,
+   .cra_flags  = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_KERN_DRIVER_ONLY,
+   .cra_blocksize  = AES_BLOCK_SIZE,
+   .cra_ctxsize= sizeof(struct omap_aes_ctx),
+   .cra_alignmask  = 0xf,
+   .cra_type   = crypto_aead_type,
+   .cra_module = THIS_MODULE,
+   .cra_init   = omap_aes_gcm_cra_init,
+   .cra_exit   = omap_aes_cra_exit,
+   .cra_u.aead = {
+   .maxauthsize= AES_BLOCK_SIZE,
+   .geniv  = eseqiv,
+   .ivsize = AES_BLOCK_SIZE,
+   .setkey = omap_aes_gcm_setkey,
+   .encrypt= omap_aes_gcm_encrypt,
+   .decrypt= omap_aes_gcm_decrypt,
+   }
+},
 };
 
 static struct omap_aes_algs_info omap_aes_algs_info_ecb_cbc[] = {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/10] crypto: omap-aes: Add support for lengths not aligned with AES_BLOCK_SIZE

2015-07-01 Thread Lokesh Vutla
OMAP AES driver returns an error if the data is not aligned with
AES_BLOCK_SIZE bytes.
But OMAP AES hw allows data input upto 1 byte aligned, but still
zeros are to be appended and complete AES_BLOCK_SIZE has to be written.
And correct length has to be passed in LENGTH field.
Adding support for inputs not aligned with AES_BLOCK_SIZE.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c |   33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 9a28b7e..a923101 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -558,6 +558,9 @@ static int omap_aes_check_aligned(struct scatterlist *sg, 
int total)
 {
int len = 0;
 
+   if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
+   return -1;
+
while (sg) {
if (!IS_ALIGNED(sg-offset, 4))
return -1;
@@ -577,9 +580,10 @@ static int omap_aes_check_aligned(struct scatterlist *sg, 
int total)
 static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
 {
void *buf_in, *buf_out;
-   int pages;
+   int pages, total;
 
-   pages = get_order(dd-total);
+   total = ALIGN(dd-total, AES_BLOCK_SIZE);
+   pages = get_order(total);
 
buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);
@@ -594,11 +598,11 @@ static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
sg_copy_buf(buf_in, dd-in_sg, 0, dd-total, 0);
 
sg_init_table(dd-in_sgl, 1);
-   sg_set_buf(dd-in_sgl, buf_in, dd-total);
+   sg_set_buf(dd-in_sgl, buf_in, total);
dd-in_sg = dd-in_sgl;
 
sg_init_table(dd-out_sgl, 1);
-   sg_set_buf(dd-out_sgl, buf_out, dd-total);
+   sg_set_buf(dd-out_sgl, buf_out, total);
dd-out_sg = dd-out_sgl;
 
return 0;
@@ -611,7 +615,7 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
struct omap_aes_ctx *ctx;
struct omap_aes_reqctx *rctx;
unsigned long flags;
-   int err, ret = 0;
+   int err, ret = 0, len;
 
spin_lock_irqsave(dd-lock, flags);
if (req)
@@ -650,8 +654,9 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
dd-sgs_copied = 0;
}
 
-   dd-in_sg_len = scatterwalk_bytes_sglen(dd-in_sg, dd-total);
-   dd-out_sg_len = scatterwalk_bytes_sglen(dd-out_sg, dd-total);
+   len = ALIGN(dd-total, AES_BLOCK_SIZE);
+   dd-in_sg_len = scatterwalk_bytes_sglen(dd-in_sg, len);
+   dd-out_sg_len = scatterwalk_bytes_sglen(dd-out_sg, len);
BUG_ON(dd-in_sg_len  0 || dd-out_sg_len  0);
 
rctx = ablkcipher_request_ctx(req);
@@ -678,7 +683,7 @@ static void omap_aes_done_task(unsigned long data)
 {
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
void *buf_in, *buf_out;
-   int pages;
+   int pages, len;
 
pr_debug(enter done_task\n);
 
@@ -697,7 +702,8 @@ static void omap_aes_done_task(unsigned long data)
 
sg_copy_buf(buf_out, dd-orig_out, 0, dd-total_save, 1);
 
-   pages = get_order(dd-total_save);
+   len = ALIGN(dd-total_save, AES_BLOCK_SIZE);
+   pages = get_order(len);
free_pages((unsigned long)buf_in, pages);
free_pages((unsigned long)buf_out, pages);
}
@@ -726,11 +732,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, 
unsigned long mode)
  !!(mode  FLAGS_ENCRYPT),
  !!(mode  FLAGS_CBC));
 
-   if (!IS_ALIGNED(req-nbytes, AES_BLOCK_SIZE)) {
-   pr_err(request size is not exact amount of AES blocks\n);
-   return -EINVAL;
-   }
-
dd = omap_aes_find_dev(ctx);
if (!dd)
return -ENODEV;
@@ -1046,9 +1047,7 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
}
}
 
-   dd-total -= AES_BLOCK_SIZE;
-
-   BUG_ON(dd-total  0);
+   dd-total -= min_t(size_t, AES_BLOCK_SIZE, dd-total);
 
/* Clear IRQ status */
status = ~AES_REG_IRQ_DATA_OUT;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/10] crypto: omap-aes: Use BIT() macro

2015-07-01 Thread Lokesh Vutla
Use BIT()/GENMASK() macros for all register definitions instead of
hand-writing bit masks.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c |   36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 96fc7f7..d974ab6 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -52,30 +52,30 @@
 #define AES_REG_IV(dd, x)  ((dd)-pdata-iv_ofs + ((x) * 0x04))
 
 #define AES_REG_CTRL(dd)   ((dd)-pdata-ctrl_ofs)
-#define AES_REG_CTRL_CTR_WIDTH_MASK(3  7)
-#define AES_REG_CTRL_CTR_WIDTH_32  (0  7)
-#define AES_REG_CTRL_CTR_WIDTH_64  (1  7)
-#define AES_REG_CTRL_CTR_WIDTH_96  (2  7)
-#define AES_REG_CTRL_CTR_WIDTH_128 (3  7)
-#define AES_REG_CTRL_CTR   (1  6)
-#define AES_REG_CTRL_CBC   (1  5)
-#define AES_REG_CTRL_KEY_SIZE  (3  3)
-#define AES_REG_CTRL_DIRECTION (1  2)
-#define AES_REG_CTRL_INPUT_READY   (1  1)
-#define AES_REG_CTRL_OUTPUT_READY  (1  0)
-#define AES_REG_CTRL_MASK  FLD_MASK(24, 2)
+#define AES_REG_CTRL_CTR_WIDTH_MASKGENMASK(8, 7)
+#define AES_REG_CTRL_CTR_WIDTH_32  0
+#define AES_REG_CTRL_CTR_WIDTH_64  BIT(7)
+#define AES_REG_CTRL_CTR_WIDTH_96  BIT(8)
+#define AES_REG_CTRL_CTR_WIDTH_128 GENMASK(8, 7)
+#define AES_REG_CTRL_CTR   BIT(6)
+#define AES_REG_CTRL_CBC   BIT(5)
+#define AES_REG_CTRL_KEY_SIZE  GENMASK(4, 3)
+#define AES_REG_CTRL_DIRECTION BIT(2)
+#define AES_REG_CTRL_INPUT_READY   BIT(1)
+#define AES_REG_CTRL_OUTPUT_READY  BIT(0)
+#define AES_REG_CTRL_MASK  GENMASK(24, 2)
 
 #define AES_REG_DATA_N(dd, x)  ((dd)-pdata-data_ofs + ((x) * 0x04))
 
 #define AES_REG_REV(dd)((dd)-pdata-rev_ofs)
 
 #define AES_REG_MASK(dd)   ((dd)-pdata-mask_ofs)
-#define AES_REG_MASK_SIDLE (1  6)
-#define AES_REG_MASK_START (1  5)
-#define AES_REG_MASK_DMA_OUT_EN(1  3)
-#define AES_REG_MASK_DMA_IN_EN (1  2)
-#define AES_REG_MASK_SOFTRESET (1  1)
-#define AES_REG_AUTOIDLE   (1  0)
+#define AES_REG_MASK_SIDLE BIT(6)
+#define AES_REG_MASK_START BIT(5)
+#define AES_REG_MASK_DMA_OUT_ENBIT(3)
+#define AES_REG_MASK_DMA_IN_EN BIT(2)
+#define AES_REG_MASK_SOFTRESET BIT(1)
+#define AES_REG_AUTOIDLE   BIT(0)
 
 #define AES_REG_LENGTH_N(x)(0x54 + ((x) * 0x04))
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/10] crypto: omap-aes: gcm: Add support for unaligned lengths

2015-07-01 Thread Lokesh Vutla
Check if the inputs are not aligned, if not process
the input before starting the hw acceleration.
Similarly after completition of hw acceleration.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes-gcm.c |   82 +
 1 file changed, 74 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
index 72815af..9c68ff0 100644
--- a/drivers/crypto/omap-aes-gcm.c
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -48,8 +48,9 @@ static void omap_aes_gcm_finish_req(struct omap_aes_dev *dd, 
int ret)
 
 static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
 {
+   void *buf;
u8 *tag;
-   int alen, clen, i, ret = 0, nsg;
+   int pages, alen, clen, i, ret = 0, nsg;
 
alen = ALIGN(dd-assoc_len, AES_BLOCK_SIZE);
clen = ALIGN(dd-total, AES_BLOCK_SIZE);
@@ -65,10 +66,29 @@ static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
omap_aes_crypt_dma_stop(dd);
}
 
+   if (dd-sgs_copied  AES_OUT_DATA_COPIED) {
+   buf = sg_virt(dd-out_sgl);
+   scatterwalk_map_and_copy(buf, dd-orig_out, 0, dd-total, 1);
+
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
if (dd-flags  FLAGS_ENCRYPT)
scatterwalk_map_and_copy(dd-ctx-auth_tag, dd-aead_req-dst,
 dd-total, dd-authsize, 1);
 
+   if (dd-sgs_copied  AES_ASSOC_DATA_COPIED) {
+   buf = sg_virt(dd-in_sgl[0]);
+   pages = get_order(alen);
+   free_pages((unsigned long)buf, pages);
+   }
+   if (dd-sgs_copied  AES_IN_DATA_COPIED) {
+   buf = sg_virt(dd-in_sgl[nsg - 1]);
+   pages = get_order(clen);
+   free_pages((unsigned long)buf, pages);
+   }
+
if (!(dd-flags  FLAGS_ENCRYPT)) {
tag = (u8 *)dd-ctx-auth_tag;
for (i = 0; i  dd-authsize; i++) {
@@ -87,13 +107,14 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
*dd,
 struct aead_request *req)
 {
void *buf_in;
-   int alen, clen, nsg;
+   int pages, alen, clen, cryptlen, nsg;
struct crypto_aead *aead = crypto_aead_reqtfm(req);
unsigned int authlen = crypto_aead_authsize(aead);
u32 dec = !(dd-flags  FLAGS_ENCRYPT);
 
-   alen = req-assoclen;
-   clen = req-cryptlen - (dec * authlen);
+   alen = ALIGN(req-assoclen, AES_BLOCK_SIZE);
+   cryptlen = req-cryptlen - (dec * authlen);
+   clen = ALIGN(cryptlen, AES_BLOCK_SIZE);
 
dd-sgs_copied = 0;
 
@@ -101,20 +122,65 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
*dd,
 
sg_init_table(dd-in_sgl, nsg);
if (req-assoclen) {
-   buf_in = sg_virt(req-assoc);
+   if (omap_aes_check_aligned(req-assoc, req-assoclen)) {
+   dd-sgs_copied |= AES_ASSOC_DATA_COPIED;
+   pages = get_order(alen);
+   buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
+   if (!buf_in) {
+   pr_err(Couldn't allocate for unaligncases.\n);
+   return -1;
+   }
+
+   scatterwalk_map_and_copy(buf_in, req-assoc, 0,
+req-assoclen, 0);
+   memset(buf_in + req-assoclen, 0, alen - req-assoclen);
+   } else {
+   buf_in = sg_virt(req-assoc);
+   }
sg_set_buf(dd-in_sgl, buf_in, alen);
}
 
if (req-cryptlen) {
-   buf_in = sg_virt(req-src);
+   if (omap_aes_check_aligned(req-src, req-cryptlen)) {
+   dd-sgs_copied |= AES_IN_DATA_COPIED;
+   pages = get_order(clen);
+   buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
+   if (!buf_in) {
+   pr_err(Couldn't allocate for unaligncases.\n);
+   return -1;
+   }
+
+   memset(buf_in + cryptlen, 0, clen - cryptlen);
+   scatterwalk_map_and_copy(buf_in, req-src, 0, cryptlen,
+0);
+   } else {
+   buf_in = sg_virt(req-src);
+   }
sg_set_buf(dd-in_sgl[nsg - 1], buf_in, clen);
}
 
dd-in_sg = dd-in_sgl;
-   dd-total = clen;
+   dd-total = cryptlen;
dd-assoc_len = req-assoclen;
dd-authsize = authlen;
-   dd-out_sg = req-dst;
+
+   if (omap_aes_check_aligned(req-dst, cryptlen)) {
+   pages = get_order(clen);
+
+   buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages

[PATCH 06/10] crypto: omap-aes: gcm: Handle inputs properly

2015-07-01 Thread Lokesh Vutla
Its not necessary that assoc data and plain text is passed always.
Add these checks before processing the input.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes-gcm.c |   26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
index 1be9d91..72815af 100644
--- a/drivers/crypto/omap-aes-gcm.c
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -87,7 +87,7 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,
 struct aead_request *req)
 {
void *buf_in;
-   int alen, clen;
+   int alen, clen, nsg;
struct crypto_aead *aead = crypto_aead_reqtfm(req);
unsigned int authlen = crypto_aead_authsize(aead);
u32 dec = !(dd-flags  FLAGS_ENCRYPT);
@@ -97,12 +97,18 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
*dd,
 
dd-sgs_copied = 0;
 
-   sg_init_table(dd-in_sgl, 2);
-   buf_in = sg_virt(req-assoc);
-   sg_set_buf(dd-in_sgl, buf_in, alen);
+   nsg = 1 + !!(req-assoclen  req-cryptlen);
 
-   buf_in = sg_virt(req-src);
-   sg_set_buf(dd-in_sgl[1], buf_in, clen);
+   sg_init_table(dd-in_sgl, nsg);
+   if (req-assoclen) {
+   buf_in = sg_virt(req-assoc);
+   sg_set_buf(dd-in_sgl, buf_in, alen);
+   }
+
+   if (req-cryptlen) {
+   buf_in = sg_virt(req-src);
+   sg_set_buf(dd-in_sgl[nsg - 1], buf_in, clen);
+   }
 
dd-in_sg = dd-in_sgl;
dd-total = clen;
@@ -258,6 +264,8 @@ static int omap_aes_gcm_crypt(struct aead_request *req, 
unsigned long mode)
 {
struct omap_aes_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct omap_aes_reqctx *rctx = aead_request_ctx(req);
+   struct crypto_aead *aead = crypto_aead_reqtfm(req);
+   unsigned int authlen = crypto_aead_authsize(aead);
struct omap_aes_dev *dd;
__be32 counter = cpu_to_be32(1);
int err;
@@ -270,6 +278,12 @@ static int omap_aes_gcm_crypt(struct aead_request *req, 
unsigned long mode)
if (err)
return err;
 
+   if (req-assoclen + req-cryptlen == 0) {
+   scatterwalk_map_and_copy(ctx-auth_tag, req-dst, 0, authlen,
+1);
+   return 0;
+   }
+
dd = omap_aes_find_dev(ctx);
if (!dd)
return -ENODEV;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/10] crypto: omap-aes: gcm: Add support for PIO mode

2015-07-01 Thread Lokesh Vutla
Add support for PIO mode for GCM mode.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes-gcm.c |   10 ++
 drivers/crypto/omap-aes.c |   24 ++--
 drivers/crypto/omap-aes.h |3 ++-
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
index 9c68ff0..370891b 100644
--- a/drivers/crypto/omap-aes-gcm.c
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -52,8 +52,8 @@ static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
u8 *tag;
int pages, alen, clen, i, ret = 0, nsg;
 
-   alen = ALIGN(dd-assoc_len, AES_BLOCK_SIZE);
-   clen = ALIGN(dd-total, AES_BLOCK_SIZE);
+   alen = ALIGN(dd-assoc_len_save, AES_BLOCK_SIZE);
+   clen = ALIGN(dd-total_save, AES_BLOCK_SIZE);
 
nsg = 1 + !!(dd-assoc_len  dd-total);
 
@@ -161,7 +161,9 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev 
*dd,
 
dd-in_sg = dd-in_sgl;
dd-total = cryptlen;
+   dd-total_save = cryptlen;
dd-assoc_len = req-assoclen;
+   dd-assoc_len_save = req-assoclen;
dd-authsize = authlen;
 
if (omap_aes_check_aligned(req-dst, cryptlen)) {
@@ -248,14 +250,14 @@ static int do_encrypt_iv(struct aead_request *req, u32 
*tag)
return ret;
 }
 
-void omap_aes_gcm_dma_out_callback(void *data)
+void omap_aes_gcm_process_auth_tag(void *data)
 {
struct omap_aes_dev *dd = data;
int i, val;
u32 *auth_tag, tag[4];
 
if (!(dd-flags  FLAGS_ENCRYPT))
-   scatterwalk_map_and_copy(tag, dd-aead_req-src, dd-total,
+   scatterwalk_map_and_copy(tag, dd-aead_req-src, dd-total_save,
 dd-authsize, 0);
 
auth_tag = dd-ctx-auth_tag;
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 11f3850..8aeb913 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -340,7 +340,7 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd,
}
 
if (dd-flags  FLAGS_GCM)
-   tx_out-callback = omap_aes_gcm_dma_out_callback;
+   tx_out-callback = omap_aes_gcm_process_auth_tag;
else
tx_out-callback = omap_aes_dma_out_callback;
tx_out-callback_param = dd;
@@ -927,8 +927,15 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
status = ~AES_REG_IRQ_DATA_IN;
omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
 
-   /* Enable DATA_OUT interrupt */
-   omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
+   /*
+* if GCM mode enable DATA_IN till assoc data is copied
+* else Enable DATA_OUT interrupt
+* */
+   if ((dd-flags  FLAGS_GCM)  dd-assoc_len)
+   dd-assoc_len -= min((size_t)AES_BLOCK_SIZE,
+dd-assoc_len);
+   else
+   omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4);
 
} else if (status  AES_REG_IRQ_DATA_OUT) {
omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0);
@@ -961,12 +968,17 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id)
status = ~AES_REG_IRQ_DATA_OUT;
omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status);
 
-   if (!dd-total)
+   if (!dd-total) {
/* All bytes read! */
-   tasklet_schedule(dd-done_task);
-   else
+   if (dd-flags  FLAGS_GCM)
+   /* Process auth tag and call done_task */
+   omap_aes_gcm_process_auth_tag(dd);
+   else
+   tasklet_schedule(dd-done_task);
+   } else {
/* Enable DATA_IN interrupt for next block */
omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2);
+   }
}
 
return IRQ_HANDLED;
diff --git a/drivers/crypto/omap-aes.h b/drivers/crypto/omap-aes.h
index 0863874..e0621dd 100644
--- a/drivers/crypto/omap-aes.h
+++ b/drivers/crypto/omap-aes.h
@@ -164,6 +164,7 @@ struct omap_aes_dev {
size_t  total;
size_t  total_save;
size_t  assoc_len;
+   size_t  assoc_len_save;
size_t  authsize;
 
struct scatterlist  *in_sg;
@@ -199,7 +200,7 @@ int omap_aes_gcm_decrypt(struct aead_request *req);
 int omap_aes_write_ctrl(struct omap_aes_dev *dd);
 int omap_aes_check_aligned(struct scatterlist *sg, int total);
 int omap_aes_crypt_dma_start(struct omap_aes_dev *dd);
-void omap_aes_gcm_dma_out_callback(void *data);
+void omap_aes_gcm_process_auth_tag(void *data);
 int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd

[PATCH 02/10] crypto: omap-aes: Fix configuring of AES mode

2015-07-01 Thread Lokesh Vutla
AES_CTRL_REG is used to configure AES mode. Before configuring
any mode we need to make sure all other modes are reset or else
driver will misbehave. So mask all modes before configuring
any AES mode.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c |   13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index a923101..96fc7f7 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -63,6 +63,7 @@
 #define AES_REG_CTRL_DIRECTION (1  2)
 #define AES_REG_CTRL_INPUT_READY   (1  1)
 #define AES_REG_CTRL_OUTPUT_READY  (1  0)
+#define AES_REG_CTRL_MASK  FLD_MASK(24, 2)
 
 #define AES_REG_DATA_N(dd, x)  ((dd)-pdata-data_ofs + ((x) * 0x04))
 
@@ -254,7 +255,7 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
 {
unsigned int key32;
int i, err;
-   u32 val, mask = 0;
+   u32 val;
 
err = omap_aes_hw_init(dd);
if (err)
@@ -274,17 +275,13 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
val = FLD_VAL(((dd-ctx-keylen  3) - 1), 4, 3);
if (dd-flags  FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
-   if (dd-flags  FLAGS_CTR) {
+   if (dd-flags  FLAGS_CTR)
val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128;
-   mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK;
-   }
+
if (dd-flags  FLAGS_ENCRYPT)
val |= AES_REG_CTRL_DIRECTION;
 
-   mask |= AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
-   AES_REG_CTRL_KEY_SIZE;
-
-   omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask);
+   omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, AES_REG_CTRL_MASK);
 
return 0;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/10] crypto: omap-aes: Add support for GCM mode

2015-07-01 Thread Lokesh Vutla
This series does some basic cleanup and adds support for
AES GCM mode for omap aes driver.
Also adds a test case for async aead algos.

Tested on BeagelBoneBlack: http://pastebin.ubuntu.com/11808341/

Lokesh Vutla (10):
  crypto: omap-aes: Add support for lengths not aligned with
AES_BLOCK_SIZE
  crypto: omap-aes: Fix configuring of AES mode
  crypto: aead: Add aead_request_cast() api
  crypto: omap-aes: Use BIT() macro
  crypto: omap-aes: Add support for GCM mode
  crypto: omap-aes: gcm: Handle inputs properly
  crypto: omap-aes: gcm: Add support for unaligned lengths
  crypto: omap-aes: gmc: Add algo info
  crypto: omap-aes: gcm: Add support for PIO mode
  crypto: tcrypt: Added speed tests for Async AEAD crypto alogrithms

 crypto/tcrypt.c   |  233 +
 crypto/tcrypt.h   |1 +
 drivers/crypto/Makefile   |3 +-
 drivers/crypto/omap-aes-gcm.c |  386 +
 drivers/crypto/omap-aes.c |  322 +-
 drivers/crypto/omap-aes.h |  206 ++
 include/linux/crypto.h|6 +
 7 files changed, 955 insertions(+), 202 deletions(-)
 create mode 100644 drivers/crypto/omap-aes-gcm.c
 create mode 100644 drivers/crypto/omap-aes.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] crypto: omap-sham: Add the offset of sg page to vaddr

2015-04-02 Thread Lokesh Vutla
kmap_atomic() gives only the page address of the input page.
Driver should take care of adding the offset of the scatterlist
within the page to the returned page address.
omap-sham driver is not adding the offset to page and directly operates
on the return vale of kmap_atomic(), because of which the following
error comes when running crypto tests:

: d9 a1 1b 7c aa 90 3b aa 11 ab cb 25 00 b8 ac bf
[2.338169] 0010: c1 39 cd ff 48 d0 a8 e2 2b fa 33 a1
[2.344008] alg: hash: Chunking test 1 failed for omap-sha256

So adding the scatterlist offset to vaddr.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
- Tested on BBB. Logs below.
Without this patch: http://pastebin.ubuntu.com/10722994/
With this patch: http://pastebin.ubuntu.com/10722992/
 drivers/crypto/omap-sham.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 21fd515..4d63e0d 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -640,6 +640,7 @@ static size_t omap_sham_append_sg(struct omap_sham_reqctx 
*ctx)
 
while (ctx-sg) {
vaddr = kmap_atomic(sg_page(ctx-sg));
+   vaddr += ctx-sg-offset;
 
count = omap_sham_append_buffer(ctx,
vaddr + ctx-offset,
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: omap-sham: Check for HIGHMEM before mapping SG pages

2015-04-02 Thread Lokesh Vutla
Hi Herbert,
On Wednesday 01 April 2015 07:48 PM, Herbert Xu wrote:
 On Tue, Mar 31, 2015 at 09:52:23AM +0530, Lokesh Vutla wrote:
 Commit 26a05489ee0e (crypto: omap-sham - Map SG pages if they are HIGHMEM 
 before accessing)
 says that HIGHMEM pages may not be mapped so we must
 kmap them before accessing, but it doesn't check whether the
 corresponding page is in highmem or not. Because of this all
 the crypto tests are failing.

 : d9 a1 1b 7c aa 90 3b aa 11 ab cb 25 00 b8 ac bf
 [2.338169] 0010: c1 39 cd ff 48 d0 a8 e2 2b fa 33 a1
 [2.344008] alg: hash: Chunking test 1 failed for omap-sha256

 So Checking for HIGHMEM before mapping SG pages.

 Fixes: 26a05489ee0 (crypto: omap-sham - Map SG pages if they are HIGHMEM 
 before accessing)
 Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
 ---
  drivers/crypto/omap-sham.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

 diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
 index 3c76696..ace5852 100644
 --- a/drivers/crypto/omap-sham.c
 +++ b/drivers/crypto/omap-sham.c
 @@ -639,13 +639,17 @@ static size_t omap_sham_append_sg(struct 
 omap_sham_reqctx *ctx)
  const u8 *vaddr;
  
  while (ctx-sg) {
 -vaddr = kmap_atomic(sg_page(ctx-sg));
 +if (PageHighMem(sg_page(ctx-sg)))
 +vaddr = kmap_atomic(sg_page(ctx-sg));
 +else
 +vaddr = sg_virt(ctx-sg);
 
 This is completely bogus.  kmap_atomic should be identical to
 sg_virt(sg_page()) for the lowmem case.
 
 So either your architecture is broken (because the same problem
 would obviously affect the core crypto code which does exactly
 the same thing), or there is some other bug causing the selftest
 to fail.
Oops my bad. You are right.
Here the problem is sg-offset is not being added to vaddr.
sg_virt gives page address + sg-offset but
kmap_atomic gives only the page address.

Ill update and repost the patch.

Thanks and regards,
Lokesh
 
 Cheers,
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: omap-sham: Check for HIGHMEM before mapping SG pages

2015-03-30 Thread Lokesh Vutla
Commit 26a05489ee0e (crypto: omap-sham - Map SG pages if they are HIGHMEM 
before accessing)
says that HIGHMEM pages may not be mapped so we must
kmap them before accessing, but it doesn't check whether the
corresponding page is in highmem or not. Because of this all
the crypto tests are failing.

: d9 a1 1b 7c aa 90 3b aa 11 ab cb 25 00 b8 ac bf
[2.338169] 0010: c1 39 cd ff 48 d0 a8 e2 2b fa 33 a1
[2.344008] alg: hash: Chunking test 1 failed for omap-sha256

So Checking for HIGHMEM before mapping SG pages.

Fixes: 26a05489ee0 (crypto: omap-sham - Map SG pages if they are HIGHMEM 
before accessing)
Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 3c76696..ace5852 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -639,13 +639,17 @@ static size_t omap_sham_append_sg(struct omap_sham_reqctx 
*ctx)
const u8 *vaddr;
 
while (ctx-sg) {
-   vaddr = kmap_atomic(sg_page(ctx-sg));
+   if (PageHighMem(sg_page(ctx-sg)))
+   vaddr = kmap_atomic(sg_page(ctx-sg));
+   else
+   vaddr = sg_virt(ctx-sg);
 
count = omap_sham_append_buffer(ctx,
vaddr + ctx-offset,
ctx-sg-length - ctx-offset);
 
-   kunmap_atomic((void *)vaddr);
+   if (PageHighMem(sg_page(ctx-sg)))
+   kunmap_atomic((void *)vaddr);
 
if (!count)
break;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: omap-aes: Fix support for unequal lengths

2015-03-30 Thread Lokesh Vutla
For cases where total length of an input SGs is not same as
length of the input data for encryption, omap-aes driver
crashes. This happens in the case when IPsec is trying to use
omap-aes driver.

To avoid this, we copy all the pages from the input SG list
into a contiguous buffer and prepare a single element SG list
for this buffer with length as the total bytes to crypt, which is
similar thing that is done in case of unaligned lengths.

Fixes: 6242332ff2f3 (crypto: omap-aes - Add support for cases of unaligned 
lengths)
Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-aes.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 42f95a4..9a28b7e 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -554,15 +554,23 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev 
*dd)
return err;
 }
 
-static int omap_aes_check_aligned(struct scatterlist *sg)
+static int omap_aes_check_aligned(struct scatterlist *sg, int total)
 {
+   int len = 0;
+
while (sg) {
if (!IS_ALIGNED(sg-offset, 4))
return -1;
if (!IS_ALIGNED(sg-length, AES_BLOCK_SIZE))
return -1;
+
+   len += sg-length;
sg = sg_next(sg);
}
+
+   if (len != total)
+   return -1;
+
return 0;
 }
 
@@ -633,8 +641,8 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
dd-in_sg = req-src;
dd-out_sg = req-dst;
 
-   if (omap_aes_check_aligned(dd-in_sg) ||
-   omap_aes_check_aligned(dd-out_sg)) {
+   if (omap_aes_check_aligned(dd-in_sg, dd-total) ||
+   omap_aes_check_aligned(dd-out_sg, dd-total)) {
if (omap_aes_copy_sgs(dd))
pr_err(Failed to copy SGs for unaligned cases\n);
dd-sgs_copied = 1;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: omap-sham: Use pm_runtime_irq_safe()

2015-03-30 Thread Lokesh Vutla
omap_sham_handle_queue() can be called as part of done_task tasklet.
During this its atomic and any calls to pm functions cannot sleep.

But there is a call to pm_runtime_get_sync() (which can sleep) in
omap_sham_handle_queue(), because of which the following appears:
 [  116.169969] BUG: scheduling while atomic: kworker/0:2/2676/0x0100

Add pm_runtime_irq_safe() to avoid this.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index ace5852..81ed511 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -1949,6 +1949,7 @@ static int omap_sham_probe(struct platform_device *pdev)
dd-flags |= dd-pdata-flags;
 
pm_runtime_enable(dev);
+   pm_runtime_irq_safe(dev);
pm_runtime_get_sync(dev);
rev = omap_sham_read(dd, SHA_REG_REV(dd));
pm_runtime_put_sync(pdev-dev);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] omap-rng: Change RNG_CONFIG_REG to RNG_CONTROL_REG when, checking and disabling TRNG

2015-03-22 Thread Lokesh Vutla
Hi Andre,
On Friday 20 February 2015 10:07 AM, Andre Wolokita wrote:
 In omap4_rng_init(), a check of bit 10 of the RNG_CONFIG_REG is done to 
 determine
 whether the RNG is running. This is suspicious firstly due to the use of
 RNG_CONTROL_ENABLE_TRNG_MASK and secondly because the same mask is written to
 RNG_CONTROL_REG after configuration of the FROs. Similar suspicious logic is
 repeated in omap4_rng_cleanup() when RNG_CONTROL_REG masked with
 RNG_CONTROL_ENABLE_TRNG_MASK is read, the same mask bit is cleared, and then
 written to RNG_CONFIG_REG. Unless the TRNG is enabled with one bit in 
 RNG_CONTROL
 and disabled with another in RNG_CONFIG and these bits are mirrored in some 
 way,
 I believe that the TRNG is not really shutting off, leaving the FROs running
 indefinitely which, in an extreme case, could lead to degredation of the
 hardware and potentially reduce the level of entropy generated.
Yes you are correct. Patch looks good to me.
It should be RNG_CONTROL_REG

Acked-by: Lokesh Vutla lokeshvu...@ti.com

Thanks and regards,
Lokesh

 
 Apart from the strange logic, I have reason to suspect that the OMAP4 related
 code in this driver is driving an Inside Secure IP hardware RNG and strongly
 suspect that bit 10 of RNG_CONFIG_REG is one of the bits configuring the
 sampling rate of the FROs. This option is by default set to 0 and is not being
 set anywhere in omap-rng.c. Reading this bit during omap4_rng_init() will
 always return 0. It will remain 0 because ~(value of TRNG_MASK in control) 
 will
 always be 0, because the TRNG is never shut off. This is of course presuming
 that the OMAP4 features the Inside Secure IP, which I strongly suspect.
 
 I'm interested in knowing what the guys at TI think about this, as only they
 can confirm or deny the detailed structure of these registers.
 
 Signed-off-by: Andre Wolokita andre.wolok...@analog.com
 ---
  drivers/char/hw_random/omap-rng.c |4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/char/hw_random/omap-rng.c 
 b/drivers/char/hw_random/omap-rng.c
 index d14dcf7..67151cb 100644
 --- a/drivers/char/hw_random/omap-rng.c
 +++ b/drivers/char/hw_random/omap-rng.c
 @@ -236,7 +236,7 @@ static int omap4_rng_init(struct omap_rng_dev *priv)
 u32 val;
 
 /* Return if RNG is already running. */
 -   if (omap_rng_read(priv, RNG_CONFIG_REG)  
 RNG_CONTROL_ENABLE_TRNG_MASK)
 +   if (omap_rng_read(priv, RNG_CONTROL_REG)  
 RNG_CONTROL_ENABLE_TRNG_MASK)
 return 0;
 
 val = RNG_CONFIG_MIN_REFIL_CYCLES  
 RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
 @@ -262,7 +262,7 @@ static void omap4_rng_cleanup(struct omap_rng_dev *priv)
 
 val = omap_rng_read(priv, RNG_CONTROL_REG);
 val = ~RNG_CONTROL_ENABLE_TRNG_MASK;
 -   omap_rng_write(priv, RNG_CONFIG_REG, val);
 +   omap_rng_write(priv, RNG_CONTROL_REG, val);
  }
 
  static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 04/14] crypto: omap-aes: Simplify DMA usage by using direct SGs

2013-08-20 Thread Lokesh Vutla
Hi Joel,

On Sunday 18 August 2013 08:12 AM, Joel Fernandes wrote:
 In early version of this driver, assumptions were made such as DMA layer
 requires contiguous buffers etc. Due to this, new buffers were allocated,
 mapped and used for DMA. These assumptions are no longer true and DMAEngine
 scatter-gather DMA doesn't have such requirements. We simply the DMA 
 operations
 by directly using the scatter-gather buffers provided by the crypto layer
 instead of creating our own.
 
 Lot of logic that handled DMA'ing only X number of bytes of the total, or as
 much as fitted into a 3rd party buffer is removed and is no longer required.
 
 Also, good performance improvement of atleast ~20% seen with encrypting a
 buffer size of 8K (1800 ops/sec vs 1400 ops/sec).  Improvement will be higher
 for much larger blocks though such benchmarking is left as an exercise for the
 reader.  Also DMA usage is much more simplified and coherent with rest of the
 code.
 
 Signed-off-by: Joel Fernandes jo...@ti.com
 ---
  drivers/crypto/omap-aes.c |  147 
 -
  1 file changed, 25 insertions(+), 122 deletions(-)
 
 diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
 index e369e6e..64dd5c1 100644
 --- a/drivers/crypto/omap-aes.c
 +++ b/drivers/crypto/omap-aes.c
 @@ -480,22 +480,14 @@ static int sg_copy(struct scatterlist **sg, size_t 
 *offset, void *buf,
  }
  
  static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
 - struct scatterlist *in_sg, struct scatterlist *out_sg)
 + struct scatterlist *in_sg, struct scatterlist *out_sg,
 + int in_sg_len, int out_sg_len)
  {
   struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
   struct omap_aes_dev *dd = ctx-dd;
   struct dma_async_tx_descriptor *tx_in, *tx_out;
   struct dma_slave_config cfg;
 - dma_addr_t dma_addr_in = sg_dma_address(in_sg);
 - int ret, length = sg_dma_len(in_sg);
 -
 - pr_debug(len: %d\n, length);
 -
 - dd-dma_size = length;
 -
 - if (!(dd-flags  FLAGS_FAST))
 - dma_sync_single_for_device(dd-dev, dma_addr_in, length,
 -DMA_TO_DEVICE);
 + int ret;
By this change FLAGS_FAST is unsed, it can be cleaned right?
or Am I missing something?

Thanks and regards,
Lokesh
  
   memset(cfg, 0, sizeof(cfg));
  
 @@ -514,7 +506,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
   return ret;
   }
  
 - tx_in = dmaengine_prep_slave_sg(dd-dma_lch_in, in_sg, 1,
 + tx_in = dmaengine_prep_slave_sg(dd-dma_lch_in, in_sg, in_sg_len,
   DMA_MEM_TO_DEV,
   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
   if (!tx_in) {
 @@ -533,7 +525,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
   return ret;
   }
  
 - tx_out = dmaengine_prep_slave_sg(dd-dma_lch_out, out_sg, 1,
 + tx_out = dmaengine_prep_slave_sg(dd-dma_lch_out, out_sg, out_sg_len,
   DMA_DEV_TO_MEM,
   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
   if (!tx_out) {
 @@ -551,7 +543,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
   dma_async_issue_pending(dd-dma_lch_out);
  
   /* start DMA */
 - dd-pdata-trigger(dd, length);
 + dd-pdata-trigger(dd, dd-total);
  
   return 0;
  }
 @@ -560,93 +552,28 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev 
 *dd)
  {
   struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
   crypto_ablkcipher_reqtfm(dd-req));
 - int err, fast = 0, in, out;
 - size_t count;
 - dma_addr_t addr_in, addr_out;
 - struct scatterlist *in_sg, *out_sg;
 - int len32;
 + int err;
  
   pr_debug(total: %d\n, dd-total);
  
 - if (sg_is_last(dd-in_sg)  sg_is_last(dd-out_sg)) {
 - /* check for alignment */
 - in = IS_ALIGNED((u32)dd-in_sg-offset, sizeof(u32));
 - out = IS_ALIGNED((u32)dd-out_sg-offset, sizeof(u32));
 -
 - fast = in  out;
 + err = dma_map_sg(dd-dev, dd-in_sg, dd-in_sg_len, DMA_TO_DEVICE);
 + if (!err) {
 + dev_err(dd-dev, dma_map_sg() error\n);
 + return -EINVAL;
   }
  
 - if (fast)  {
 - count = min(dd-total, sg_dma_len(dd-in_sg));
 - count = min(count, sg_dma_len(dd-out_sg));
 -
 - if (count != dd-total) {
 - pr_err(request length != buffer length\n);
 - return -EINVAL;
 - }
 -
 - pr_debug(fast\n);
 -
 - err = dma_map_sg(dd-dev, dd-in_sg, 1, DMA_TO_DEVICE);
 - if (!err) {
 - dev_err(dd-dev, dma_map_sg() error\n);
 - return -EINVAL;
 - }
 -
 - err = dma_map_sg(dd-dev, dd-out_sg, 1, DMA_FROM_DEVICE);
 - if (!err) {
 - 

[PATCH 1/2] crypto: omap-sham: Enable Polling mode if DMA fails

2013-08-20 Thread Lokesh Vutla
For writing input buffer into DATA_IN register current driver
has the following state machine:
- if input buffer  9 : use fallback driver
- else if input buffer  block size : Copy input buffer into data_in regs
- else use dma transfer.

In cases where requesting for DMA channels fails for some reason,
or channel numbers are not provided in DT or platform data, probe
also fails. Instead of returning from driver use cpu polling mode.
In this mode processor polls on INPUT_READY bit and writes data into
data_in regs when it equals 1. This operation is repeated until the
length of message.

Now the state machine looks like:
- if input buffer  9 : use fallback driver
- else if input buffer  block size : Copy input buffer into data_in regs
- else if dma enabled: use dma transfer
   else use cpu polling mode.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c |   61 ++--
 1 file changed, 42 insertions(+), 19 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index ae1ca8b2..0a2bd16 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -225,6 +225,7 @@ struct omap_sham_dev {
unsigned intdma;
struct dma_chan *dma_lch;
struct tasklet_struct   done_task;
+   u8  polling_mode;
 
unsigned long   flags;
struct crypto_queue queue;
@@ -510,7 +511,7 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, 
const u8 *buf,
  size_t length, int final)
 {
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd-req);
-   int count, len32;
+   int count, len32, bs32, offset = 0;
const u32 *buffer = (const u32 *)buf;
 
dev_dbg(dd-dev, xmit_cpu: digcnt: %d, length: %d, final: %d\n,
@@ -522,18 +523,23 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, 
const u8 *buf,
/* should be non-zero before next lines to disable clocks later */
ctx-digcnt += length;
 
-   if (dd-pdata-poll_irq(dd))
-   return -ETIMEDOUT;
-
if (final)
set_bit(FLAGS_FINAL, dd-flags); /* catch last interrupt */
 
set_bit(FLAGS_CPU, dd-flags);
 
len32 = DIV_ROUND_UP(length, sizeof(u32));
+   bs32 = get_block_size(ctx) / sizeof(u32);
+
+   while (len32) {
+   if (dd-pdata-poll_irq(dd))
+   return -ETIMEDOUT;
 
-   for (count = 0; count  len32; count++)
-   omap_sham_write(dd, SHA_REG_DIN(dd, count), buffer[count]);
+   for (count = 0; count  min(len32, bs32); count++, offset++)
+   omap_sham_write(dd, SHA_REG_DIN(dd, count),
+   buffer[offset]);
+   len32 -= min(len32, bs32);
+   }
 
return -EINPROGRESS;
 }
@@ -774,13 +780,22 @@ static int omap_sham_update_dma_start(struct 
omap_sham_dev *dd)
 static int omap_sham_update_cpu(struct omap_sham_dev *dd)
 {
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd-req);
-   int bufcnt;
+   int bufcnt, final;
+
+   if (!ctx-total)
+   return 0;
 
omap_sham_append_sg(ctx);
+
+   final = (ctx-flags  BIT(FLAGS_FINUP))  !ctx-total;
+
+   dev_dbg(dd-dev, cpu: bufcnt: %u, digcnt: %d, final: %d\n,
+   ctx-bufcnt, ctx-digcnt, final);
+
bufcnt = ctx-bufcnt;
ctx-bufcnt = 0;
 
-   return omap_sham_xmit_cpu(dd, ctx-buffer, bufcnt, 1);
+   return omap_sham_xmit_cpu(dd, ctx-buffer, bufcnt, final);
 }
 
 static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
@@ -903,8 +918,11 @@ static int omap_sham_final_req(struct omap_sham_dev *dd)
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
int err = 0, use_dma = 1;
 
-   if (ctx-bufcnt = DMA_MIN)
-   /* faster to handle last block with cpu */
+   if ((ctx-bufcnt = get_block_size(ctx)) || dd-polling_mode)
+   /*
+* faster to handle last block with cpu or
+* use cpu when dma is not present.
+*/
use_dma = 0;
 
if (use_dma)
@@ -1056,6 +1074,7 @@ static int omap_sham_enqueue(struct ahash_request *req, 
unsigned int op)
 static int omap_sham_update(struct ahash_request *req)
 {
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
+   struct omap_sham_dev *dd = ctx-dd;
int bs = get_block_size(ctx);
 
if (!req-nbytes)
@@ -1074,10 +1093,12 @@ static int omap_sham_update(struct ahash_request *req)
*/
omap_sham_append_sg(ctx);
return 0;
-   } else if (ctx-bufcnt + ctx-total = bs) {
+   } else if ((ctx-bufcnt + ctx-total = bs) ||
+  dd-polling_mode) {
/*
-   * faster to use CPU for short transfers

[PATCH 0/2] crypto: omap-sham: Misc updates for driver

2013-08-20 Thread Lokesh Vutla
This patch series updates the following for the driver:
- Enable polling mode if DMA fails.
- Correct the DMA burst size.

Lokesh Vutla (2):
  crypto: omap-sham: Enable Polling mode if DMA fails
  crypto: omap-sham: correct dma burst size

 drivers/crypto/omap-sham.c |   72 
 1 file changed, 46 insertions(+), 26 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] crypto: omap-sham: correct dma burst size

2013-08-20 Thread Lokesh Vutla
Each cycle of SHA512 operates on 32 data words where as
SHA256 operates on 16 data words. This needs to be updated
while configuring DMA channels. Doing the same.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c |   11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 0a2bd16..8bdde57 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -46,9 +46,6 @@
 
 #define MD5_DIGEST_SIZE16
 
-#define DST_MAXBURST   16
-#define DMA_MIN(DST_MAXBURST * sizeof(u32))
-
 #define SHA_REG_IDIGEST(dd, x) ((dd)-pdata-idigest_ofs + ((x)*0x04))
 #define SHA_REG_DIN(dd, x) ((dd)-pdata-din_ofs + ((x) * 0x04))
 #define SHA_REG_DIGCNT(dd) ((dd)-pdata-digcnt_ofs)
@@ -558,7 +555,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, 
dma_addr_t dma_addr,
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd-req);
struct dma_async_tx_descriptor *tx;
struct dma_slave_config cfg;
-   int len32, ret;
+   int len32, ret, dma_min = get_block_size(ctx);
 
dev_dbg(dd-dev, xmit_dma: digcnt: %d, length: %d, final: %d\n,
ctx-digcnt, length, final);
@@ -567,7 +564,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, 
dma_addr_t dma_addr,
 
cfg.dst_addr = dd-phys_base + SHA_REG_DIN(dd, 0);
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-   cfg.dst_maxburst = DST_MAXBURST;
+   cfg.dst_maxburst = dma_min / DMA_SLAVE_BUSWIDTH_4_BYTES;
 
ret = dmaengine_slave_config(dd-dma_lch, cfg);
if (ret) {
@@ -575,7 +572,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, 
dma_addr_t dma_addr,
return ret;
}
 
-   len32 = DIV_ROUND_UP(length, DMA_MIN) * DMA_MIN;
+   len32 = DIV_ROUND_UP(length, dma_min) * dma_min;
 
if (is_sg) {
/*
@@ -729,7 +726,7 @@ static int omap_sham_update_dma_start(struct omap_sham_dev 
*dd)
 * the dmaengine infrastructure will calculate that it needs
 * to transfer 0 frames which ultimately fails.
 */
-   if (ctx-total  (DST_MAXBURST * sizeof(u32)))
+   if (ctx-total  get_block_size(ctx))
return omap_sham_update_dma_slow(dd);
 
dev_dbg(dd-dev, fast: digcnt: %d, bufcnt: %u, total: %u\n,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] hwrng: reorder OMAP TRNG driver code

2013-08-20 Thread Lokesh Vutla
Hi Olof,
On Tuesday 20 August 2013 11:37 PM, Olof Johansson wrote:
 The newly added omap4 support in the driver was added without
 consideration for building older configs. When building omap1_defconfig,
 it resulted in:
 
 drivers/char/hw_random/omap-rng.c:190:12: warning: 'omap4_rng_init' defined 
 but not used [-Wunused-function]
 drivers/char/hw_random/omap-rng.c:215:13: warning: 'omap4_rng_cleanup' 
 defined but not used [-Wunused-function]
 drivers/char/hw_random/omap-rng.c:251:20: warning: 'omap4_rng_irq' defined 
 but not used [-Wunused-function]
 
 Move the code around so it is grouped with its operations struct, which
 for the omap4 case means also under the #ifdef CONFIG_OF, where it needs
 to be.
 
Missed testing this. Thanks for the patch.
Reviewed-by: Lokesh Vutla lokeshvu...@ti.com

Regards,
Lokesh

 Signed-off-by: Olof Johansson o...@lixom.net
 Cc: Lokesh Vutla lokeshvu...@ti.com
 ---
  drivers/char/hw_random/omap-rng.c |  108 
 ++---
  1 file changed, 54 insertions(+), 54 deletions(-)
 
 diff --git a/drivers/char/hw_random/omap-rng.c 
 b/drivers/char/hw_random/omap-rng.c
 index f3f7142..9b89ff4 100644
 --- a/drivers/char/hw_random/omap-rng.c
 +++ b/drivers/char/hw_random/omap-rng.c
 @@ -140,16 +140,6 @@ static inline void omap_rng_write(struct omap_rng_dev 
 *priv, u16 reg,
   __raw_writel(val, priv-base + priv-pdata-regs[reg]);
  }
  
 -static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv)
 -{
 - return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1;
 -}
 -
 -static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
 -{
 - return omap_rng_read(priv, RNG_STATUS_REG)  RNG_REG_STATUS_RDY;
 -}
 -
  static int omap_rng_data_present(struct hwrng *rng, int wait)
  {
   struct omap_rng_dev *priv;
 @@ -187,6 +177,60 @@ static int omap_rng_data_read(struct hwrng *rng, u32 
 *data)
   return data_size;
  }
  
 +static int omap_rng_init(struct hwrng *rng)
 +{
 + struct omap_rng_dev *priv;
 +
 + priv = (struct omap_rng_dev *)rng-priv;
 + return priv-pdata-init(priv);
 +}
 +
 +static void omap_rng_cleanup(struct hwrng *rng)
 +{
 + struct omap_rng_dev *priv;
 +
 + priv = (struct omap_rng_dev *)rng-priv;
 + priv-pdata-cleanup(priv);
 +}
 +
 +static struct hwrng omap_rng_ops = {
 + .name   = omap,
 + .data_present   = omap_rng_data_present,
 + .data_read  = omap_rng_data_read,
 + .init   = omap_rng_init,
 + .cleanup= omap_rng_cleanup,
 +};
 +
 +static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv)
 +{
 + return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1;
 +}
 +
 +static int omap2_rng_init(struct omap_rng_dev *priv)
 +{
 + omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1);
 + return 0;
 +}
 +
 +static void omap2_rng_cleanup(struct omap_rng_dev *priv)
 +{
 + omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0);
 +}
 +
 +static struct omap_rng_pdata omap2_rng_pdata = {
 + .regs   = (u16 *)reg_map_omap2,
 + .data_size  = OMAP2_RNG_OUTPUT_SIZE,
 + .data_present   = omap2_rng_data_present,
 + .init   = omap2_rng_init,
 + .cleanup= omap2_rng_cleanup,
 +};
 +
 +#if defined(CONFIG_OF)
 +static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
 +{
 + return omap_rng_read(priv, RNG_STATUS_REG)  RNG_REG_STATUS_RDY;
 +}
 +
  static int omap4_rng_init(struct omap_rng_dev *priv)
  {
   u32 val;
 @@ -221,33 +265,6 @@ static void omap4_rng_cleanup(struct omap_rng_dev *priv)
   omap_rng_write(priv, RNG_CONFIG_REG, val);
  }
  
 -static int omap2_rng_init(struct omap_rng_dev *priv)
 -{
 - omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1);
 - return 0;
 -}
 -
 -static void omap2_rng_cleanup(struct omap_rng_dev *priv)
 -{
 - omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0);
 -}
 -
 -static int omap_rng_init(struct hwrng *rng)
 -{
 - struct omap_rng_dev *priv;
 -
 - priv = (struct omap_rng_dev *)rng-priv;
 - return priv-pdata-init(priv);
 -}
 -
 -static void omap_rng_cleanup(struct hwrng *rng)
 -{
 - struct omap_rng_dev *priv;
 -
 - priv = (struct omap_rng_dev *)rng-priv;
 - priv-pdata-cleanup(priv);
 -}
 -
  static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
  {
   struct omap_rng_dev *priv = dev_id;
 @@ -275,23 +292,6 @@ static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
   return IRQ_HANDLED;
  }
  
 -static struct hwrng omap_rng_ops = {
 - .name   = omap,
 - .data_present   = omap_rng_data_present,
 - .data_read  = omap_rng_data_read,
 - .init   = omap_rng_init,
 - .cleanup= omap_rng_cleanup,
 -};
 -
 -static struct omap_rng_pdata omap2_rng_pdata = {
 - .regs   = (u16 *)reg_map_omap2,
 - .data_size  = OMAP2_RNG_OUTPUT_SIZE,
 - .data_present   = omap2_rng_data_present,
 - .init   = omap2_rng_init,
 - .cleanup= omap2_rng_cleanup,
 -};
 -
 -#if defined

[PATCH 5/6] ARM: OMAP2+: Only manually add hwmod data when DT not used.

2013-08-05 Thread Lokesh Vutla
The omap_init_rng() routine in devices.c only needs to be
called when there is no device tree present.

Cc: Tony Lindgren t...@atomide.com
Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 arch/arm/mach-omap2/devices.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 3c1279f..afc2017 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -570,12 +570,12 @@ static int __init omap2_init_devices(void)
omap_init_mcspi();
omap_init_sham();
omap_init_aes();
+   omap_init_rng();
} else {
/* These can be removed when bindings are done */
omap_init_wl12xx_of();
}
omap_init_sti();
-   omap_init_rng();
omap_init_vout();
 
return 0;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/6] hwrng: OMAP: Add device tree support

2013-08-05 Thread Lokesh Vutla
Add Device Tree suport to the omap-rng driver.
Currently, only support for OMAP2 and OMAP3 is
being added but support for OMAP4 and OMAP5 will
be added in a subsequent patch.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/char/hw_random/omap-rng.c |   12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/char/hw_random/omap-rng.c 
b/drivers/char/hw_random/omap-rng.c
index 5a2ab3b..3076c9d 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -24,6 +24,9 @@
 #include linux/delay.h
 #include linux/slab.h
 #include linux/pm_runtime.h
+#include linux/of.h
+#include linux/of_device.h
+#include linux/of_address.h
 
 #include asm/io.h
 
@@ -104,6 +107,14 @@ static struct hwrng omap_rng_ops = {
.data_read  = omap_rng_data_read,
 };
 
+#if defined(CONFIG_OF)
+static const struct of_device_id omap_rng_of_match[] = {
+   { .compatible = ti,omap2-rng },
+   {},
+};
+MODULE_DEVICE_TABLE(of, omap_rng_of_match);
+#endif
+
 static int omap_rng_probe(struct platform_device *pdev)
 {
struct omap_rng_private_data *priv;
@@ -197,6 +208,7 @@ static struct platform_driver omap_rng_driver = {
.name   = omap_rng,
.owner  = THIS_MODULE,
.pm = OMAP_RNG_PM,
+   .of_match_table = of_match_ptr(omap_rng_of_match),
},
.probe  = omap_rng_probe,
.remove = __exit_p(omap_rng_remove),
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] hwrng: OMAP: Use module_platform_driver macro

2013-08-05 Thread Lokesh Vutla
module_platform_driver() makes the code simpler.
Using the macro in the driver.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/char/hw_random/omap-rng.c |   18 ++
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/char/hw_random/omap-rng.c 
b/drivers/char/hw_random/omap-rng.c
index 6843ec8..3e9a7ec 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -198,9 +198,6 @@ static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, 
omap_rng_resume);
 
 #endif
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS(platform:omap_rng);
-
 static struct platform_driver omap_rng_driver = {
.driver = {
.name   = omap_rng,
@@ -211,18 +208,7 @@ static struct platform_driver omap_rng_driver = {
.remove = __exit_p(omap_rng_remove),
 };
 
-static int __init omap_rng_init(void)
-{
-   return platform_driver_register(omap_rng_driver);
-}
-
-static void __exit omap_rng_exit(void)
-{
-   platform_driver_unregister(omap_rng_driver);
-}
-
-module_init(omap_rng_init);
-module_exit(omap_rng_exit);
-
+module_platform_driver(omap_rng_driver);
+MODULE_ALIAS(platform:omap_rng);
 MODULE_AUTHOR(Deepak Saxena (and others));
 MODULE_LICENSE(GPL);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/6] hwrng: OMAP: Add OMAP4 TRNG support

2013-08-05 Thread Lokesh Vutla
Add support for OMAP4 version of TRNG module
that is present on OMAP4, AM33xx and OMAP5 SoCs.

The modules have several differences including register
offsets, output size, triggering rng and how configuring
FROs. To handle these differences, a platform_data structure
is defined and contains routine pointers, register offsets. OMAP2
specific routines are prefixed with 'omap2_' and OMAP4
specific routines are prefixed with 'omap4_'.

Note: Few Hard coded values are from the TI AM33xx SDK.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/char/hw_random/Kconfig|6 +-
 drivers/char/hw_random/omap-rng.c |  352 +++--
 2 files changed, 305 insertions(+), 53 deletions(-)

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 40a8654..0aa9d91 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -153,12 +153,12 @@ config HW_RANDOM_IXP4XX
 
 config HW_RANDOM_OMAP
tristate OMAP Random Number Generator support
-   depends on HW_RANDOM  (ARCH_OMAP16XX || ARCH_OMAP2)
+   depends on HW_RANDOM  (ARCH_OMAP16XX || ARCH_OMAP2PLUS)
default HW_RANDOM
---help---
  This driver provides kernel-side support for the Random Number
- Generator hardware found on OMAP16xx and OMAP24xx multimedia
- processors.
+ Generator hardware found on OMAP16xx, OMAP2/3/4/5 and AM33xx/AM43xx
+ multimedia processors.
 
  To compile this driver as a module, choose M here: the
  module will be called omap-rng.
diff --git a/drivers/char/hw_random/omap-rng.c 
b/drivers/char/hw_random/omap-rng.c
index 3076c9d..f3f7142 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -27,57 +27,138 @@
 #include linux/of.h
 #include linux/of_device.h
 #include linux/of_address.h
+#include linux/interrupt.h
 
 #include asm/io.h
 
-#define RNG_OUT_REG0x00/* Output register */
-#define RNG_STAT_REG   0x04/* Status register
-   [0] = STAT_BUSY */
-#define RNG_ALARM_REG  0x24/* Alarm register
-   [7:0] = ALARM_COUNTER */
-#define RNG_CONFIG_REG 0x28/* Configuration register
-   [11:6] = RESET_COUNT
-   [5:3]  = RING2_DELAY
-   [2:0]  = RING1_DELAY */
-#define RNG_REV_REG0x3c/* Revision register
-   [7:0] = REV_NB */
-#define RNG_MASK_REG   0x40/* Mask and reset register
-   [2] = IT_EN
-   [1] = SOFTRESET
-   [0] = AUTOIDLE */
-#define RNG_SYSSTATUS  0x44/* System status
-   [0] = RESETDONE */
+#define RNG_REG_STATUS_RDY (1  0)
+
+#define RNG_REG_INTACK_RDY_MASK(1  0)
+#define RNG_REG_INTACK_SHUTDOWN_OFLO_MASK  (1  1)
+#define RNG_SHUTDOWN_OFLO_MASK (1  1)
+
+#define RNG_CONTROL_STARTUP_CYCLES_SHIFT   16
+#define RNG_CONTROL_STARTUP_CYCLES_MASK(0x  16)
+#define RNG_CONTROL_ENABLE_TRNG_SHIFT  10
+#define RNG_CONTROL_ENABLE_TRNG_MASK   (1  10)
+
+#define RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT  16
+#define RNG_CONFIG_MAX_REFIL_CYCLES_MASK   (0x  16)
+#define RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT  0
+#define RNG_CONFIG_MIN_REFIL_CYCLES_MASK   (0xff  0)
+
+#define RNG_CONTROL_STARTUP_CYCLES 0xff
+#define RNG_CONFIG_MIN_REFIL_CYCLES0x21
+#define RNG_CONFIG_MAX_REFIL_CYCLES0x22
+
+#define RNG_ALARMCNT_ALARM_TH_SHIFT0x0
+#define RNG_ALARMCNT_ALARM_TH_MASK (0xff  0)
+#define RNG_ALARMCNT_SHUTDOWN_TH_SHIFT 16
+#define RNG_ALARMCNT_SHUTDOWN_TH_MASK  (0x1f  16)
+#define RNG_ALARM_THRESHOLD0xff
+#define RNG_SHUTDOWN_THRESHOLD 0x4
+
+#define RNG_REG_FROENABLE_MASK 0xff
+#define RNG_REG_FRODETUNE_MASK 0xff
+
+#define OMAP2_RNG_OUTPUT_SIZE  0x4
+#define OMAP4_RNG_OUTPUT_SIZE  0x8
+
+enum {
+   RNG_OUTPUT_L_REG = 0,
+   RNG_OUTPUT_H_REG,
+   RNG_STATUS_REG,
+   RNG_INTMASK_REG,
+   RNG_INTACK_REG,
+   RNG_CONTROL_REG,
+   RNG_CONFIG_REG,
+   RNG_ALARMCNT_REG,
+   RNG_FROENABLE_REG,
+   RNG_FRODETUNE_REG,
+   RNG_ALARMMASK_REG,
+   RNG_ALARMSTOP_REG,
+   RNG_REV_REG,
+   RNG_SYSCONFIG_REG,
+};
+
+static const u16 reg_map_omap2[] = {
+   [RNG_OUTPUT_L_REG

[PATCH 0/4] crypto: omap-sham: Add support for SHA384/SHA512 for OMAP5/AM43xx Soc's

2013-07-26 Thread Lokesh Vutla
This patch series adds support for SHA348 and SHA512 in addition to MD5,
SHA1, SHA224 SHA256 that the omap sha module supports. Also adding the pdata
for OMAP5 and AM43xx Soc's.
And using devm_* calls to make cleanup paths simpler.

Lokesh Vutla (4):
  crypto: omap-sham: Add SHA384 and SHA512 Support
  crypto: omap-sham: Add OMAP5/AM43XX SHAM Support
  crypto: omap-sham: Convert to devm_request_irq()
  crypto: omap-sham: Convert to devm_kzalloc()

 drivers/crypto/Kconfig |   11 +-
 drivers/crypto/omap-sham.c |  314 +++-
 2 files changed, 262 insertions(+), 63 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] crypto: omap-sham: Add SHA384 and SHA512 Support

2013-07-26 Thread Lokesh Vutla
Adding support for SHA348 and SHA512 in addition to MD5, SHA1, SHA224
SHA256 that the omap sha module supports.

In order to add the support
- Removed hard coded register offsets and passing offsets from pdata
- Updating Flag offsets so that they can be used for SHA256 and SHA512
- Adding the algo info.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/Kconfig |   11 +-
 drivers/crypto/omap-sham.c |  245 
 2 files changed, 209 insertions(+), 47 deletions(-)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 8ff7c23..62fb673 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -242,13 +242,16 @@ config CRYPTO_DEV_PPC4XX
  This option allows you to have support for AMCC crypto acceleration.
 
 config CRYPTO_DEV_OMAP_SHAM
-   tristate Support for OMAP SHA1/MD5 hw accelerator
-   depends on ARCH_OMAP2 || ARCH_OMAP3
+   tristate Support for OMAP MD5/SHA1/SHA2 hw accelerator
+   depends on ARCH_OMAP2PLUS
select CRYPTO_SHA1
select CRYPTO_MD5
+   select CRYPTO_SHA256
+   select CRYPTO_SHA512
+   select CRYPTO_HMAC
help
- OMAP processors have SHA1/MD5 hw accelerator. Select this if you
- want to use the OMAP module for SHA1/MD5 algorithms.
+ OMAP processors have MD5/SHA1/SHA2 hw accelerator. Select this if you
+ want to use the OMAP module for MD5/SHA1/SHA2 algorithms.
 
 config CRYPTO_DEV_OMAP_AES
tristate Support for OMAP AES hw engine
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 4bb6765..f73b1e0 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -44,7 +44,6 @@
 #include crypto/hash.h
 #include crypto/internal/hash.h
 
-#define SHA1_MD5_BLOCK_SIZESHA1_BLOCK_SIZE
 #define MD5_DIGEST_SIZE16
 
 #define DST_MAXBURST   16
@@ -54,7 +53,7 @@
 #define SHA_REG_DIN(dd, x) ((dd)-pdata-din_ofs + ((x) * 0x04))
 #define SHA_REG_DIGCNT(dd) ((dd)-pdata-digcnt_ofs)
 
-#define SHA_REG_ODIGEST(x) (0x00 + ((x) * 0x04))
+#define SHA_REG_ODIGEST(dd, x) ((dd)-pdata-odigest_ofs + (x * 0x04))
 
 #define SHA_REG_CTRL   0x18
 #define SHA_REG_CTRL_LENGTH(0x  5)
@@ -75,18 +74,21 @@
 #define SHA_REG_SYSSTATUS(dd)  ((dd)-pdata-sysstatus_ofs)
 #define SHA_REG_SYSSTATUS_RESETDONE(1  0)
 
-#define SHA_REG_MODE   0x44
+#define SHA_REG_MODE(dd)   ((dd)-pdata-mode_ofs)
 #define SHA_REG_MODE_HMAC_OUTER_HASH   (1  7)
 #define SHA_REG_MODE_HMAC_KEY_PROC (1  5)
 #define SHA_REG_MODE_CLOSE_HASH(1  4)
 #define SHA_REG_MODE_ALGO_CONSTANT (1  3)
-#define SHA_REG_MODE_ALGO_MASK (3  1)
-#defineSHA_REG_MODE_ALGO_MD5_128   (0  1)
-#defineSHA_REG_MODE_ALGO_SHA1_160  (1  1)
-#defineSHA_REG_MODE_ALGO_SHA2_224  (2  1)
-#defineSHA_REG_MODE_ALGO_SHA2_256  (3  1)
 
-#define SHA_REG_LENGTH 0x48
+#define SHA_REG_MODE_ALGO_MASK (7  0)
+#define SHA_REG_MODE_ALGO_MD5_128  (0  1)
+#define SHA_REG_MODE_ALGO_SHA1_160 (1  1)
+#define SHA_REG_MODE_ALGO_SHA2_224 (2  1)
+#define SHA_REG_MODE_ALGO_SHA2_256 (3  1)
+#define SHA_REG_MODE_ALGO_SHA2_384 (1  0)
+#define SHA_REG_MODE_ALGO_SHA2_512 (3  0)
+
+#define SHA_REG_LENGTH(dd) ((dd)-pdata-length_ofs)
 
 #define SHA_REG_IRQSTATUS  0x118
 #define SHA_REG_IRQSTATUS_CTX_RDY  (1  3)
@@ -117,18 +119,16 @@
 #define FLAGS_SG   17
 
 #define FLAGS_MODE_SHIFT   18
-#define FLAGS_MODE_MASK(SHA_REG_MODE_ALGO_MASK 
\
-(FLAGS_MODE_SHIFT - 1))
-#defineFLAGS_MODE_MD5  (SHA_REG_MODE_ALGO_MD5_128  
\
-(FLAGS_MODE_SHIFT - 1))
-#defineFLAGS_MODE_SHA1 (SHA_REG_MODE_ALGO_SHA1_160 
\
-(FLAGS_MODE_SHIFT - 1))
-#defineFLAGS_MODE_SHA224   (SHA_REG_MODE_ALGO_SHA2_224 
\
-(FLAGS_MODE_SHIFT - 1))
-#defineFLAGS_MODE_SHA256   (SHA_REG_MODE_ALGO_SHA2_256 
\
-(FLAGS_MODE_SHIFT - 1))
-#define FLAGS_HMAC 20
-#define FLAGS_ERROR21
+#define FLAGS_MODE_MASK(SHA_REG_MODE_ALGO_MASK  
FLAGS_MODE_SHIFT)
+#define FLAGS_MODE_MD5 (SHA_REG_MODE_ALGO_MD5_128  FLAGS_MODE_SHIFT)
+#define FLAGS_MODE_SHA1(SHA_REG_MODE_ALGO_SHA1_160  
FLAGS_MODE_SHIFT)
+#define FLAGS_MODE_SHA224  (SHA_REG_MODE_ALGO_SHA2_224  FLAGS_MODE_SHIFT)
+#define FLAGS_MODE_SHA256  (SHA_REG_MODE_ALGO_SHA2_256  FLAGS_MODE_SHIFT)
+#define FLAGS_MODE_SHA384

[PATCH 3/4] crypto: omap-sham: Convert to devm_request_irq()

2013-07-26 Thread Lokesh Vutla
Using devm_request_irq() rather than request_irq().
So removing free_irq() calls from the probe error
path and the remove handler.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c |   12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index a6eb6a8..b82b140 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -1896,10 +1896,11 @@ static int omap_sham_probe(struct platform_device *pdev)
}
dd-phys_base = res.start;
 
-   err = request_irq(dd-irq, dd-pdata-intr_hdlr, IRQF_TRIGGER_LOW,
- dev_name(dev), dd);
+   err = devm_request_irq(dev, dd-irq, dd-pdata-intr_hdlr,
+  IRQF_TRIGGER_NONE, dev_name(dev), dd);
if (err) {
-   dev_err(dev, unable to request irq.\n);
+   dev_err(dev, unable to request irq %d, err = %d\n,
+   dd-irq, err);
goto res_err;
}
 
@@ -1912,7 +1913,7 @@ static int omap_sham_probe(struct platform_device *pdev)
dev_err(dev, unable to obtain RX DMA engine channel %u\n,
dd-dma);
err = -ENXIO;
-   goto dma_err;
+   goto res_err;
}
 
dd-flags |= dd-pdata-flags;
@@ -1950,8 +1951,6 @@ err_algs:
dd-pdata-algs_info[i].algs_list[j]);
pm_runtime_disable(dev);
dma_release_channel(dd-dma_lch);
-dma_err:
-   free_irq(dd-irq, dd);
 res_err:
kfree(dd);
dd = NULL;
@@ -1979,7 +1978,6 @@ static int omap_sham_remove(struct platform_device *pdev)
tasklet_kill(dd-done_task);
pm_runtime_disable(pdev-dev);
dma_release_channel(dd-dma_lch);
-   free_irq(dd-irq, dd);
kfree(dd);
dd = NULL;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] crypto: omap-sham: Convert to devm_kzalloc()

2013-07-26 Thread Lokesh Vutla
Use devm_kzalloc() to make cleanup paths simpler.

Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
---
 drivers/crypto/omap-sham.c |   15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index b82b140..ae1ca8b2 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -1870,7 +1870,7 @@ static int omap_sham_probe(struct platform_device *pdev)
int err, i, j;
u32 rev;
 
-   dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
+   dd = devm_kzalloc(dev, sizeof(struct omap_sham_dev), GFP_KERNEL);
if (dd == NULL) {
dev_err(dev, unable to alloc data struct.\n);
err = -ENOMEM;
@@ -1887,12 +1887,12 @@ static int omap_sham_probe(struct platform_device *pdev)
err = (dev-of_node) ? omap_sham_get_res_of(dd, dev, res) :
   omap_sham_get_res_pdev(dd, pdev, res);
if (err)
-   goto res_err;
+   goto data_err;
 
dd-io_base = devm_ioremap_resource(dev, res);
if (IS_ERR(dd-io_base)) {
err = PTR_ERR(dd-io_base);
-   goto res_err;
+   goto data_err;
}
dd-phys_base = res.start;
 
@@ -1901,7 +1901,7 @@ static int omap_sham_probe(struct platform_device *pdev)
if (err) {
dev_err(dev, unable to request irq %d, err = %d\n,
dd-irq, err);
-   goto res_err;
+   goto data_err;
}
 
dma_cap_zero(mask);
@@ -1913,7 +1913,7 @@ static int omap_sham_probe(struct platform_device *pdev)
dev_err(dev, unable to obtain RX DMA engine channel %u\n,
dd-dma);
err = -ENXIO;
-   goto res_err;
+   goto data_err;
}
 
dd-flags |= dd-pdata-flags;
@@ -1951,9 +1951,6 @@ err_algs:
dd-pdata-algs_info[i].algs_list[j]);
pm_runtime_disable(dev);
dma_release_channel(dd-dma_lch);
-res_err:
-   kfree(dd);
-   dd = NULL;
 data_err:
dev_err(dev, initialization failed.\n);
 
@@ -1978,8 +1975,6 @@ static int omap_sham_remove(struct platform_device *pdev)
tasklet_kill(dd-done_task);
pm_runtime_disable(pdev-dev);
dma_release_channel(dd-dma_lch);
-   kfree(dd);
-   dd = NULL;
 
return 0;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html