[PATCH] crypto : async implementation for sha1-mb

2016-06-17 Thread Megha Dey
From: Megha Dey 

Herbert wants the sha1-mb algorithm to have an async implementation:
https://lkml.org/lkml/2016/4/5/286.
Currently, sha1-mb uses an async interface for the outer algorithm
and a sync interface for the inner algorithm. This patch introduces
a async interface for even the inner algorithm.

Signed-off-by: Megha Dey 
Signed-off-by: Tim Chen 
---
 arch/x86/crypto/sha-mb/sha1_mb.c | 187 ++-
 crypto/mcryptd.c | 124 +++---
 include/crypto/internal/hash.h   |  12 +--
 include/crypto/mcryptd.h |   8 +-
 4 files changed, 166 insertions(+), 165 deletions(-)

diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c
index 0a46491..c76d1ba 100644
--- a/arch/x86/crypto/sha-mb/sha1_mb.c
+++ b/arch/x86/crypto/sha-mb/sha1_mb.c
@@ -80,10 +80,10 @@ struct sha1_mb_ctx {
 static inline struct mcryptd_hash_request_ctx
*cast_hash_to_mcryptd_ctx(struct sha1_hash_ctx *hash_ctx)
 {
-   struct shash_desc *desc;
+   struct ahash_request *areq;
 
-   desc = container_of((void *) hash_ctx, struct shash_desc, __ctx);
-   return container_of(desc, struct mcryptd_hash_request_ctx, desc);
+   areq = container_of((void *) hash_ctx, struct ahash_request, __ctx);
+   return container_of(areq, struct mcryptd_hash_request_ctx, areq);
 }
 
 static inline struct ahash_request
@@ -93,7 +93,7 @@ static inline struct ahash_request
 }
 
 static void req_ctx_init(struct mcryptd_hash_request_ctx *rctx,
-   struct shash_desc *desc)
+   struct ahash_request *areq)
 {
rctx->flag = HASH_UPDATE;
 }
@@ -375,9 +375,9 @@ static struct sha1_hash_ctx *sha1_ctx_mgr_flush(struct 
sha1_ctx_mgr *mgr)
}
 }
 
-static int sha1_mb_init(struct shash_desc *desc)
+static int sha1_mb_init(struct ahash_request *areq)
 {
-   struct sha1_hash_ctx *sctx = shash_desc_ctx(desc);
+   struct sha1_hash_ctx *sctx = ahash_request_ctx(areq);
 
hash_ctx_init(sctx);
sctx->job.result_digest[0] = SHA1_H0;
@@ -395,7 +395,7 @@ static int sha1_mb_init(struct shash_desc *desc)
 static int sha1_mb_set_results(struct mcryptd_hash_request_ctx *rctx)
 {
int i;
-   struct  sha1_hash_ctx *sctx = shash_desc_ctx(>desc);
+   struct  sha1_hash_ctx *sctx = ahash_request_ctx(>areq);
__be32  *dst = (__be32 *) rctx->out;
 
for (i = 0; i < 5; ++i)
@@ -427,7 +427,7 @@ static int sha_finish_walk(struct mcryptd_hash_request_ctx 
**ret_rctx,
 
}
sha_ctx = (struct sha1_hash_ctx *)
-   shash_desc_ctx(>desc);
+   ahash_request_ctx(>areq);
kernel_fpu_begin();
sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx,
rctx->walk.data, nbytes, flag);
@@ -519,11 +519,10 @@ static void sha1_mb_add_list(struct 
mcryptd_hash_request_ctx *rctx,
mcryptd_arm_flusher(cstate, delay);
 }
 
-static int sha1_mb_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
+static int sha1_mb_update(struct ahash_request *areq)
 {
struct mcryptd_hash_request_ctx *rctx =
-   container_of(desc, struct mcryptd_hash_request_ctx, desc);
+   container_of(areq, struct mcryptd_hash_request_ctx, areq);
struct mcryptd_alg_cstate *cstate =
this_cpu_ptr(sha1_mb_alg_state.alg_cstate);
 
@@ -539,7 +538,7 @@ static int sha1_mb_update(struct shash_desc *desc, const u8 
*data,
}
 
/* need to init context */
-   req_ctx_init(rctx, desc);
+   req_ctx_init(rctx, areq);
 
nbytes = crypto_ahash_walk_first(req, >walk);
 
@@ -552,7 +551,7 @@ static int sha1_mb_update(struct shash_desc *desc, const u8 
*data,
rctx->flag |= HASH_DONE;
 
/* submit */
-   sha_ctx = (struct sha1_hash_ctx *) shash_desc_ctx(desc);
+   sha_ctx = (struct sha1_hash_ctx *) ahash_request_ctx(areq);
sha1_mb_add_list(rctx, cstate);
kernel_fpu_begin();
sha_ctx = sha1_ctx_mgr_submit(cstate->mgr, sha_ctx, rctx->walk.data,
@@ -579,11 +578,10 @@ done:
return ret;
 }
 
-static int sha1_mb_finup(struct shash_desc *desc, const u8 *data,
-unsigned int len, u8 *out)
+static int sha1_mb_finup(struct ahash_request *areq)
 {
struct mcryptd_hash_request_ctx *rctx =
-   container_of(desc, struct mcryptd_hash_request_ctx, desc);
+   container_of(areq, struct mcryptd_hash_request_ctx, areq);
struct mcryptd_alg_cstate *cstate =
this_cpu_ptr(sha1_mb_alg_state.alg_cstate);
 
@@ -598,7 +596,7 @@ static int sha1_mb_finup(struct shash_desc *desc, 

[PATCH] crypto: use timespec64 for jent_get_nstime

2016-06-17 Thread Arnd Bergmann
The jent_get_nstime() function uses __getnstimeofday() to get
something similar to a 64-bit nanosecond counter. As we want
to get rid of struct timespec to fix the y2038 overflow,
this patch changes the code to use __getnstimeofday64()
instead, which returns a timespec64 structure.

Nothing changes about the algorithm, but it looks like it
might be better to use

 *out = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;

or even

 *out = ktime_get_raw_fast_ns();

to get an actual nanosecond value and avoid the predictable
jitter that happens at the end of a second. Checking whether
or not this would be good needs investigation by someone who
understands the code better than me.

Signed-off-by: Arnd Bergmann 
---
 crypto/jitterentropy-kcapi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 597cedd3531c..82ac44eff20d 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -89,7 +89,7 @@ void jent_memcpy(void *dest, const void *src, unsigned int n)
 
 void jent_get_nstime(__u64 *out)
 {
-   struct timespec ts;
+   struct timespec64 ts;
__u64 tmp = 0;
 
tmp = random_get_entropy();
@@ -98,9 +98,11 @@ void jent_get_nstime(__u64 *out)
 * If random_get_entropy does not return a value (which is possible on,
 * for example, MIPS), invoke __getnstimeofday
 * hoping that there are timers we can work with.
+*
+* should we have a __ktime_get_ns() instead?
 */
if ((0 == tmp) &&
-  (0 == __getnstimeofday())) {
+  (0 == __getnstimeofday64())) {
tmp = ts.tv_sec;
tmp = tmp << 32;
tmp = tmp | ts.tv_nsec;
-- 
2.9.0

--
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 v4 0/5] /dev/random - a new approach

2016-06-17 Thread Sandy Harris
David Jaša  wrote:

>
> BTW when looking at an old BSI's issue with Linux urandom that Jarod
> Wilson tried to solve with this series:
> https://www.spinics.net/lists/linux-crypto/msg06113.html
> I was thinking:
> 1) wouldn't it help for large urandom consumers if kernel created a DRBG
> instance for each of them? It would likely enhance performance and solve
> BSI's concern of predicting what numbers could other urandom consumers
> obtain at cost of memory footprint
> and then, after reading paper associated with this series:
> 2) did you evaluate use of intermediate DRBG fed by primary generator to
> instantiate per-node DRBG's? It would allow initialization of all
> secondary DRBGs right after primary generator initialization.

Theodore Ts'o, the random maintainer, already has a patch that
seems to deal with this issue. He has posted more than one
version & I'm not sure this is the best or latest, but ...
https://lkml.org/lkml/2016/5/30/22
--
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 v9 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-17 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key, along with the parameters
   known to both parties involved in the key-agreement session.
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 328 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 552 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index c903f18..8070678 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), ))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+
 static int crypto_report_one(struct crypto_alg *alg,
 struct crypto_user_alg *ualg, struct sk_buff *skb)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), ))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_kpp_show(struct seq_file *m, 

[PATCH v9 0/3] Key-agreement Protocol Primitives (KPP) API

2016-06-17 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v8:
* set_secret accept a buffer packed and prefixed with a tiny header of
  2 fields: type and len. Each kpp type define its own type and provide
  helper for user (encoder) and drivers (decoder)

Changed from v7:
* API change: merge set_param and set_key to set_key. Params and private
  key are now provided together. Params have always to be provided.
* Merge generate_public_key and compute_shared_secret into compute_val.
  API stay as it is
* Add ecc_is_key_valid to validate private key when set. Now that params
  and key are set together we can validate the key right away. Before the
  check was deferred to generate_public_key.

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review


Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |9 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  189 
 crypto/dh_helper.c  |   84 
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 ++
 crypto/ecdh_helper.c|   75 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  362 ++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   29 ++
 include/crypto/ecdh.h   |   30 ++
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  330 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 19 files changed, 2939 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

--
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 v9 3/3] crypto: kpp - Add ECDH software support

2016-06-17 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |4 +
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 +++
 crypto/ecdh_helper.c|   75 
 crypto/testmgr.c|  176 +++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   30 ++
 include/crypto/kpp.h|1 +
 11 files changed, 1669 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 92b5f0b..d0492ae 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 28e8708..47b1fae 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -35,6 +35,10 @@ obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 dh_generic-y := dh.o
 dh_generic-y += dh_helper.o
 obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+ecdh_generic-y += ecdh_helper.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..9aedec6
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *  * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : _p192;
+   case ECC_CURVE_NIST_P256:
+   return _p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   

[PATCH v9 2/3] crypto: kpp - Add DH software implementation

2016-06-17 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig   |   8 ++
 crypto/Makefile  |   4 +
 crypto/dh.c  | 189 ++
 crypto/dh_helper.c   |  84 +
 crypto/testmgr.c | 204 ++
 crypto/testmgr.h | 208 +++
 include/crypto/dh.h  |  29 +++
 include/crypto/kpp.h |   1 +
 8 files changed, 727 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8070678..92b5f0b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..28e8708 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,10 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+dh_generic-y := dh.o
+dh_generic-y += dh_helper.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..d060b11
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,189 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static inline void dh_clear_params(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   ctx->p = NULL;
+   ctx->g = NULL;
+}
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   dh_clear_params(ctx);
+   mpi_free(ctx->xa);
+   ctx->xa = NULL;
+}
+
+/*
+ * If base is g we compute the public key
+ * ya = g^xa mod p; [RFC2631 sec 2.1.1]
+ * else if base if the counterpart public key we compute the shared secret
+ * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+ */
+static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
+{
+   /* val = base^xa mod p */
+   return mpi_powm(val, base, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
+{
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buf, unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh *params = NULL;
+
+   if (crypto_dh_decode_key(buf, len, ) < 0)
+   return -EINVAL;
+
+   if (dh_set_params(ctx, params) < 0)
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(params->key, params->key_size);
+   if (!ctx->xa) {
+   dh_clear_params(ctx);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_compute_value(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI base, val = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!val)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_val;
+   }
+
+   if (req->src) {
+   base = mpi_read_raw_from_sgl(req->src, req->src_len);
+   if 

Re: [PATCH v4 0/5] /dev/random - a new approach

2016-06-17 Thread David Jaša
Hi Stephan,

thank you for your thorough reply,

On St, 2016-06-15 at 18:58 +0200, Stephan Mueller wrote:
> Am Mittwoch, 15. Juni 2016, 18:17:43 schrieb David Jaša:
> 
> Hi David,
> 
> > Hello Stephan,
> > 
> > Did you consider blocking urandom output or returning error until
> > initialized? Given the speed of initialization you report, it shouldn't
> > break any userspace apps while making sure that nobody uses predictable
> > pseudoranom numbers.
> 
> My LRNG will definitely touch the beginning of the initramfs booting until it 
> is fully seeded. As these days the initramfs is driven by systemd which 
> always 
> pulls from /dev/urandom, we cannot block as this would block systemd. In 
> Ted's 
> last patch, he mentioned that he tried to make /dev/urandom block which 
> caused 
> user space pain.

I was thinking along the lines that "almost every important package
supports FreeBSD as well where they have to handle the condition so
option to switch to Rather Break Than Generate Weak Keys would be nice"
- but I didn't expect that systemd could be a roadblock here. :-/

I was also thinking of little devices where OpenWRT or proprietary
Linux-based systems run that ended up with predictable keys way too
ofter (or as in OpenWRT's case, with cumbersome tutorials how to
generate keys elsewhere).

> 
> But if you use the getrandom system call, it works like /dev/urandom but 
> blocks until the DRBG behind /dev/urandom is fully initialized.
> > 
> > I was considering asking for patch (or even trying to write it myself)
> > to make current urandom block/fail when not initialized but that would
> > surely have to be off by default over "never break userspace" rule (even
> > if it means way too easy security problem with both random and urandom).
> > Properties of your urandom implementation makes this point moot and it
> > could make the random/urandom wars over.
> 
> That patch unfortunately will not work. But if you are interested in that 
> blocking /dev/urandom behavior for your application, use getrandom.
> 

I'm QA with a touch of sysadmin so the numbers of apps to fix is large
and I don't have neither control over the projects nor abilities to
patch them all myself. :)

> > 
> > Best Regards,
> > 
> > David Jaša
> 
> 
> Ciao
> Stephan

BTW when looking at an old BSI's issue with Linux urandom that Jarod
Wilson tried to solve with this series:
https://www.spinics.net/lists/linux-crypto/msg06113.html
I was thinking:
1) wouldn't it help for large urandom consumers if kernel created a DRBG
instance for each of them? It would likely enhance performance and solve
BSI's concern of predicting what numbers could other urandom consumers
obtain at cost of memory footprint
and then, after reading paper associated with this series:
2) did you evaluate use of intermediate DRBG fed by primary generator to
instantiate per-node DRBG's? It would allow initialization of all
secondary DRBGs right after primary generator initialization.

Cheers,

David

--
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 10/10] crypto: marvell: Increase the size of the crypto queue

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:09 +0200
Romain Perier  wrote:

> Now that crypto requests are chained together at the DMA level, we
> increase the size of the crypto queue for each engine. The result is
> that as the backlog list is reached later, it does not stop the crypto
> stack from sending asychronous requests, so more cryptographic tasks
> are processed by the engines.
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

> ---
>  drivers/crypto/marvell/cesa.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
> index bb91156..5147073 100644
> --- a/drivers/crypto/marvell/cesa.c
> +++ b/drivers/crypto/marvell/cesa.c
> @@ -32,7 +32,7 @@
>  #include "cesa.h"
>  
>  /* Limit of the crypto queue before reaching the backlog */
> -#define CESA_CRYPTO_DEFAULT_MAX_QLEN 50
> +#define CESA_CRYPTO_DEFAULT_MAX_QLEN 128
>  
>  static int allhwsupport = !IS_ENABLED(CONFIG_CRYPTO_DEV_MV_CESA);
>  module_param_named(allhwsupport, allhwsupport, int, 0444);

--
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 09/10] crypto: marvell: Add support for chaining crypto requests in TDMA mode

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:08 +0200
Romain Perier  wrote:

> The Cryptographic Engines and Security Accelerators (CESA) supports the
> Multi-Packet Chain Mode. With this mode enabled, multiple tdma requests
> can be chained and processed by the hardware without software
> intervention. This mode was already activated, however the crypto
> requests were not chained together. By doing so, we reduce significantly
> the number of IRQs. Instead of being interrupted at the end of each
> crypto request, we are interrupted at the end of the last cryptographic
> request processed by the engine.
> 
> This commits re-factorizes the code, changes the code architecture and
> adds the required data structures to chain cryptographic requests
> together before sending them to an engine (stopped or possibly already
> running).
> 
> Signed-off-by: Romain Perier 
> ---
> 
> Changes in v2:
> 
>   - Reworded the commit message
>   - Fixed cosmetic changes: coding styles issues, missing blank lines
>   - Reworked mv_cesa_rearm_engine: lock handling is simpler
>   - Removed the call to the complete operation in mv_cesa_std_process,
> in case of errors (not required)
>   - Squashed the removal of the '.prepare' fields (cipher.c, hash.c)
> into another commit (see PATCH 08/10).
>   - In mv_cesa_tdma_process only treat the status argument for the last
> request, use 'normal' status for the other ones.
>   - Added a comment for explaining how the errors are notified to the
> cesa core.
> 
>  drivers/crypto/marvell/cesa.c   | 115 
> +++-
>  drivers/crypto/marvell/cesa.h   |  39 +-
>  drivers/crypto/marvell/cipher.c |   2 +-
>  drivers/crypto/marvell/hash.c   |   6 +++
>  drivers/crypto/marvell/tdma.c   |  88 ++
>  5 files changed, 223 insertions(+), 27 deletions(-)
> 

[...]

> +void
> +mv_cesa_tdma_chain(struct mv_cesa_engine *engine, struct mv_cesa_req *dreq)

void mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
struct mv_cesa_req *dreq)

> +{
> + if (engine->chain.first == NULL && engine->chain.last == NULL) {
> + engine->chain.first = dreq->chain.first;
> + engine->chain.last  = dreq->chain.last;
> + } else {
> + struct mv_cesa_tdma_desc *last;
> +
> + last = engine->chain.last;
> + last->next = dreq->chain.first;
> + engine->chain.last = dreq->chain.last;
> +
> + if (!(last->flags & CESA_TDMA_BREAK_CHAIN))
> + last->next_dma = dreq->chain.first->cur_dma;
> + }
> +}
> +
> +int
> +mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status)

int mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status)

> +{
> + struct crypto_async_request *req = NULL;
> + struct mv_cesa_tdma_desc *tdma = NULL, *next = NULL;
> + dma_addr_t tdma_cur;
> + int res = 0;
> +
> + tdma_cur = readl(engine->regs + CESA_TDMA_CUR);
> +
> + for (tdma = engine->chain.first; tdma; tdma = next) {
> + spin_lock_bh(>lock);
> + next = tdma->next;
> + spin_unlock_bh(>lock);
> +
> + if (tdma->flags & CESA_TDMA_END_OF_REQ) {
> + struct crypto_async_request *backlog = NULL;
> + struct mv_cesa_ctx *ctx;
> + u32 current_status;
> +
> + spin_lock_bh(>lock);
> + /*
> +  * if req is NULL, this means we're processing the
> +  * request in engine->req.
> +  */
> + if (!req)
> + req = engine->req;
> + else
> + req = mv_cesa_dequeue_req_locked(engine,
> +  );
> +
> + /* Re-chaining to the next request */
> + engine->chain.first = tdma->next;
> + tdma->next = NULL;
> +
> + /* If this is the last request, clear the chain */
> + if (engine->chain.first == NULL)
> + engine->chain.last  = NULL;
> + spin_unlock_bh(>lock);
> +
> + ctx = crypto_tfm_ctx(req->tfm);
> + current_status = (tdma->cur_dma == tdma_cur) ?
> +   status : CESA_SA_INT_ACC0_IDMA_DONE;
> + res = ctx->ops->process(req, current_status);
> + ctx->ops->complete(req);
> +
> + if (res == 0)
> + mv_cesa_engine_enqueue_complete_request(engine,
> + req);
> +
> + if (backlog)
> + backlog->complete(backlog, -EINPROGRESS);

Re: [PATCH v2 08/10] crypto: marvell: Add load balancing between engines

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:07 +0200
Romain Perier  wrote:

> This commits adds support for fine grained load balancing on
> multi-engine IPs. The engine is pre-selected based on its current load
> and on the weight of the crypto request that is about to be processed.
> The global crypto queue is also moved to each engine. These changes are
> required to allow chaining crypto requests at the DMA level. By using
> a crypto queue per engine, we make sure that we keep the state of the
> tdma chain synchronized with the crypto queue. We also reduce contention
> on 'cesa_dev->lock' and improve parallelism.
> 
> Signed-off-by: Romain Perier 
> ---
> 
> Changes in v2:
> 
>   - Reworded the commit message
>   - Moved the code about SRAM I/O operations from this commit to
> a separated commit (see PATCH 07/10).
> 
>  drivers/crypto/marvell/cesa.c   | 30 ++
>  drivers/crypto/marvell/cesa.h   | 29 +
>  drivers/crypto/marvell/cipher.c | 57 
> ++---
>  drivers/crypto/marvell/hash.c   | 50 ++--
>  4 files changed, 82 insertions(+), 84 deletions(-)
> 
> diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
> index af96426..f9e6688 100644
> --- a/drivers/crypto/marvell/cesa.c
> +++ b/drivers/crypto/marvell/cesa.c
> @@ -45,11 +45,9 @@ static void mv_cesa_dequeue_req_unlocked(struct 
> mv_cesa_engine *engine)

This function should be renamed mv_cesa_dequeue_req_locked(). I see
you're doing it in patch 9, but it should be done here.

>   struct crypto_async_request *req, *backlog;
>   struct mv_cesa_ctx *ctx;
>  
> - spin_lock_bh(_dev->lock);
> - backlog = crypto_get_backlog(_dev->queue);
> - req = crypto_dequeue_request(_dev->queue);
> + backlog = crypto_get_backlog(>queue);
> + req = crypto_dequeue_request(>queue);
>   engine->req = req;
> - spin_unlock_bh(_dev->lock);
>  
>   if (!req)
>   return;
--
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 07/10] crypto: marvell: Move SRAM I/O operations to step functions

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:06 +0200
Romain Perier  wrote:

> Currently the crypto requests were sent to engines sequentially.
> This commit moves the SRAM I/O operations from the prepare to the step
> functions. It provides flexibility for future works and allow to prepare
> a request while the engine is running.
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

> ---
>  drivers/crypto/marvell/cipher.c |  6 +++---
>  drivers/crypto/marvell/hash.c   | 18 +-
>  2 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
> index 175ce76..79d4175 100644
> --- a/drivers/crypto/marvell/cipher.c
> +++ b/drivers/crypto/marvell/cipher.c
> @@ -89,6 +89,9 @@ static void mv_cesa_ablkcipher_std_step(struct 
> ablkcipher_request *req)
>   size_t  len = min_t(size_t, req->nbytes - sreq->offset,
>   CESA_SA_SRAM_PAYLOAD_SIZE);
>  
> + mv_cesa_adjust_op(engine, >op);
> + memcpy_toio(engine->sram, >op, sizeof(sreq->op));
> +
>   len = sg_pcopy_to_buffer(req->src, creq->src_nents,
>engine->sram + CESA_SA_DATA_SRAM_OFFSET,
>len, sreq->offset);
> @@ -177,12 +180,9 @@ mv_cesa_ablkcipher_std_prepare(struct ablkcipher_request 
> *req)
>  {
>   struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
>   struct mv_cesa_ablkcipher_std_req *sreq = >std;
> - struct mv_cesa_engine *engine = creq->base.engine;
>  
>   sreq->size = 0;
>   sreq->offset = 0;
> - mv_cesa_adjust_op(engine, >op);
> - memcpy_toio(engine->sram, >op, sizeof(sreq->op));
>  }
>  
>  static inline void mv_cesa_ablkcipher_prepare(struct crypto_async_request 
> *req,
> diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
> index 09665a7..e1f8acd 100644
> --- a/drivers/crypto/marvell/hash.c
> +++ b/drivers/crypto/marvell/hash.c
> @@ -162,6 +162,15 @@ static void mv_cesa_ahash_std_step(struct ahash_request 
> *req)
>   unsigned int new_cache_ptr = 0;
>   u32 frag_mode;
>   size_t  len;
> + unsigned int digsize;
> + int i;
> +
> + mv_cesa_adjust_op(engine, >op_tmpl);
> + memcpy_toio(engine->sram, >op_tmpl, sizeof(creq->op_tmpl));
> +
> + digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
> + for (i = 0; i < digsize / 4; i++)
> + writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
>  
>   if (creq->cache_ptr)
>   memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
> @@ -265,11 +274,8 @@ static void mv_cesa_ahash_std_prepare(struct 
> ahash_request *req)
>  {
>   struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
>   struct mv_cesa_ahash_std_req *sreq = >req.std;
> - struct mv_cesa_engine *engine = creq->base.engine;
>  
>   sreq->offset = 0;
> - mv_cesa_adjust_op(engine, >op_tmpl);
> - memcpy_toio(engine->sram, >op_tmpl, sizeof(creq->op_tmpl));
>  }
>  
>  static void mv_cesa_ahash_step(struct crypto_async_request *req)
> @@ -336,8 +342,6 @@ static void mv_cesa_ahash_prepare(struct 
> crypto_async_request *req,
>  {
>   struct ahash_request *ahashreq = ahash_request_cast(req);
>   struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
> - unsigned int digsize;
> - int i;
>  
>   creq->base.engine = engine;
>  
> @@ -345,10 +349,6 @@ static void mv_cesa_ahash_prepare(struct 
> crypto_async_request *req,
>   mv_cesa_ahash_dma_prepare(ahashreq);
>   else
>   mv_cesa_ahash_std_prepare(ahashreq);
> -
> - digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(ahashreq));
> - for (i = 0; i < digsize / 4; i++)
> - writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
>  }
>  
>  static void mv_cesa_ahash_req_cleanup(struct crypto_async_request *req)

--
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 06/10] crypto: marvell: Add a complete operation for async requests

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:05 +0200
Romain Perier  wrote:

> So far, the 'process' operation was used to check if the current request
> was correctly handled by the engine, if it was the case it copied
> information from the SRAM to the main memory. Now, we split this
> operation. We keep the 'process' operation, which still checks if the
> request was correctly handled by the engine or not, then we add a new
> operation for completion. The 'complete' method copies the content of
> the SRAM to memory. This will soon become useful if we want to call
> the process and the complete operations from different locations
> depending on the type of the request (different cleanup logic).
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

> ---
> 
> Changes in v2:
> 
>   - Removed useless cosmetic change added for checkpatch (which
> had nothing to do with the patch itself)
>   - Removed duplicated initialization of 'ivsize'
> mv_cesa_ablkcipher_complete.
>   - Replace memcpy_fromio by memcpy in mv_cesa_ablkcipher_complete
> 
>  drivers/crypto/marvell/cesa.c   |  1 +
>  drivers/crypto/marvell/cesa.h   |  3 +++
>  drivers/crypto/marvell/cipher.c | 28 +++-
>  drivers/crypto/marvell/hash.c   | 22 --
>  4 files changed, 39 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
> index fe04d1b..af96426 100644
> --- a/drivers/crypto/marvell/cesa.c
> +++ b/drivers/crypto/marvell/cesa.c
> @@ -98,6 +98,7 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
>   engine->req = NULL;
>   mv_cesa_dequeue_req_unlocked(engine);
>   spin_unlock_bh(>lock);
> + ctx->ops->complete(req);
>   ctx->ops->cleanup(req);
>   local_bh_disable();
>   req->complete(req, res);
> diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
> index e67e3f1..c463528 100644
> --- a/drivers/crypto/marvell/cesa.h
> +++ b/drivers/crypto/marvell/cesa.h
> @@ -456,6 +456,8 @@ struct mv_cesa_engine {
>   *   code)
>   * @step:launch the crypto operation on the next chunk
>   * @cleanup: cleanup the crypto request (release associated data)
> + * @complete:complete the request, i.e copy result from sram or 
> contexts
> + *   when it is needed.

You mean "copy result or context from sram when needed", right?

>   */
>  struct mv_cesa_req_ops {
>   void (*prepare)(struct crypto_async_request *req,
> @@ -463,6 +465,7 @@ struct mv_cesa_req_ops {
>   int (*process)(struct crypto_async_request *req, u32 status);
>   void (*step)(struct crypto_async_request *req);
>   void (*cleanup)(struct crypto_async_request *req);
> + void (*complete)(struct crypto_async_request *req);
>  };
>  
>  /**
> diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
> index ffe0f4a..175ce76 100644
> --- a/drivers/crypto/marvell/cipher.c
> +++ b/drivers/crypto/marvell/cipher.c
> @@ -118,7 +118,6 @@ static int mv_cesa_ablkcipher_std_process(struct 
> ablkcipher_request *req,
>   struct mv_cesa_ablkcipher_std_req *sreq = >std;
>   struct mv_cesa_engine *engine = creq->base.engine;
>   size_t len;
> - unsigned int ivsize;
>  
>   len = sg_pcopy_from_buffer(req->dst, creq->dst_nents,
>  engine->sram + CESA_SA_DATA_SRAM_OFFSET,
> @@ -128,10 +127,6 @@ static int mv_cesa_ablkcipher_std_process(struct 
> ablkcipher_request *req,
>   if (sreq->offset < req->nbytes)
>   return -EINPROGRESS;
>  
> - ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
> - memcpy_fromio(req->info,
> -   engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET, ivsize);
> -
>   return 0;
>  }
>  
> @@ -211,11 +206,34 @@ mv_cesa_ablkcipher_req_cleanup(struct 
> crypto_async_request *req)
>   mv_cesa_ablkcipher_cleanup(ablkreq);
>  }
>  
> +static void
> +mv_cesa_ablkcipher_complete(struct crypto_async_request *req)
> +{
> + struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
> + struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
> + struct mv_cesa_engine *engine = creq->base.engine;
> + unsigned int ivsize;
> +
> + ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq));
> +
> + if (mv_cesa_req_get_type(>base) == CESA_DMA_REQ) {
> + struct mv_cesa_req *basereq;
> +
> + basereq = >base;
> + memcpy(ablkreq->info, basereq->chain.last->data, ivsize);
> + } else {
> + memcpy_fromio(ablkreq->info,
> +   engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET,
> +   

Re: [PATCH v2 05/10] crypto: marvell: Move tdma chain out of mv_cesa_tdma_req and remove it

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:04 +0200
Romain Perier  wrote:

> Currently, the only way to access the tdma chain is to use the 'req'
> union from a mv_cesa_{ablkcipher,ahash}. This will soon become a problem
> if we want to handle the TDMA chaining vs standard/non-DMA processing in
> a generic way (with generic functions at the cesa.c level detecting
> whether the request should be queued at the DMA level or not). Hence the
> decision to move the chain field a the mv_cesa_req level at the expense
> of adding 2 void * fields to all request contexts (including non-DMA
> ones) and to remove the type completly. To limit the overhead, we get
> rid of the type field, which can now be deduced from the req->chain.first
> value. Once these changes are done the union is no longer needed, so
> remove it and move mv_cesa_ablkcipher_std_req and mv_cesa_req
> to mv_cesa_ablkcipher_req directly. There are also no needs to keep the
> 'base' field into the union of mv_cesa_ahash_req, so move it into the
> upper structure.
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

> ---
> 
> Changes in v2:
>   - Reworded the commit log
>   - In mv_cesa_ablkcipher_req moved 'base' and 'std' into the upper
> structure. Also removed the union
>   - Removed 'base' from mv_cesa_ablkcipher_std_req
>   - In mv_cesa_hash_req moved 'base' into the upper structure
>   - Remove 'base' from mv_cesa_ahash_std_req and mv_cesa_ahash_dma_req
>   - Cosmetic changes: variables renaming, missing blank lines
>   - Replaced the test in mv_cesa_ahash_req_init from
> 'mv_cesa_req_get_type == CESA_DMA_REQ' to 'cesa_dev->caps->has_tdma',
> now mv_cesa_hash_dma_req_init is really called. 
> 
>  drivers/crypto/marvell/cesa.c   |  3 +-
>  drivers/crypto/marvell/cesa.h   | 44 ++-
>  drivers/crypto/marvell/cipher.c | 66 
> +
>  drivers/crypto/marvell/hash.c   | 64 ++-
>  drivers/crypto/marvell/tdma.c   |  8 ++---
>  5 files changed, 85 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
> index 93700cd..fe04d1b 100644
> --- a/drivers/crypto/marvell/cesa.c
> +++ b/drivers/crypto/marvell/cesa.c
> @@ -111,7 +111,8 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
>   return ret;
>  }
>  
> -int mv_cesa_queue_req(struct crypto_async_request *req)
> +int mv_cesa_queue_req(struct crypto_async_request *req,
> +   struct mv_cesa_req *creq)
>  {
>   int ret;
>   int i;
> diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
> index 685a627..e67e3f1 100644
> --- a/drivers/crypto/marvell/cesa.h
> +++ b/drivers/crypto/marvell/cesa.h
> @@ -509,21 +509,11 @@ enum mv_cesa_req_type {
>  
>  /**
>   * struct mv_cesa_req - CESA request
> - * @type:request type
>   * @engine:  engine associated with this request
> + * @chain:   list of tdma descriptors associated  with this request
>   */
>  struct mv_cesa_req {
> - enum mv_cesa_req_type type;
>   struct mv_cesa_engine *engine;
> -};
> -
> -/**
> - * struct mv_cesa_tdma_req - CESA TDMA request
> - * @base:base information
> - * @chain:   TDMA chain
> - */
> -struct mv_cesa_tdma_req {
> - struct mv_cesa_req base;
>   struct mv_cesa_tdma_chain chain;
>  };
>  
> @@ -540,13 +530,11 @@ struct mv_cesa_sg_std_iter {
>  
>  /**
>   * struct mv_cesa_ablkcipher_std_req - cipher standard request
> - * @base:base information
>   * @op:  operation context
>   * @offset:  current operation offset
>   * @size:size of the crypto operation
>   */
>  struct mv_cesa_ablkcipher_std_req {
> - struct mv_cesa_req base;
>   struct mv_cesa_op_ctx op;
>   unsigned int offset;
>   unsigned int size;
> @@ -560,34 +548,27 @@ struct mv_cesa_ablkcipher_std_req {
>   * @dst_nents:   number of entries in the dest sg list
>   */
>  struct mv_cesa_ablkcipher_req {
> - union {
> - struct mv_cesa_req base;
> - struct mv_cesa_tdma_req dma;
> - struct mv_cesa_ablkcipher_std_req std;
> - } req;
> + struct mv_cesa_req base;
> + struct mv_cesa_ablkcipher_std_req std;
>   int src_nents;
>   int dst_nents;
>  };
>  
>  /**
>   * struct mv_cesa_ahash_std_req - standard hash request
> - * @base:base information
>   * @offset:  current operation offset
>   */
>  struct mv_cesa_ahash_std_req {
> - struct mv_cesa_req base;
>   unsigned int offset;
>  };
>  
>  /**
>   * struct mv_cesa_ahash_dma_req - DMA hash request
> - * @base:base information
>   * @padding: padding buffer
>   * @padding_dma: DMA address of the padding buffer
>   * @cache_dma:   DMA address of the cache buffer
>   */
>  struct mv_cesa_ahash_dma_req {
> - struct mv_cesa_tdma_req base;
>   u8 

Re: [PATCH v2 04/10] crypto: marvell: Copy IV vectors by DMA transfers for acipher requests

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:03 +0200
Romain Perier  wrote:

> Add a TDMA descriptor at the end of the request for copying the
> output IV vector via a DMA transfer. This is a good way for offloading
> as much as processing as possible to the DMA and the crypto engine.
> This is also required for processing multiple cipher requests
> in chained mode, otherwise the content of the IV vector would be
> overwritten by the last processed request.
> 
> Signed-off-by: Romain Perier 

After fixing the coding style issue,

Acked-by: Boris Brezillon 

> ---
> 
> Changes in v2:
>   - Reworded the commit message, the term 'asynchronously' was
> ambigous
>   - Changed the value of CESA_TDMA_IV from 4 to 3
>   - Adding missing blank lines
>   - Rewrote the function mv_cesa_ablkcipher_process to something more
> readable.
>   - Fixed a bug about how the type of a TDMA operation was tested in
> mv_cesa_dma_cleanup and mv_cesa_dma_prepare, I created a separated
> commit for that (see PATCH 03/10)
>   - Renamed variables in mv_cesa_dma_add_iv_op
>   - Removed the flag CESA_TDMA_DATA from mv_cesa_dma_add_iv_op (not
> needed)
> 
>  drivers/crypto/marvell/cesa.c   |  4 
>  drivers/crypto/marvell/cesa.h   |  5 +
>  drivers/crypto/marvell/cipher.c | 32 +++-
>  drivers/crypto/marvell/tdma.c   | 29 +
>  4 files changed, 61 insertions(+), 9 deletions(-)
> 

[...]

> @@ -135,21 +140,21 @@ static int mv_cesa_ablkcipher_process(struct
> crypto_async_request *req, {
>   struct ablkcipher_request *ablkreq =
> ablkcipher_request_cast(req); struct mv_cesa_ablkcipher_req *creq =
> ablkcipher_request_ctx(ablkreq);
> - struct mv_cesa_ablkcipher_std_req *sreq = >req.std;
> - struct mv_cesa_engine *engine = sreq->base.engine;
> + struct mv_cesa_tdma_req *dreq;
> + unsigned int ivsize;
>   int ret;
>  
> - if (creq->req.base.type == CESA_DMA_REQ)
> - ret = mv_cesa_dma_process(>req.dma, status);
> - else
> - ret = mv_cesa_ablkcipher_std_process(ablkreq,
> status);
> + if (creq->req.base.type == CESA_STD_REQ)
> + return mv_cesa_ablkcipher_std_process(ablkreq,
> status); 
> + ret = mv_cesa_dma_process(>req.dma, status);
>   if (ret)
>   return ret;
>  
> - memcpy_fromio(ablkreq->info,
> -   engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET,
> -
> crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq)));
> + dreq = >req.dma;
> + ivsize =
> + crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq));

My bad, my mailer wrapped the line: please put the assignment on the
same line and use a temporary variable if it exceeds 80 chars.


> + memcpy_fromio(ablkreq->info, dreq->chain.last->data, ivsize);
>  
>   return 0;
>  }

--
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 03/10] crypto: marvell: Fix wrong type check in dma functions

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:02 +0200
Romain Perier  wrote:

> So far, the way that the type of a TDMA operation was checked was
> wrong. We have to use the type mask in order to get the right part of
> the flag containing the type of the operation.
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

Thanks for fixing it.

> ---
>  drivers/crypto/marvell/tdma.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/crypto/marvell/tdma.c
> b/drivers/crypto/marvell/tdma.c index 8c86bb6..de8c253 100644
> --- a/drivers/crypto/marvell/tdma.c
> +++ b/drivers/crypto/marvell/tdma.c
> @@ -64,8 +64,9 @@ void mv_cesa_dma_cleanup(struct mv_cesa_tdma_req
> *dreq) 
>   for (tdma = dreq->chain.first; tdma;) {
>   struct mv_cesa_tdma_desc *old_tdma = tdma;
> + u32 type = tdma->flags & CESA_TDMA_TYPE_MSK;
>  
> - if (tdma->flags & CESA_TDMA_OP)
> + if (type == CESA_TDMA_OP)
>   dma_pool_free(cesa_dev->dma->op_pool,
> tdma->op, le32_to_cpu(tdma->src));
>  
> @@ -90,7 +91,7 @@ void mv_cesa_dma_prepare(struct mv_cesa_tdma_req
> *dreq, if (tdma->flags & CESA_TDMA_SRC_IN_SRAM)
>   tdma->src = cpu_to_le32(tdma->src +
> engine->sram_dma); 
> - if (tdma->flags & CESA_TDMA_OP)
> + if ((tdma->flags & CESA_TDMA_TYPE_MSK) ==
> CESA_TDMA_OP) mv_cesa_adjust_op(engine, tdma->op);
>   }
>  }

--
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 02/10] crypto: marvell: Check engine is not already running when enabling a req

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:01 +0200
Romain Perier  wrote:

> Add a BUG_ON() call when the driver tries to launch a crypto request
> while the engine is still processing the previous one. This replaces
> a silent system hang by a verbose kernel panic with the associated
> backtrace to let the user know that something went wrong in the CESA
> driver.
> 
> Signed-off-by: Romain Perier 

Acked-by: Boris Brezillon 

> ---
> 
> Changes in v2:
>   - Reworded the commit message
>   - Fixed cosmetic changes
> 
>  drivers/crypto/marvell/cipher.c | 2 ++
>  drivers/crypto/marvell/hash.c   | 2 ++
>  drivers/crypto/marvell/tdma.c   | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/drivers/crypto/marvell/cipher.c
> b/drivers/crypto/marvell/cipher.c index dcf1fce..ec23609 100644
> --- a/drivers/crypto/marvell/cipher.c
> +++ b/drivers/crypto/marvell/cipher.c
> @@ -106,6 +106,8 @@ static void mv_cesa_ablkcipher_std_step(struct
> ablkcipher_request *req) 
>   mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE);
>   writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs +
> CESA_SA_CFG);
> + BUG_ON(readl(engine->regs + CESA_SA_CMD) &
> +  CESA_SA_CMD_EN_CESA_SA_ACCL0);

Still incorrectly aligned ;).

>   writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs +
> CESA_SA_CMD); }
>  
> diff --git a/drivers/crypto/marvell/hash.c
> b/drivers/crypto/marvell/hash.c index 7ca2e0f..80bddd7 100644
> --- a/drivers/crypto/marvell/hash.c
> +++ b/drivers/crypto/marvell/hash.c
> @@ -237,6 +237,8 @@ static void mv_cesa_ahash_std_step(struct
> ahash_request *req) 
>   mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE);
>   writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs +
> CESA_SA_CFG);
> + BUG_ON(readl(engine->regs + CESA_SA_CMD) &
> +CESA_SA_CMD_EN_CESA_SA_ACCL0);
>   writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs +
> CESA_SA_CMD); }
>  
> diff --git a/drivers/crypto/marvell/tdma.c
> b/drivers/crypto/marvell/tdma.c index 7642798..8c86bb6 100644
> --- a/drivers/crypto/marvell/tdma.c
> +++ b/drivers/crypto/marvell/tdma.c
> @@ -53,6 +53,8 @@ void mv_cesa_dma_step(struct mv_cesa_tdma_req *dreq)
>  engine->regs + CESA_SA_CFG);
>   writel_relaxed(dreq->chain.first->cur_dma,
>  engine->regs + CESA_TDMA_NEXT_ADDR);
> + BUG_ON(readl(engine->regs + CESA_SA_CMD) &
> +CESA_SA_CMD_EN_CESA_SA_ACCL0);
>   writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs +
> CESA_SA_CMD); }
>  

--
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 01/10] crypto: marvell: Add a macro constant for the size of the crypto queue

2016-06-17 Thread Boris Brezillon
On Fri, 17 Jun 2016 13:24:00 +0200
Romain Perier  wrote:

> Adding a macro constant to be used for the size of the crypto queue,
> instead of using a numeric value directly. It will be easier to
> maintain in case we add more than one crypto queue of the same size.
> 
> Signed-off-by: Romain Perier 

You forgot

Acked-by: Boris Brezillon 

> ---
>  drivers/crypto/marvell/cesa.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/crypto/marvell/cesa.c
> b/drivers/crypto/marvell/cesa.c index 056a754..fb403e1 100644
> --- a/drivers/crypto/marvell/cesa.c
> +++ b/drivers/crypto/marvell/cesa.c
> @@ -31,6 +31,9 @@
>  
>  #include "cesa.h"
>  
> +/* Limit of the crypto queue before reaching the backlog */
> +#define CESA_CRYPTO_DEFAULT_MAX_QLEN 50
> +
>  static int allhwsupport = !IS_ENABLED(CONFIG_CRYPTO_DEV_MV_CESA);
>  module_param_named(allhwsupport, allhwsupport, int, 0444);
>  MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware
> (even it if overlaps with the mv_cesa driver)"); @@ -416,7 +419,7 @@
> static int mv_cesa_probe(struct platform_device *pdev) return -ENOMEM;
>  
>   spin_lock_init(>lock);
> - crypto_init_queue(>queue, 50);
> + crypto_init_queue(>queue,
> CESA_CRYPTO_DEFAULT_MAX_QLEN); res =
> platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
> cesa->regs = devm_ioremap_resource(dev, res); if (IS_ERR(cesa->regs))

--
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: caam - replace deprecated EXTRA_CFLAGS

2016-06-17 Thread Horia Ioan Geanta Neag
On 6/16/2016 4:33 PM, Tudor Ambarus wrote:
> EXTRA_CFLAGS is still supported but its usage is deprecated.
> 
> Signed-off-by: Tudor Ambarus 

Reviewed-by: Horia Geantă 

> ---
>  drivers/crypto/caam/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile
> index 399ad55..3e9d3e1 100644
> --- a/drivers/crypto/caam/Makefile
> +++ b/drivers/crypto/caam/Makefile
> @@ -2,7 +2,7 @@
>  # Makefile for the CAAM backend and dependent components
>  #
>  ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG), y)
> - EXTRA_CFLAGS := -DDEBUG
> + ccflags-y := -DDEBUG
>  endif
>  
>  ccflags-y += -I$(srctree)/crypto
> 

--
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 06/10] crypto: marvell: Add a complete operation for async requests

2016-06-17 Thread Romain Perier
So far, the 'process' operation was used to check if the current request
was correctly handled by the engine, if it was the case it copied
information from the SRAM to the main memory. Now, we split this
operation. We keep the 'process' operation, which still checks if the
request was correctly handled by the engine or not, then we add a new
operation for completion. The 'complete' method copies the content of
the SRAM to memory. This will soon become useful if we want to call
the process and the complete operations from different locations
depending on the type of the request (different cleanup logic).

Signed-off-by: Romain Perier 
---

Changes in v2:

  - Removed useless cosmetic change added for checkpatch (which
had nothing to do with the patch itself)
  - Removed duplicated initialization of 'ivsize'
mv_cesa_ablkcipher_complete.
  - Replace memcpy_fromio by memcpy in mv_cesa_ablkcipher_complete

 drivers/crypto/marvell/cesa.c   |  1 +
 drivers/crypto/marvell/cesa.h   |  3 +++
 drivers/crypto/marvell/cipher.c | 28 +++-
 drivers/crypto/marvell/hash.c   | 22 --
 4 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index fe04d1b..af96426 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -98,6 +98,7 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
engine->req = NULL;
mv_cesa_dequeue_req_unlocked(engine);
spin_unlock_bh(>lock);
+   ctx->ops->complete(req);
ctx->ops->cleanup(req);
local_bh_disable();
req->complete(req, res);
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index e67e3f1..c463528 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -456,6 +456,8 @@ struct mv_cesa_engine {
  * code)
  * @step:  launch the crypto operation on the next chunk
  * @cleanup:   cleanup the crypto request (release associated data)
+ * @complete:  complete the request, i.e copy result from sram or contexts
+ * when it is needed.
  */
 struct mv_cesa_req_ops {
void (*prepare)(struct crypto_async_request *req,
@@ -463,6 +465,7 @@ struct mv_cesa_req_ops {
int (*process)(struct crypto_async_request *req, u32 status);
void (*step)(struct crypto_async_request *req);
void (*cleanup)(struct crypto_async_request *req);
+   void (*complete)(struct crypto_async_request *req);
 };
 
 /**
diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index ffe0f4a..175ce76 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -118,7 +118,6 @@ static int mv_cesa_ablkcipher_std_process(struct 
ablkcipher_request *req,
struct mv_cesa_ablkcipher_std_req *sreq = >std;
struct mv_cesa_engine *engine = creq->base.engine;
size_t len;
-   unsigned int ivsize;
 
len = sg_pcopy_from_buffer(req->dst, creq->dst_nents,
   engine->sram + CESA_SA_DATA_SRAM_OFFSET,
@@ -128,10 +127,6 @@ static int mv_cesa_ablkcipher_std_process(struct 
ablkcipher_request *req,
if (sreq->offset < req->nbytes)
return -EINPROGRESS;
 
-   ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
-   memcpy_fromio(req->info,
- engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET, ivsize);
-
return 0;
 }
 
@@ -211,11 +206,34 @@ mv_cesa_ablkcipher_req_cleanup(struct 
crypto_async_request *req)
mv_cesa_ablkcipher_cleanup(ablkreq);
 }
 
+static void
+mv_cesa_ablkcipher_complete(struct crypto_async_request *req)
+{
+   struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
+   struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
+   struct mv_cesa_engine *engine = creq->base.engine;
+   unsigned int ivsize;
+
+   ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq));
+
+   if (mv_cesa_req_get_type(>base) == CESA_DMA_REQ) {
+   struct mv_cesa_req *basereq;
+
+   basereq = >base;
+   memcpy(ablkreq->info, basereq->chain.last->data, ivsize);
+   } else {
+   memcpy_fromio(ablkreq->info,
+ engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET,
+ ivsize);
+   }
+}
+
 static const struct mv_cesa_req_ops mv_cesa_ablkcipher_req_ops = {
.step = mv_cesa_ablkcipher_step,
.process = mv_cesa_ablkcipher_process,
.prepare = mv_cesa_ablkcipher_prepare,
.cleanup = mv_cesa_ablkcipher_req_cleanup,
+   .complete = mv_cesa_ablkcipher_complete,
 };
 
 static int 

[PATCH v2 02/10] crypto: marvell: Check engine is not already running when enabling a req

2016-06-17 Thread Romain Perier
Add a BUG_ON() call when the driver tries to launch a crypto request
while the engine is still processing the previous one. This replaces
a silent system hang by a verbose kernel panic with the associated
backtrace to let the user know that something went wrong in the CESA
driver.

Signed-off-by: Romain Perier 
---

Changes in v2:
  - Reworded the commit message
  - Fixed cosmetic changes

 drivers/crypto/marvell/cipher.c | 2 ++
 drivers/crypto/marvell/hash.c   | 2 ++
 drivers/crypto/marvell/tdma.c   | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index dcf1fce..ec23609 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -106,6 +106,8 @@ static void mv_cesa_ablkcipher_std_step(struct 
ablkcipher_request *req)
 
mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE);
writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs + CESA_SA_CFG);
+   BUG_ON(readl(engine->regs + CESA_SA_CMD) &
+CESA_SA_CMD_EN_CESA_SA_ACCL0);
writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD);
 }
 
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index 7ca2e0f..80bddd7 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -237,6 +237,8 @@ static void mv_cesa_ahash_std_step(struct ahash_request 
*req)
 
mv_cesa_set_int_mask(engine, CESA_SA_INT_ACCEL0_DONE);
writel_relaxed(CESA_SA_CFG_PARA_DIS, engine->regs + CESA_SA_CFG);
+   BUG_ON(readl(engine->regs + CESA_SA_CMD) &
+  CESA_SA_CMD_EN_CESA_SA_ACCL0);
writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD);
 }
 
diff --git a/drivers/crypto/marvell/tdma.c b/drivers/crypto/marvell/tdma.c
index 7642798..8c86bb6 100644
--- a/drivers/crypto/marvell/tdma.c
+++ b/drivers/crypto/marvell/tdma.c
@@ -53,6 +53,8 @@ void mv_cesa_dma_step(struct mv_cesa_tdma_req *dreq)
   engine->regs + CESA_SA_CFG);
writel_relaxed(dreq->chain.first->cur_dma,
   engine->regs + CESA_TDMA_NEXT_ADDR);
+   BUG_ON(readl(engine->regs + CESA_SA_CMD) &
+  CESA_SA_CMD_EN_CESA_SA_ACCL0);
writel(CESA_SA_CMD_EN_CESA_SA_ACCL0, engine->regs + CESA_SA_CMD);
 }
 
-- 
2.7.4

--
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 04/10] crypto: marvell: Copy IV vectors by DMA transfers for acipher requests

2016-06-17 Thread Romain Perier
Add a TDMA descriptor at the end of the request for copying the
output IV vector via a DMA transfer. This is a good way for offloading
as much as processing as possible to the DMA and the crypto engine.
This is also required for processing multiple cipher requests
in chained mode, otherwise the content of the IV vector would be
overwritten by the last processed request.

Signed-off-by: Romain Perier 
---

Changes in v2:
  - Reworded the commit message, the term 'asynchronously' was ambigous
  - Changed the value of CESA_TDMA_IV from 4 to 3
  - Adding missing blank lines
  - Rewrote the function mv_cesa_ablkcipher_process to something more
readable.
  - Fixed a bug about how the type of a TDMA operation was tested in
mv_cesa_dma_cleanup and mv_cesa_dma_prepare, I created a separated
commit for that (see PATCH 03/10)
  - Renamed variables in mv_cesa_dma_add_iv_op
  - Removed the flag CESA_TDMA_DATA from mv_cesa_dma_add_iv_op (not needed)

 drivers/crypto/marvell/cesa.c   |  4 
 drivers/crypto/marvell/cesa.h   |  5 +
 drivers/crypto/marvell/cipher.c | 32 +++-
 drivers/crypto/marvell/tdma.c   | 29 +
 4 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index fb403e1..93700cd 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -312,6 +312,10 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
if (!dma->padding_pool)
return -ENOMEM;
 
+   dma->iv_pool = dmam_pool_create("cesa_iv", dev, 16, 1, 0);
+   if (!dma->iv_pool)
+   return -ENOMEM;
+
cesa->dma = dma;
 
return 0;
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 74071e4..685a627 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -275,6 +275,7 @@ struct mv_cesa_op_ctx {
 #define CESA_TDMA_DUMMY0
 #define CESA_TDMA_DATA 1
 #define CESA_TDMA_OP   2
+#define CESA_TDMA_IV   3
 
 /**
  * struct mv_cesa_tdma_desc - TDMA descriptor
@@ -390,6 +391,7 @@ struct mv_cesa_dev_dma {
struct dma_pool *op_pool;
struct dma_pool *cache_pool;
struct dma_pool *padding_pool;
+   struct dma_pool *iv_pool;
 };
 
 /**
@@ -790,6 +792,9 @@ mv_cesa_tdma_desc_iter_init(struct mv_cesa_tdma_chain 
*chain)
memset(chain, 0, sizeof(*chain));
 }
 
+int mv_cesa_dma_add_iv_op(struct mv_cesa_tdma_chain *chain, dma_addr_t src,
+ u32 size, u32 flags, gfp_t gfp_flags);
+
 struct mv_cesa_op_ctx *mv_cesa_dma_add_op(struct mv_cesa_tdma_chain *chain,
const struct mv_cesa_op_ctx *op_templ,
bool skip_ctx,
diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index ec23609..ded5feb 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -118,6 +118,7 @@ static int mv_cesa_ablkcipher_std_process(struct 
ablkcipher_request *req,
struct mv_cesa_ablkcipher_std_req *sreq = >req.std;
struct mv_cesa_engine *engine = sreq->base.engine;
size_t len;
+   unsigned int ivsize;
 
len = sg_pcopy_from_buffer(req->dst, creq->dst_nents,
   engine->sram + CESA_SA_DATA_SRAM_OFFSET,
@@ -127,6 +128,10 @@ static int mv_cesa_ablkcipher_std_process(struct 
ablkcipher_request *req,
if (sreq->offset < req->nbytes)
return -EINPROGRESS;
 
+   ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
+   memcpy_fromio(req->info,
+ engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET, ivsize);
+
return 0;
 }
 
@@ -135,21 +140,21 @@ static int mv_cesa_ablkcipher_process(struct 
crypto_async_request *req,
 {
struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
-   struct mv_cesa_ablkcipher_std_req *sreq = >req.std;
-   struct mv_cesa_engine *engine = sreq->base.engine;
+   struct mv_cesa_tdma_req *dreq;
+   unsigned int ivsize;
int ret;
 
-   if (creq->req.base.type == CESA_DMA_REQ)
-   ret = mv_cesa_dma_process(>req.dma, status);
-   else
-   ret = mv_cesa_ablkcipher_std_process(ablkreq, status);
+   if (creq->req.base.type == CESA_STD_REQ)
+   return mv_cesa_ablkcipher_std_process(ablkreq, status);
 
+   ret = mv_cesa_dma_process(>req.dma, status);
if (ret)
return ret;
 
-   memcpy_fromio(ablkreq->info,
- engine->sram + CESA_SA_CRYPT_IV_SRAM_OFFSET,
- 
crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ablkreq)));
+   dreq = >req.dma;

[PATCH v2 10/10] crypto: marvell: Increase the size of the crypto queue

2016-06-17 Thread Romain Perier
Now that crypto requests are chained together at the DMA level, we
increase the size of the crypto queue for each engine. The result is
that as the backlog list is reached later, it does not stop the crypto
stack from sending asychronous requests, so more cryptographic tasks
are processed by the engines.

Signed-off-by: Romain Perier 
---
 drivers/crypto/marvell/cesa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index bb91156..5147073 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -32,7 +32,7 @@
 #include "cesa.h"
 
 /* Limit of the crypto queue before reaching the backlog */
-#define CESA_CRYPTO_DEFAULT_MAX_QLEN 50
+#define CESA_CRYPTO_DEFAULT_MAX_QLEN 128
 
 static int allhwsupport = !IS_ENABLED(CONFIG_CRYPTO_DEV_MV_CESA);
 module_param_named(allhwsupport, allhwsupport, int, 0444);
-- 
2.7.4

--
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 07/10] crypto: marvell: Move SRAM I/O operations to step functions

2016-06-17 Thread Romain Perier
Currently the crypto requests were sent to engines sequentially.
This commit moves the SRAM I/O operations from the prepare to the step
functions. It provides flexibility for future works and allow to prepare
a request while the engine is running.

Signed-off-by: Romain Perier 
---
 drivers/crypto/marvell/cipher.c |  6 +++---
 drivers/crypto/marvell/hash.c   | 18 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index 175ce76..79d4175 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -89,6 +89,9 @@ static void mv_cesa_ablkcipher_std_step(struct 
ablkcipher_request *req)
size_t  len = min_t(size_t, req->nbytes - sreq->offset,
CESA_SA_SRAM_PAYLOAD_SIZE);
 
+   mv_cesa_adjust_op(engine, >op);
+   memcpy_toio(engine->sram, >op, sizeof(sreq->op));
+
len = sg_pcopy_to_buffer(req->src, creq->src_nents,
 engine->sram + CESA_SA_DATA_SRAM_OFFSET,
 len, sreq->offset);
@@ -177,12 +180,9 @@ mv_cesa_ablkcipher_std_prepare(struct ablkcipher_request 
*req)
 {
struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(req);
struct mv_cesa_ablkcipher_std_req *sreq = >std;
-   struct mv_cesa_engine *engine = creq->base.engine;
 
sreq->size = 0;
sreq->offset = 0;
-   mv_cesa_adjust_op(engine, >op);
-   memcpy_toio(engine->sram, >op, sizeof(sreq->op));
 }
 
 static inline void mv_cesa_ablkcipher_prepare(struct crypto_async_request *req,
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index 09665a7..e1f8acd 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -162,6 +162,15 @@ static void mv_cesa_ahash_std_step(struct ahash_request 
*req)
unsigned int new_cache_ptr = 0;
u32 frag_mode;
size_t  len;
+   unsigned int digsize;
+   int i;
+
+   mv_cesa_adjust_op(engine, >op_tmpl);
+   memcpy_toio(engine->sram, >op_tmpl, sizeof(creq->op_tmpl));
+
+   digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
+   for (i = 0; i < digsize / 4; i++)
+   writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
 
if (creq->cache_ptr)
memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
@@ -265,11 +274,8 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request 
*req)
 {
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
struct mv_cesa_ahash_std_req *sreq = >req.std;
-   struct mv_cesa_engine *engine = creq->base.engine;
 
sreq->offset = 0;
-   mv_cesa_adjust_op(engine, >op_tmpl);
-   memcpy_toio(engine->sram, >op_tmpl, sizeof(creq->op_tmpl));
 }
 
 static void mv_cesa_ahash_step(struct crypto_async_request *req)
@@ -336,8 +342,6 @@ static void mv_cesa_ahash_prepare(struct 
crypto_async_request *req,
 {
struct ahash_request *ahashreq = ahash_request_cast(req);
struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
-   unsigned int digsize;
-   int i;
 
creq->base.engine = engine;
 
@@ -345,10 +349,6 @@ static void mv_cesa_ahash_prepare(struct 
crypto_async_request *req,
mv_cesa_ahash_dma_prepare(ahashreq);
else
mv_cesa_ahash_std_prepare(ahashreq);
-
-   digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(ahashreq));
-   for (i = 0; i < digsize / 4; i++)
-   writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
 }
 
 static void mv_cesa_ahash_req_cleanup(struct crypto_async_request *req)
-- 
2.7.4

--
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 03/10] crypto: marvell: Fix wrong type check in dma functions

2016-06-17 Thread Romain Perier
So far, the way that the type of a TDMA operation was checked was wrong.
We have to use the type mask in order to get the right part of the flag
containing the type of the operation.

Signed-off-by: Romain Perier 
---
 drivers/crypto/marvell/tdma.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/marvell/tdma.c b/drivers/crypto/marvell/tdma.c
index 8c86bb6..de8c253 100644
--- a/drivers/crypto/marvell/tdma.c
+++ b/drivers/crypto/marvell/tdma.c
@@ -64,8 +64,9 @@ void mv_cesa_dma_cleanup(struct mv_cesa_tdma_req *dreq)
 
for (tdma = dreq->chain.first; tdma;) {
struct mv_cesa_tdma_desc *old_tdma = tdma;
+   u32 type = tdma->flags & CESA_TDMA_TYPE_MSK;
 
-   if (tdma->flags & CESA_TDMA_OP)
+   if (type == CESA_TDMA_OP)
dma_pool_free(cesa_dev->dma->op_pool, tdma->op,
  le32_to_cpu(tdma->src));
 
@@ -90,7 +91,7 @@ void mv_cesa_dma_prepare(struct mv_cesa_tdma_req *dreq,
if (tdma->flags & CESA_TDMA_SRC_IN_SRAM)
tdma->src = cpu_to_le32(tdma->src + engine->sram_dma);
 
-   if (tdma->flags & CESA_TDMA_OP)
+   if ((tdma->flags & CESA_TDMA_TYPE_MSK) == CESA_TDMA_OP)
mv_cesa_adjust_op(engine, tdma->op);
}
 }
-- 
2.7.4

--
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 01/10] crypto: marvell: Add a macro constant for the size of the crypto queue

2016-06-17 Thread Romain Perier
Adding a macro constant to be used for the size of the crypto queue,
instead of using a numeric value directly. It will be easier to
maintain in case we add more than one crypto queue of the same size.

Signed-off-by: Romain Perier 
---
 drivers/crypto/marvell/cesa.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 056a754..fb403e1 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -31,6 +31,9 @@
 
 #include "cesa.h"
 
+/* Limit of the crypto queue before reaching the backlog */
+#define CESA_CRYPTO_DEFAULT_MAX_QLEN 50
+
 static int allhwsupport = !IS_ENABLED(CONFIG_CRYPTO_DEV_MV_CESA);
 module_param_named(allhwsupport, allhwsupport, int, 0444);
 MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if 
overlaps with the mv_cesa driver)");
@@ -416,7 +419,7 @@ static int mv_cesa_probe(struct platform_device *pdev)
return -ENOMEM;
 
spin_lock_init(>lock);
-   crypto_init_queue(>queue, 50);
+   crypto_init_queue(>queue, CESA_CRYPTO_DEFAULT_MAX_QLEN);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
cesa->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(cesa->regs))
-- 
2.7.4

--
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 09/10] crypto: marvell: Add support for chaining crypto requests in TDMA mode

2016-06-17 Thread Romain Perier
The Cryptographic Engines and Security Accelerators (CESA) supports the
Multi-Packet Chain Mode. With this mode enabled, multiple tdma requests
can be chained and processed by the hardware without software
intervention. This mode was already activated, however the crypto
requests were not chained together. By doing so, we reduce significantly
the number of IRQs. Instead of being interrupted at the end of each
crypto request, we are interrupted at the end of the last cryptographic
request processed by the engine.

This commits re-factorizes the code, changes the code architecture and
adds the required data structures to chain cryptographic requests
together before sending them to an engine (stopped or possibly already
running).

Signed-off-by: Romain Perier 
---

Changes in v2:

  - Reworded the commit message
  - Fixed cosmetic changes: coding styles issues, missing blank lines
  - Reworked mv_cesa_rearm_engine: lock handling is simpler
  - Removed the call to the complete operation in mv_cesa_std_process,
in case of errors (not required)
  - Squashed the removal of the '.prepare' fields (cipher.c, hash.c)
into another commit (see PATCH 08/10).
  - In mv_cesa_tdma_process only treat the status argument for the last
request, use 'normal' status for the other ones.
  - Added a comment for explaining how the errors are notified to the
cesa core.

 drivers/crypto/marvell/cesa.c   | 115 +++-
 drivers/crypto/marvell/cesa.h   |  39 +-
 drivers/crypto/marvell/cipher.c |   2 +-
 drivers/crypto/marvell/hash.c   |   6 +++
 drivers/crypto/marvell/tdma.c   |  88 ++
 5 files changed, 223 insertions(+), 27 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index f9e6688..bb91156 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -40,14 +40,33 @@ MODULE_PARM_DESC(allhwsupport, "Enable support for all 
hardware (even it if over
 
 struct mv_cesa_dev *cesa_dev;
 
-static void mv_cesa_dequeue_req_unlocked(struct mv_cesa_engine *engine)
+struct crypto_async_request *
+mv_cesa_dequeue_req_locked(struct mv_cesa_engine *engine,
+  struct crypto_async_request **backlog)
 {
-   struct crypto_async_request *req, *backlog;
-   struct mv_cesa_ctx *ctx;
+   struct crypto_async_request *req;
 
-   backlog = crypto_get_backlog(>queue);
+   *backlog = crypto_get_backlog(>queue);
req = crypto_dequeue_request(>queue);
-   engine->req = req;
+
+   if (!req)
+   return NULL;
+
+   return req;
+}
+
+static void mv_cesa_rearm_engine(struct mv_cesa_engine *engine)
+{
+   struct crypto_async_request *req = NULL, *backlog = NULL;
+   struct mv_cesa_ctx *ctx;
+
+
+   spin_lock_bh(>lock);
+   if (!engine->req) {
+   req = mv_cesa_dequeue_req_locked(engine, );
+   engine->req = req;
+   }
+   spin_unlock_bh(>lock);
 
if (!req)
return;
@@ -57,6 +76,46 @@ static void mv_cesa_dequeue_req_unlocked(struct 
mv_cesa_engine *engine)
 
ctx = crypto_tfm_ctx(req->tfm);
ctx->ops->step(req);
+
+   return;
+}
+
+static int mv_cesa_std_process(struct mv_cesa_engine *engine, u32 status)
+{
+   struct crypto_async_request *req;
+   struct mv_cesa_ctx *ctx;
+   int res;
+
+   req = engine->req;
+   ctx = crypto_tfm_ctx(req->tfm);
+   res = ctx->ops->process(req, status);
+
+   if (res == 0) {
+   ctx->ops->complete(req);
+   mv_cesa_engine_enqueue_complete_request(engine, req);
+   } else if (res == -EINPROGRESS) {
+   ctx->ops->step(req);
+   }
+
+   return res;
+}
+
+static int mv_cesa_int_process(struct mv_cesa_engine *engine, u32 status)
+{
+   if (engine->chain.first && engine->chain.last)
+   return mv_cesa_tdma_process(engine, status);
+
+   return mv_cesa_std_process(engine, status);
+}
+
+static inline void
+mv_cesa_complete_req(struct mv_cesa_ctx *ctx, struct crypto_async_request *req,
+int res)
+{
+   ctx->ops->cleanup(req);
+   local_bh_disable();
+   req->complete(req, res);
+   local_bh_enable();
 }
 
 static irqreturn_t mv_cesa_int(int irq, void *priv)
@@ -83,26 +142,31 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
writel(~status, engine->regs + CESA_SA_FPGA_INT_STATUS);
writel(~status, engine->regs + CESA_SA_INT_STATUS);
 
+   /* Process fetched requests */
+   res = mv_cesa_int_process(engine, status & mask);
ret = IRQ_HANDLED;
+
spin_lock_bh(>lock);
req = engine->req;
+   if (res != -EINPROGRESS)
+   engine->req = NULL;
spin_unlock_bh(>lock);
-   if (req) {
-   ctx = 

[PATCH v2 08/10] crypto: marvell: Add load balancing between engines

2016-06-17 Thread Romain Perier
This commits adds support for fine grained load balancing on
multi-engine IPs. The engine is pre-selected based on its current load
and on the weight of the crypto request that is about to be processed.
The global crypto queue is also moved to each engine. These changes are
required to allow chaining crypto requests at the DMA level. By using
a crypto queue per engine, we make sure that we keep the state of the
tdma chain synchronized with the crypto queue. We also reduce contention
on 'cesa_dev->lock' and improve parallelism.

Signed-off-by: Romain Perier 
---

Changes in v2:

  - Reworded the commit message
  - Moved the code about SRAM I/O operations from this commit to
a separated commit (see PATCH 07/10).

 drivers/crypto/marvell/cesa.c   | 30 ++
 drivers/crypto/marvell/cesa.h   | 29 +
 drivers/crypto/marvell/cipher.c | 57 ++---
 drivers/crypto/marvell/hash.c   | 50 ++--
 4 files changed, 82 insertions(+), 84 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index af96426..f9e6688 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -45,11 +45,9 @@ static void mv_cesa_dequeue_req_unlocked(struct 
mv_cesa_engine *engine)
struct crypto_async_request *req, *backlog;
struct mv_cesa_ctx *ctx;
 
-   spin_lock_bh(_dev->lock);
-   backlog = crypto_get_backlog(_dev->queue);
-   req = crypto_dequeue_request(_dev->queue);
+   backlog = crypto_get_backlog(>queue);
+   req = crypto_dequeue_request(>queue);
engine->req = req;
-   spin_unlock_bh(_dev->lock);
 
if (!req)
return;
@@ -58,7 +56,6 @@ static void mv_cesa_dequeue_req_unlocked(struct 
mv_cesa_engine *engine)
backlog->complete(backlog, -EINPROGRESS);
 
ctx = crypto_tfm_ctx(req->tfm);
-   ctx->ops->prepare(req, engine);
ctx->ops->step(req);
 }
 
@@ -116,21 +113,19 @@ int mv_cesa_queue_req(struct crypto_async_request *req,
  struct mv_cesa_req *creq)
 {
int ret;
-   int i;
+   struct mv_cesa_engine *engine = creq->engine;
 
-   spin_lock_bh(_dev->lock);
-   ret = crypto_enqueue_request(_dev->queue, req);
-   spin_unlock_bh(_dev->lock);
+   spin_lock_bh(>lock);
+   ret = crypto_enqueue_request(>queue, req);
+   spin_unlock_bh(>lock);
 
if (ret != -EINPROGRESS)
return ret;
 
-   for (i = 0; i < cesa_dev->caps->nengines; i++) {
-   spin_lock_bh(_dev->engines[i].lock);
-   if (!cesa_dev->engines[i].req)
-   mv_cesa_dequeue_req_unlocked(_dev->engines[i]);
-   spin_unlock_bh(_dev->engines[i].lock);
-   }
+   spin_lock_bh(>lock);
+   if (!engine->req)
+   mv_cesa_dequeue_req_unlocked(engine);
+   spin_unlock_bh(>lock);
 
return -EINPROGRESS;
 }
@@ -425,7 +420,7 @@ static int mv_cesa_probe(struct platform_device *pdev)
return -ENOMEM;
 
spin_lock_init(>lock);
-   crypto_init_queue(>queue, CESA_CRYPTO_DEFAULT_MAX_QLEN);
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
cesa->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(cesa->regs))
@@ -498,6 +493,9 @@ static int mv_cesa_probe(struct platform_device *pdev)
engine);
if (ret)
goto err_cleanup;
+
+   crypto_init_queue(>queue, CESA_CRYPTO_DEFAULT_MAX_QLEN);
+   atomic_set(>load, 0);
}
 
cesa_dev = cesa;
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index c463528..644be35 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -400,7 +400,6 @@ struct mv_cesa_dev_dma {
  * @regs:  device registers
  * @sram_size: usable SRAM size
  * @lock:  device lock
- * @queue: crypto request queue
  * @engines:   array of engines
  * @dma:   dma pools
  *
@@ -412,7 +411,6 @@ struct mv_cesa_dev {
struct device *dev;
unsigned int sram_size;
spinlock_t lock;
-   struct crypto_queue queue;
struct mv_cesa_engine *engines;
struct mv_cesa_dev_dma *dma;
 };
@@ -431,6 +429,8 @@ struct mv_cesa_dev {
  * @int_mask:  interrupt mask cache
  * @pool:  memory pool pointing to the memory region reserved in
  * SRAM
+ * @queue: fifo of the pending crypto requests
+ * @load:  engine load counter, useful for load balancing
  *
  * Structure storing CESA engine information.
  */
@@ -446,11 +446,12 @@ struct mv_cesa_engine {
size_t max_req_len;
u32 int_mask;
struct gen_pool *pool;
+   struct crypto_queue queue;
+   atomic_t load;
 };
 
 /**
  * struct 

[PATCH v2 00/10] Chain crypto requests together at the DMA level

2016-06-17 Thread Romain Perier
The Cryptographic Engines and Security Accelerators (CESA) supports
the TDMA chained mode support. When this mode is enabled and crypto
requests are chained at the DMA level, multiple crypto requests can be
handled by the hardware engine without requiring any software
intervention. This approach limits the number of interrupts generated
by the engines thus improving its throughput and making the whole system
behave nicely under heavy crypto load.

Benchmarking results with dmcrypt
=
I/O readI/O write
Before  81.7 MB/s   31.7 MB/s
After   129  MB/s   39.8 MB/s

Improvement +57.8 % +25.5 %

Romain Perier (10):
  crypto: marvell: Add a macro constant for the size of the crypto queue
  crypto: marvell: Check engine is not already running when enabling a
req
  crypto: marvell: Fix wrong type check in dma functions
  crypto: marvell: Copy IV vectors by DMA transfers for acipher requests
  crypto: marvell: Move tdma chain out of mv_cesa_tdma_req and remove it
  crypto: marvell: Add a complete operation for async requests
  crypto: marvell: Move SRAM I/O operations to step functions
  crypto: marvell: Add load balancing between engines
  crypto: marvell: Add support for chaining crypto requests in TDMA mode
  crypto: marvell: Increase the size of the crypto queue

 drivers/crypto/marvell/cesa.c   | 142 +++-
 drivers/crypto/marvell/cesa.h   | 120 +-
 drivers/crypto/marvell/cipher.c | 157 
 drivers/crypto/marvell/hash.c   | 150 ++
 drivers/crypto/marvell/tdma.c   | 132 +++--
 5 files changed, 483 insertions(+), 218 deletions(-)

-- 
2.7.4
--
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 7/7] crypto: marvell: Add support for chaining crypto requests in TDMA mode

2016-06-17 Thread Romain Perier

Hello,

Le 15/06/2016 23:43, Boris Brezillon a écrit :

On Wed, 15 Jun 2016 21:15:34 +0200
Romain Perier  wrote:


The Cryptographic Engines and Security Accelerators (CESA) supports the
Multi-Packet Chain Mode. With this mode enabled, multiple tdma requests
can be chained and processed by the hardware without software
interferences.


intervention.


ack



Not necessarily before sending them to the engine, it can be done while
the engine is running.


I re-worded it


Coding style issue:

struct crypto_async_request *
mv_cesa_dequeue_req_locked(struct mv_cesa_engine *engine,
   struct crypto_async_request **backlog)


ack




+{
+   struct crypto_async_request *req;
+
+   *backlog = crypto_get_backlog(>queue);
+   req = crypto_dequeue_request(>queue);
+
+   if (!req)
+   return NULL;
+
+   return req;
+}
+
+static void mv_cesa_rearm_engine(struct mv_cesa_engine *engine)
  {
struct crypto_async_request *req, *backlog;
struct mv_cesa_ctx *ctx;

-   backlog = crypto_get_backlog(>queue);
-   req = crypto_dequeue_request(>queue);
-   engine->req = req;

+   spin_lock_bh(>lock);
+   if (engine->req)
+   goto out_unlock;
+
+   req = mv_cesa_dequeue_req_locked(engine, );
if (!req)
-   return;
+   goto out_unlock;
+
+   engine->req = req;
+   spin_unlock_bh(>lock);


I'm not a big fan of those multiple 'unlock() locations', and since
your code is pretty simple I'd prefer seeing something like.


mhhh, yes I have re-worked this function recently (the locking was more 
complicated before), I will change the code.




spin_lock_bh(>lock);
if (!engine->req) {
req = mv_cesa_dequeue_req_locked(engine, );
engine->req = req;
}
spin_unlock_bh(>lock);

if (!req)
return;

With req and backlog initialized to NULL at the beginning of the
function.


ack





if (backlog)
backlog->complete(backlog, -EINPROGRESS);

ctx = crypto_tfm_ctx(req->tfm);
ctx->ops->step(req);
+   return;


Missing blank line.


ack




+out_unlock:
+   spin_unlock_bh(>lock);
+}
+
+static int mv_cesa_std_process(struct mv_cesa_engine *engine, u32 status)
+{
+   struct crypto_async_request *req;
+   struct mv_cesa_ctx *ctx;
+   int res;
+
+   req = engine->req;
+   ctx = crypto_tfm_ctx(req->tfm);
+   res = ctx->ops->process(req, status);
+
+   if (res == 0) {
+   ctx->ops->complete(req);
+   mv_cesa_engine_enqueue_complete_request(engine, req);
+   } else if (res == -EINPROGRESS) {
+   ctx->ops->step(req);
+   } else {
+   ctx->ops->complete(req);


Do we really have to call ->complete() in this case?


I was simply to be consistent with the old code (that is currently in 
mainline) but to be honest I don't think so...





+   }
+
+   return res;
+}
+
+static int mv_cesa_int_process(struct mv_cesa_engine *engine, u32 status)
+{
+   if (engine->chain.first && engine->chain.last)
+   return mv_cesa_tdma_process(engine, status);


Missing blank line.


ack




+   return mv_cesa_std_process(engine, status);
+}
+
+static inline void mv_cesa_complete_req(struct mv_cesa_ctx *ctx,
+   struct crypto_async_request *req, int res)


Align parameters to the open parenthesis.


ack




@@ -116,16 +181,15 @@ int mv_cesa_queue_req(struct crypto_async_request *req,
struct mv_cesa_engine *engine = creq->engine;

spin_lock_bh(>lock);
+   if (mv_cesa_req_get_type(creq) == CESA_DMA_REQ)
+   mv_cesa_tdma_chain(engine, creq);


Missing blank line.


ack



diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 5626aa7..e0fee1f 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -271,7 +271,9 @@ struct mv_cesa_op_ctx {
  /* TDMA descriptor flags */
  #define CESA_TDMA_DST_IN_SRAM BIT(31)
  #define CESA_TDMA_SRC_IN_SRAM BIT(30)
-#define CESA_TDMA_TYPE_MSK GENMASK(29, 0)
+#define CESA_TDMA_END_OF_REQ   BIT(29)
+#define CESA_TDMA_NOT_CHAINBIT(28)


I would name it CESA_TDMA_BREAK_CHAIN.


ack




+#define CESA_TDMA_TYPE_MSK GENMASK(27, 0)
  #define CESA_TDMA_DUMMY   0
  #define CESA_TDMA_DATA1
  #define CESA_TDMA_OP  2
@@ -431,6 +433,9 @@ struct mv_cesa_dev {
   *SRAM
   * @queue:fifo of the pending crypto requests
   * @load: engine load counter, useful for load balancing
+ * @chain: list of the current tdma descriptors being processed
+ * by this engine.
+ * @complete_queue:fifo of the processed 

RE: [PATCH v2 0/2] Add SHA-3 algorithm and test vectors.

2016-06-17 Thread Raveendra Padasalagi
++ Stephan Mueller

Regards,
Raveendra
> -Original Message-
> From: Raveendra Padasalagi [mailto:raveendra.padasal...@broadcom.com]
> Sent: 17 June 2016 10:31
> To: Herbert Xu; David S. Miller; linux-crypto@vger.kernel.org; linux-
> ker...@vger.kernel.org
> Cc: Jon Mason; Florian Fainelli; Anup Patel; Ray Jui; Scott Branden;
Pramod
> Kumar; bcm-kernel-feedback-l...@broadcom.com; Raveendra Padasalagi
> Subject: [PATCH v2 0/2] Add SHA-3 algorithm and test vectors.
>
> This patchset adds the implementation of SHA-3 algorithm in software and
it's
> based on original implementation pushed in patch
> https://lwn.net/Articles/518415/ with additional changes to match the
padding
> rules specified in SHA-3 specification.
>
> This patchset also includes changes in tcrypt module to add support for
SHA-3
> algorithms test and related test vectors for basic testing.
>
> Broadcom Secure Processing Unit-2(SPU-2) engine supports offloading of
SHA-3
> operations in hardware, in order to add SHA-3 support in SPU-2 driver we
> needed to have the software implementation and test framework in place.
>
> The patchset is based on v4.7-rc1 tag and its tested on Broadcom
NorthStar2
> SoC.
>
> The patch set can be fetched from iproc-sha3-v2 branch of
> https://github.com/Broadcom/arm64-linux.git
>
> Changes since v1:
>  - Renamed MODULE_ALIAS to MODULE_ALIAS_CRYPTO
>  - Added aliases for below cra_driver_name's
>sha3-224-generic
>sha3-256-generic
>sha3-384-generic
>sha3-512-generic
>
> Jeff Garzik (1):
>   Crypto: Add SHA-3 hash algorithm
>
> Raveendra Padasalagi (1):
>   Crypto: Add SHA-3 Test's in tcrypt
>
>  crypto/Kconfig|  10 ++
>  crypto/Makefile   |   1 +
>  crypto/sha3_generic.c | 300
> ++
>  crypto/tcrypt.c   |  53 -
>  crypto/testmgr.c  |  40 +++
>  crypto/testmgr.h  | 125 +
>  include/crypto/sha3.h |  29 +
>  7 files changed, 557 insertions(+), 1 deletion(-)  create mode 100644
> crypto/sha3_generic.c  create mode 100644 include/crypto/sha3.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


Re: [patch] crypto: drbg - fix an error code in drbg_init_sym_kernel()

2016-06-17 Thread Stephan Mueller
Am Freitag, 17. Juni 2016, 11:19:58 schrieb Stephan Mueller:

Hi Stephan,

> Am Freitag, 17. Juni 2016, 12:16:19 schrieb Dan Carpenter:
> 
> Hi Dan,
> 
> > We accidentally return PTR_ERR(NULL) which is success but we should
> > return -ENOMEM.
> > 
> > Fixes: 355912852115 ('crypto: drbg - use CTR AES instead of ECB AES')
> > Signed-off-by: Dan Carpenter 
> 
> Acked-by: Stephan Mueller 
> 
> That points to an error in the documentation of skcipher_request_alloc.

Apologies, that documentation issue has already been fixed in the 
cryptodev-2.6 tree. I was looking at the vanilla 4.6 tree for the 
documentation while I was preparing my patch.

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] crypto: drbg - fix an error code in drbg_init_sym_kernel()

2016-06-17 Thread Stephan Mueller
Am Freitag, 17. Juni 2016, 12:16:19 schrieb Dan Carpenter:

Hi Dan,

> We accidentally return PTR_ERR(NULL) which is success but we should
> return -ENOMEM.
> 
> Fixes: 355912852115 ('crypto: drbg - use CTR AES instead of ECB AES')
> Signed-off-by: Dan Carpenter 

Acked-by: Stephan Mueller 

That points to an error in the documentation of skcipher_request_alloc.

I will send a follow-up patch.
> 
> diff --git a/crypto/drbg.c b/crypto/drbg.c
> index ded8638..6872d15 100644
> --- a/crypto/drbg.c
> +++ b/crypto/drbg.c
> @@ -1686,7 +1686,7 @@ static int drbg_init_sym_kernel(struct drbg_state
> *drbg) if (!req) {
>   pr_info("DRBG: could not allocate request queue\n");
>   drbg_fini_sym_kernel(drbg);
> - return PTR_ERR(req);
> + return -ENOMEM;
>   }
>   drbg->ctr_req = req;
>   skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,


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


[patch] crypto: drbg - fix an error code in drbg_init_sym_kernel()

2016-06-17 Thread Dan Carpenter
We accidentally return PTR_ERR(NULL) which is success but we should
return -ENOMEM.

Fixes: 355912852115 ('crypto: drbg - use CTR AES instead of ECB AES')
Signed-off-by: Dan Carpenter 

diff --git a/crypto/drbg.c b/crypto/drbg.c
index ded8638..6872d15 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1686,7 +1686,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
if (!req) {
pr_info("DRBG: could not allocate request queue\n");
drbg_fini_sym_kernel(drbg);
-   return PTR_ERR(req);
+   return -ENOMEM;
}
drbg->ctr_req = req;
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
--
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