crypto: drivers - Fix Kconfig selects

2015-06-16 Thread Herbert Xu
This patch fixes a number of problems in crypto driver Kconfig
entries:

1. Select BLKCIPHER instead of BLKCIPHER2.  The latter is internal
and should not be used outside of the crypto API itself.
2. Do not select ALGAPI unless you use a legacy type like
CRYPTO_ALG_TYPE_CIPHER.
3. Select the algorithm type that you are implementing, e.g., AEAD.
4. Do not select generic C code such as CBC/ECB unless you use them
as a fallback.
5. Remove default n since that is the default default.

Signed-off-by: Herbert Xu 
---

 drivers/crypto/Kconfig   |   41 +
 drivers/crypto/caam/Kconfig  |5 ++---
 drivers/crypto/ccp/Kconfig   |1 -
 drivers/crypto/nx/Kconfig|8 
 drivers/crypto/qat/Kconfig   |6 ++
 drivers/crypto/ux500/Kconfig |4 ++--
 6 files changed, 19 insertions(+), 46 deletions(-)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 92c899f..7a72797 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -162,9 +162,8 @@ config CRYPTO_GHASH_S390
 config CRYPTO_DEV_MV_CESA
tristate "Marvell's Cryptographic Engine"
depends on PLAT_ORION
-   select CRYPTO_ALGAPI
select CRYPTO_AES
-   select CRYPTO_BLKCIPHER2
+   select CRYPTO_BLKCIPHER
select CRYPTO_HASH
help
  This driver allows you to utilize the Cryptographic Engines and
@@ -176,7 +175,8 @@ config CRYPTO_DEV_MV_CESA
 config CRYPTO_DEV_NIAGARA2
tristate "Niagara2 Stream Processing Unit driver"
select CRYPTO_DES
-   select CRYPTO_ALGAPI
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_HASH
depends on SPARC64
help
  Each core of a Niagara2 processor contains a Stream
@@ -189,7 +189,6 @@ config CRYPTO_DEV_NIAGARA2
 config CRYPTO_DEV_HIFN_795X
tristate "Driver HIFN 795x crypto accelerator chips"
select CRYPTO_DES
-   select CRYPTO_ALGAPI
select CRYPTO_BLKCIPHER
select HW_RANDOM if CRYPTO_DEV_HIFN_795X_RNG
depends on PCI
@@ -208,8 +207,10 @@ source drivers/crypto/caam/Kconfig
 
 config CRYPTO_DEV_TALITOS
tristate "Talitos Freescale Security Engine (SEC)"
-   select CRYPTO_ALGAPI
+   select CRYPTO_AEAD
select CRYPTO_AUTHENC
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_HASH
select HW_RANDOM
depends on FSL_SOC
help
@@ -244,7 +245,7 @@ config CRYPTO_DEV_IXP4XX
tristate "Driver for IXP4xx crypto hardware acceleration"
depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE
select CRYPTO_DES
-   select CRYPTO_ALGAPI
+   select CRYPTO_AEAD
select CRYPTO_AUTHENC
select CRYPTO_BLKCIPHER
help
@@ -254,7 +255,6 @@ config CRYPTO_DEV_PPC4XX
tristate "Driver AMCC PPC4xx crypto accelerator"
depends on PPC && 4xx
select CRYPTO_HASH
-   select CRYPTO_ALGAPI
select CRYPTO_BLKCIPHER
help
  This option allows you to have support for AMCC crypto acceleration.
@@ -275,7 +275,7 @@ config CRYPTO_DEV_OMAP_AES
tristate "Support for OMAP AES hw engine"
depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP2PLUS
select CRYPTO_AES
-   select CRYPTO_BLKCIPHER2
+   select CRYPTO_BLKCIPHER
help
  OMAP processors have AES module accelerator. Select this if you
  want to use the OMAP module for AES algorithms.
@@ -284,7 +284,7 @@ config CRYPTO_DEV_OMAP_DES
tristate "Support for OMAP DES3DES hw engine"
depends on ARCH_OMAP2PLUS
select CRYPTO_DES
-   select CRYPTO_BLKCIPHER2
+   select CRYPTO_BLKCIPHER
help
  OMAP processors have DES/3DES module accelerator. Select this if you
  want to use the OMAP module for DES and 3DES algorithms. Currently
@@ -294,9 +294,10 @@ config CRYPTO_DEV_OMAP_DES
 config CRYPTO_DEV_PICOXCELL
tristate "Support for picoXcell IPSEC and Layer2 crypto engines"
depends on ARCH_PICOXCELL && HAVE_CLK
+   select CRYPTO_AEAD
select CRYPTO_AES
select CRYPTO_AUTHENC
-   select CRYPTO_ALGAPI
+   select CRYPTO_BLKCIPHER
select CRYPTO_DES
select CRYPTO_CBC
select CRYPTO_ECB
@@ -322,7 +323,6 @@ config CRYPTO_DEV_S5P
tristate "Support for Samsung S5PV210/Exynos crypto accelerator"
depends on ARCH_S5PV210 || ARCH_EXYNOS
select CRYPTO_AES
-   select CRYPTO_ALGAPI
select CRYPTO_BLKCIPHER
help
  This option allows you to have support for S5P crypto acceleration.
@@ -345,7 +345,6 @@ endif
 config CRYPTO_DEV_UX500
tristate "Driver for ST-Ericsson UX500 crypto hardware acceleration"
depends on ARCH_U8500
-   select CRYPTO_ALGAPI
help
  Driver for ST-Ericsson UX500 crypto engine.
 
@@ -363,10 +362,7 @@ config CRYPTO_DEV_BFIN_CRC
 config CRYPTO_DEV_ATMEL_AES
tristate "Support for Atmel AES hw accelerator"
depends on AR

crypto: tcrypt - Fixed AEAD speed test setup

2015-06-16 Thread Herbert Xu
The AEAD speed test SG list setup did not correctly mark the AD,
potentially causing a crash.

Signed-off-by: Herbert Xu 
---

 crypto/tcrypt.c |   15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 5146367..9f6f10b 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -258,12 +258,12 @@ static void sg_init_aead(struct scatterlist *sg, char 
*xbuf[XBUFSIZE],
rem = buflen % PAGE_SIZE;
}
 
-   sg_init_table(sg, np);
+   sg_init_table(sg, np + 1);
np--;
for (k = 0; k < np; k++)
-   sg_set_buf(&sg[k], xbuf[k], PAGE_SIZE);
+   sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE);
 
-   sg_set_buf(&sg[k], xbuf[k], rem);
+   sg_set_buf(&sg[k + 1], xbuf[k], rem);
 }
 
 static void test_aead_speed(const char *algo, int enc, unsigned int secs,
@@ -337,8 +337,6 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
do {
assoc = axbuf[0];
memset(assoc, 0xff, aad_size);
-   sg_set_buf(&sg[0], assoc, aad_size);
-   sg_set_buf(&sgout[0], assoc, aad_size);
 
if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
pr_err("template (%u) too big for tvmem 
(%lu)\n",
@@ -374,12 +372,15 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
goto out;
}
 
-   sg_init_aead(&sg[1], xbuf,
+   sg_init_aead(sg, xbuf,
*b_size + (enc ? authsize : 0));
 
-   sg_init_aead(&sgout[1], xoutbuf,
+   sg_init_aead(sgout, xoutbuf,
*b_size + (enc ? authsize : 0));
 
+   sg_set_buf(&sg[0], assoc, aad_size);
+   sg_set_buf(&sgout[0], assoc, aad_size);
+
aead_request_set_crypt(req, sg, sgout, *b_size, iv);
aead_request_set_ad(req, aad_size);
 
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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


crypto: tcrypt - Add rfc4309(ccm(aes)) speed test

2015-06-16 Thread Herbert Xu
This patch adds a speed test for rfc4309(ccm(aes)) as mode 212.

Signed-off-by: Herbert Xu 
---

 crypto/tcrypt.c |5 +
 crypto/tcrypt.h |1 +
 2 files changed, 6 insertions(+)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 4b4a931..5146367 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1761,6 +1761,11 @@ static int do_test(const char *alg, u32 type, u32 mask, 
int m)
NULL, 0, 16, 8, aead_speed_template_20);
break;
 
+   case 212:
+   test_aead_speed("rfc4309(ccm(aes))", ENCRYPT, sec,
+   NULL, 0, 16, 8, aead_speed_template_19);
+   break;
+
case 300:
if (alg) {
test_hash_speed(alg, sec, generic_hash_speed_template);
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 6c7e21a..6cc1b85 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -65,6 +65,7 @@ static u8 speed_template_32_64[] = {32, 64, 0};
 /*
  * AEAD speed tests
  */
+static u8 aead_speed_template_19[] = {19, 0};
 static u8 aead_speed_template_20[] = {20, 0};
 
 /*
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 v5 04/14] crypto: add a new driver for Marvell's CESA

2015-06-16 Thread Herbert Xu
On Tue, Jun 16, 2015 at 11:58:58AM +0200, Boris Brezillon wrote:
>
> +config CRYPTO_DEV_MARVELL_CESA
> + tristate "New Marvell's Cryptographic Engine driver"
> + depends on (PLAT_ORION || ARCH_MVEBU || COMPILE_TEST) && HAS_DMA && 
> HAS_IOMEM
> + select CRYPTO_ALGAPI
> + select CRYPTO_AES
> + select CRYPTO_DES
> + select CRYPTO_BLKCIPHER2
> + select CRYPTO_HASH

While you're fixing the DMA issue, could you also replace BLKCIPHER2
with BLKCIPHER and kill the select on ALGAPI? BLKCIPHER2 is internal
to the crypto API and should not be used elsewhere while ALGAPI is
only meant to be selected by crypto types such as BLKCIPHER.

I know the existing driver does this too and I will fix that now.

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 v5 05/14] crypto: marvell/CESA: add TDMA support

2015-06-16 Thread Herbert Xu
On Wed, Jun 17, 2015 at 01:05:27PM +0800, Herbert Xu wrote:
> On Tue, Jun 16, 2015 at 11:58:59AM +0200, Boris Brezillon wrote:
> >
> > +   ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
> > +DMA_TO_DEVICE);
> > +   if (ret != creq->src_nents)
> > +   return -ENOMEM;
> 
> Hmm it doesn't quite work like that.  It returns zero on error,
> otherwise it returns the number (n) of mapped entries which may be
> less than what you gave it due to merging.  You're then supposed
> to use only the first n entries which should contain everything.

Please take a look at Documentation/DMA-API-HOWTO.txt, it has
everything you need to know about the dma_map_sg interface.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 v5 05/14] crypto: marvell/CESA: add TDMA support

2015-06-16 Thread Herbert Xu
On Tue, Jun 16, 2015 at 11:58:59AM +0200, Boris Brezillon wrote:
>
> + ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
> +  DMA_TO_DEVICE);
> + if (ret != creq->src_nents)
> + return -ENOMEM;

Hmm it doesn't quite work like that.  It returns zero on error,
otherwise it returns the number (n) of mapped entries which may be
less than what you gave it due to merging.  You're then supposed
to use only the first n entries which should contain everything.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
On 06/16/2015 07:36 PM, Herbert Xu wrote:
> The existing crypto/asymmetric_key errno scheme doesn't really
> mesh in with the rest of crypto.  So you'll just have to pick one
> scheme and stick with it.
> 
> I don't really mind either way as long as the error codes are
> unique and meaningful.

So I would use -EINVAL since these are input parameters. Do you agree 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 RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Herbert Xu
On Tue, Jun 16, 2015 at 07:32:16PM -0700, Tadeusz Struk wrote:
>
> I thought that -EBADMSG was mainly used for authenticated ciphers in case 
> when verification of auth data fails.
> Since this are input params I thought that -EINVAL would be more appropriate.
> I can change it to -EBADMSG, no problem.
> Herbert, what do you think?

The existing crypto/asymmetric_key errno scheme doesn't really
mesh in with the rest of crypto.  So you'll just have to pick one
scheme and stick with it.

I don't really mind either way as long as the error codes are
unique and meaningful.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Hi David,
On 06/16/2015 03:10 PM, David Howells wrote:
>> +static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
>> > +{
>> > +  /* (1) Validate 0 <= m < n */
>> > +  if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
>> > +  return -EINVAL;
> Why -EINVAL not -EBADMSG?

I thought that -EBADMSG was mainly used for authenticated ciphers in case when 
verification of auth data fails.
Since this are input params I thought that -EINVAL would be more appropriate.
I can change it to -EBADMSG, no problem.
Herbert, what do you think?
--
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 RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread David Howells
Tadeusz Struk  wrote:

> +static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
> +{
> + /* (1) Validate 0 <= m < n */
> + if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
> + return -EINVAL;

Why -EINVAL not -EBADMSG?

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


[PATCH RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig|7 +
 crypto/Makefile   |8 +
 crypto/rsa.c  |  315 +
 crypto/rsa_helper.c   |  121 
 crypto/rsakey.asn1|5 +
 include/crypto/internal/rsa.h |   27 
 6 files changed, 483 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/internal/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 264dadb..52467cf 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,6 +102,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate "RSA algorithm"
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 1ed382d..0077476 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
+$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
+clean-files += rsakey-asn1.c rsakey-asn1.h
+
+rsa_generic-y := rsakey-asn1.o
+rsa_generic-y += rsa.o
+rsa_generic-y += rsa_helper.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+
 cryptomgr-y := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..752af06
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,315 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk 
+ *
+ * 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 
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 <= m < n */
+   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key->e, key->n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 <= c < n */
+   if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key->d, key->n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 <= m < n */
+   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key->d, key->n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 <= s < n */
+   if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key->e, key->n);
+}
+
+static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   const struct rsa_key *pkey = rsa_get_key(tfm);
+   MPI m, c = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (unlikely(!pkey->n || !pkey->e)) {
+   ret = -EINVAL;
+   goto err_free_c;
+   }
+
+   if (req->dst_len < mpi_get_size(pkey->n)) {
+   req->dst_len = mpi_get_size(pkey->n);
+   ret = -EOVERFLOW;
+   goto err_free_c;
+   }
+
+   m = mpi_read_raw_data(req->src, req->src_len);
+   if (!m) {
+   ret = -ENOMEM;
+   goto err_free_c;
+   }
+
+   ret = _rsa_enc(pkey, c, m);
+   if (ret)
+   goto err_free_m;
+
+   ret = mpi_read_buffer(c, req->dst, req->dst_len, &req->dst_len, &sign);
+   if (ret)
+   goto err_free_m;
+
+   if (sign < 0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+err_free_m:
+   mpi_free(m);
+err_free_c:
+   mpi_free(c);
+   return ret;
+}

[PATCH RFC v7 3/3] crypto: add tests vectors for RSA

2015-06-16 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig   |1 
 crypto/testmgr.c |  158 ++
 crypto/testmgr.h |  187 ++
 3 files changed, 346 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 52467cf..9471ac8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -122,6 +122,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
+   select CRYPTO_AKCIPHER2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..975e1ea 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1832,147 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int out_len_max, out_len = 0;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   init_completion(&result.completion);
+   err = crypto_akcipher_setkey(tfm, vecs->key, vecs->key_len);
+   if (err)
+   goto free_req;
+
+   akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
+  out_len);
+   /* expect this to fail, and update the required buf len */
+   crypto_akcipher_encrypt(req);
+   out_len = req->dst_len;
+   if (!out_len) {
+   err = -EINVAL;
+   goto free_req;
+   }
+
+   out_len_max = out_len;
+   err = -ENOMEM;
+   outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_enc)
+   goto free_req;
+
+   akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
+  out_len);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(&result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err("alg: rsa: encrypt test failed. err %d\n", err);
+   goto free_all;
+   }
+   if (out_len != vecs->c_size) {
+   pr_err("alg: rsa: encrypt test failed. Invalid output len\n");
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that encrypted message is equal to expected */
+   if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
+   pr_err("alg: rsa: encrypt test failed. Invalid output\n");
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* Don't invoke decrypt for vectors with public key */
+   if (vecs->public_key_vec) {
+   err = 0;
+   goto free_all;
+   }
+   outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+   init_completion(&result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
+  out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(&result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err("alg: rsa: decrypt test failed. err %d\n", err);
+   goto free_all;
+   }
+   out_len = req->dst_len;
+   if (out_len != vecs->m_size) {
+   pr_err("alg: rsa: decrypt test failed. Invalid output len\n");
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs->m, outbuf_dec, vecs->m_size)) {
+   pr_err("alg: rsa: decrypt test failed. Invalid output\n");
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_a

[PATCH RFC v7 0/3] crypto: Introduce Public Key Encryption API

2015-06-16 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

The benefits it gives interface are:
- drivers can add many implementations of RSA or DSA
  algorithms and user will allocate instances (tfms) of these, base on
  algorithm priority, in the same way as it is with the symmetric ciphers.
- the new interface allows for asynchronous implementations that
  can use crypto hardware to offload the calculations to.
- integrating it with linux crypto api allows using all its benefits
  i.e. managing algorithms using NETLINK_CRYPTO, monitoring implementations
  using /proc/crypto. etc

New helper functions have been added to allocate crypto_akcipher instances
and invoke the operations to make it easier to use.
For instance to verify a public_signature against a public_key using
the RSA algorithm a user would do:

struct crypto_akcipher *tfm = crypto_alloc_akcipher("rsa", 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, &res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

Changes in v7:
 - change req->dst_len to be int instead of int *
 - remove result_len from comments - it's not longer there
 - use crypto_akcipher_reqtfm helper instead of __crypto_akcipher_tfm
 - fix memleak in rsa.c
 - change error code to -EOVERFLOW if dst buf is not big enough
 - drop redundant cra_ctxsize inits
 - add type-safe init/exit functions
 - cleanup headers in rsa_helpers
 - remove checks for NULL before mpi_free

Changes in v6:
 - in FIPS mode only allow key sizes 2K & 3K
 - remove result_len and use dst_len as in/out param
 - remove subtype from akcipher reports
 - store rsa_key in tfm ctx and change ras_parse_key to take struct rsa_key
   instead of tfm. 
 - export rsa_free_key, which free memory allocated by ras_parse_key.
 - split akcipher.h into public and internal with public key specific helpers
 - remove maxsize() and set the required size in enc/dec/sign/verify instead
 - add public key vector
 - split AKCIPHER into AKCIPHER and AKCIPHER2 in Kconfig
 - remove MPI patch from the series - already applied

Changes in v5:
 - make mpi_get_size() function inline.
 - add a setkey function to the algorithm and rsa_parse_key() helper to
   parse rsa keys from BER encoded to MPI. The helper will also validate
   the given key if it is strong enough in case FIPS mode is enabled.
 - change the format of the key from struct public_key * to void * BER encoded
   buffer.
 - change the format of the rsa keys in testmgr to BER encoded form.
 - change mpi_free to use kzfree instead of kfree because it is used to free
   crypto keys

Changes in v4:
 - add an rsa generic implementation
 - don't convert the existing public_key implementation to the new interface.
   This will be done after the new interface is accepted.
 - add new mpi_get_buf(), mpi_copy() and mpi_get_size() mpi helpers 
 - on set key the ftm now will clone the key instead of just setting a ptr
 - add a check on enc/dec/sign/veryfi to make sure a valid (public or private)
   key is setup
 - add maxsize fn into algorith that will be used to query implementation
   what is the max size of a result for a give public key that the user needs
   to allocate
 - removed private ctx from crypto_akcipher as the crypto_tfm base has one
   already
 - add 2K bit RSA test vectors
 - add cipher text validation in crypto test mgr as (required for FIPS)

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len & dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (3):
  crypto: add PKE API
  crypto: rsa: add a new rsa generic implementation
  crypto: add tests vectors for RSA


 crypto/Kconfig |   19 ++
 crypto/Makefile|9

[PATCH RFC v7 1/3] crypto: add PKE API

2015-06-16 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig |   11 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  117 
 crypto/crypto_user.c   |   22 ++
 include/crypto/akcipher.h  |  340 
 include/crypto/internal/akcipher.h |   60 ++
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h
 create mode 100644 include/crypto/internal/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..264dadb 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,17 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_AKCIPHER
+   tristate "Public Key Algorithms API"
+   select CRYPTO_AKCIPHER2
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..1ed382d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..d798641
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,117 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk 
+ *
+ * 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_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), &rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, "type : akcipher\n");
+}
+
+static void crypto_akcipher_exit_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+   struct akcipher_alg *alg = crypto_akcipher_alg(akcipher);
+
+   alg->exit(akcipher);
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+   struct akcipher_alg *alg = crypto_akcipher_alg(akcipher);
+
+   if (alg->exit)
+   akcipher->base.exit = crypto_akcipher_exit_tfm;
+
+   if (alg->init)
+   return alg->init(akcipher);
+
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, &crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = &alg->base;
+
+   base->cra_type = &crypto_akcipher_type;
+   base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+   base->cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+   crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic public key c

RE: [BUG?] crypto: caam: little/big endianness on ARM vs PPC

2015-06-16 Thread Victoria Milhoan
Jon,

The patches published to the mailing list yesterday for comment (titled crypto: 
caam - Add i.MX6 support to the Freescale CAAM driver) are based on the patches 
in the Freescale 3.14 git repository which enable i.MX6 support. The initial 
patch set is intended to provide a functional driver, based on the mainline 
kernel, which supports both QorIQ and i.MX6. 

Thanks,
Victoria

-Original Message-
From: Jon Nettleton [mailto:jon.nettle...@gmail.com] 
Sent: Tuesday, June 16, 2015 1:11 AM
To: Milhoan Victoria-B42089
Cc: Herbert Xu; Steffen Trumtrar; Kim Phillips; linux-ker...@vger.kernel.org; 
Gupta Ruchika-R66431; linux-arm-ker...@lists.infradead.org; 
ker...@pengutronix.de; Geanta Neag Horia Ioan-B05471; 
linux-crypto@vger.kernel.org
Subject: Re: [BUG?] crypto: caam: little/big endianness on ARM vs PPC

Victoria,

I was hoping you would join the conversation.  I know you have a series of 
patches in Freescale's 3.14 git repository.  Have you updated those for 
mainline and published them for review and inclusion in the upstream kernel?  
If yes to any could you post a link?

-Jon

On Tue, Jun 16, 2015 at 5:27 AM, Victoria Milhoan  
wrote:
> All,
>
> Freescale has been adding i.MX6 support to the CAAM driver and testing on 
> both i.MX6 and QorIQ platforms. The patch series is now available for review. 
> Your feedback for the provided patches is appreciated.
>
> Thanks,
> Victoria
>
> -Original Message-
> From: linux-crypto-ow...@vger.kernel.org 
> [mailto:linux-crypto-ow...@vger.kernel.org] On Behalf Of Herbert Xu
> Sent: Monday, June 15, 2015 3:05 PM
> To: Steffen Trumtrar
> Cc: linux-ker...@vger.kernel.org; 
> linux-arm-ker...@lists.infradead.org; linux-crypto@vger.kernel.org; 
> Gupta Ruchika-R66431; ker...@pengutronix.de; Geanta Neag Horia 
> Ioan-B05471; Kim Phillips
> Subject: Re: [BUG?] crypto: caam: little/big endianness on ARM vs PPC
>
> On Mon, Jun 15, 2015 at 05:59:07PM +0200, Steffen Trumtrar wrote:
>> Hi!
>>
>> I'm working on CAAM support for the ARM-based i.MX6 SoCs. The current 
>> drivers/crypto/caam driver only works for PowerPC AFAIK.
>> Actually, there isn't that much to do, to get support for the i.MX6 
>> but one patch breaks the driver severely:
>>
>>   commit ef94b1d834aace7101de77c3a7c2631b9ae9c5f6
>>   crypto: caam - Add definition of rd/wr_reg64 for little endian 
>> platform
>>
>> This patch adds
>>
>> +#ifdef __LITTLE_ENDIAN
>> +static inline void wr_reg64(u64 __iomem *reg, u64 data) {
>> + wr_reg32((u32 __iomem *)reg + 1, (data & 0xull) >> 32);
>> + wr_reg32((u32 __iomem *)reg, data & 0xull); }
>>
>> The wr_reg64 function is only used in one place in the 
>> drivers/crypto/caam/jr.c
>> driver: to write the dma_addr_t to the register. Without that patch 
>> everything works fine on ARM (little endian, 32bit), with that patch 
>> the driver will write 0's into the register that holds the DMA address (the 
>> numerically-higher) -> kernel hangs.
>> Also, from my understanding, the comment above the defines, stating 
>> that you have to first write the numerically-lower and then the 
>> numerically-higher address on 32bit systems doesn't match with the 
>> implementation.
>>
>> What I don't know/understand is if this makes any sense for any PowerPC 
>> implementation.
>>
>> So, the question is, how to fix this? I'd prefer to do it directly in 
>> the jr driver instead of the ifdef-ery.
>>
>> Something like
>>   if (sizeof(dma_addr_t) == sizeof(u32))
>>   wr_reg32(&jrp->rregs->inpring_base + 1, inpbusaddr);
>>   else if (sizeof(dma_addr_t) == sizeof(u64))
>>   wr_reg64(...)
>>
>> or just go by DT compatible and then remove the inline function definitions.
>>
>> As far as I can tell, the compatible wouldn't be needed for anything 
>> else in the jr driver, so maybe that is not optimal. On the other 
>> hand the sizeof(..) solution would only catch little endian on 32bit 
>> and not big endian (?!) I however don't know what combinations 
>> actually
>> *have* to be caught, as I don't know, which exist.
>>
>> So, what do you think people?
>
> I'm adding a couple of CCs.
>
> Thanks,
> --
> Email: Herbert Xu  Home Page: 
> http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
> --
> 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
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
N�r��yb�X��ǧv�^�)޺{.n�+{�r����ܨ}���Ơz�&j:+v���zZ+��+zf���h���~i���z��w���?�&�)ߢf

Re: [BUG?] crypto: caam: little/big endianness on ARM vs PPC

2015-06-16 Thread Steffen Trumtrar
Hi!

On Tue, Jun 16, 2015 at 03:27:54AM +, Victoria Milhoan wrote:
> All,
> 
> Freescale has been adding i.MX6 support to the CAAM driver and testing on 
> both i.MX6 and QorIQ platforms. The patch series is now available for review. 
> Your feedback for the provided patches is appreciated.
> 

Could you maybe bounce me that thread?
I can't find it in a format that allows me to reply to the patches.

Thanks,
Steffen

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
--
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: caam - fix non-64-bit write/read access

2015-06-16 Thread Steffen Trumtrar
The patch

crypto: caam - Add definition of rd/wr_reg64 for little endian platform

added support for little endian platforms to the CAAM driver. Namely a
write and read function for 64 bit registers.
The only user of this functions is the Job Ring driver 
(drivers/crypto/caam/jr.c).
It uses the functions to set the DMA addresses for the input/output rings.
However, at least in the default configuration, the least significant 32 bits 
are
always in the base+0x0004 address; independent of the endianness of the bytes 
itself.
That means the addresses do not change with the system endianness.

DMA addresses are only 32 bits wide on non-64-bit systems, writing the upper 32 
bits
of this value to the register for the least significant bits results in the DMA 
address
being set to 0.

Fix this by always writing the registers in the same way.

Suggested-by: Russell King 
Signed-off-by: Steffen Trumtrar 
---

This patch is only compile-tested for PowerPC and tested on ARM.
According to the datasheets for i.MX6 and P1010 this should be correct, though.

 drivers/crypto/caam/regs.h | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 378ddc17f60e..672c97489505 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -83,35 +83,35 @@
 #endif
 #endif
 
+/*
+ * The only users of these wr/rd_reg64 functions is the Job Ring (JR).
+ * The DMA address registers in the JR are a pair of 32-bit registers.
+ * The layout is:
+ *
+ *base + 0x : most-significant 32 bits
+ *base + 0x0004 : least-significant 32 bits
+ *
+ * The 32-bit version of this core therefore has to write to base + 0x0004
+ * to set the 32-bit wide DMA address. This seems to be independent of the
+ * endianness of the written/read data.
+ */
+
 #ifndef CONFIG_64BIT
-#ifdef __BIG_ENDIAN
-static inline void wr_reg64(u64 __iomem *reg, u64 data)
-{
-   wr_reg32((u32 __iomem *)reg, (data & 0xull) >> 32);
-   wr_reg32((u32 __iomem *)reg + 1, data & 0xull);
-}
+#define REG64_MS32(reg) ((u32 __iomem *)(reg))
+#define REG64_LS32(reg) ((u32 __iomem *)(reg) + 1)
 
-static inline u64 rd_reg64(u64 __iomem *reg)
-{
-   return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) |
-   ((u64)rd_reg32((u32 __iomem *)reg + 1));
-}
-#else
-#ifdef __LITTLE_ENDIAN
 static inline void wr_reg64(u64 __iomem *reg, u64 data)
 {
-   wr_reg32((u32 __iomem *)reg + 1, (data & 0xull) >> 32);
-   wr_reg32((u32 __iomem *)reg, data & 0xull);
+   wr_reg32(REG64_MS32(reg), data >> 32);
+   wr_reg32(REG64_LS32(reg), data);
 }
 
 static inline u64 rd_reg64(u64 __iomem *reg)
 {
-   return (((u64)rd_reg32((u32 __iomem *)reg + 1)) << 32) |
-   ((u64)rd_reg32((u32 __iomem *)reg));
+   return ((u64)rd_reg32(REG64_MS32(reg)) << 32 |
+   (u64)rd_reg32(REG64_LS32(reg)));
 }
 #endif
-#endif
-#endif
 
 /*
  * jr_outentry
-- 
2.1.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 v5 08/14] crypto: marvell/CESA: add MD5 support

2015-06-16 Thread Boris Brezillon
From: Arnaud Ebalard 

Add support for MD5 operations.

Signed-off-by: Arnaud Ebalard 
Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c |   2 +
 drivers/crypto/marvell/cesa.h |   2 +
 drivers/crypto/marvell/hash.c | 172 +-
 3 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index c0b1b49..047c1c0 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -178,7 +178,9 @@ static struct crypto_alg *armada_370_cipher_algs[] = {
 };
 
 static struct ahash_alg *armada_370_ahash_algs[] = {
+   &mv_md5_alg,
&mv_sha1_alg,
+   &mv_ahmac_md5_alg,
&mv_ahmac_sha1_alg,
 };
 
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 2e8b7fc..2a7e21a 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -774,7 +774,9 @@ int mv_cesa_dma_add_op_transfers(struct mv_cesa_tdma_chain 
*chain,
 
 /* Algorithm definitions */
 
+extern struct ahash_alg mv_md5_alg;
 extern struct ahash_alg mv_sha1_alg;
+extern struct ahash_alg mv_ahmac_md5_alg;
 extern struct ahash_alg mv_ahmac_sha1_alg;
 
 extern struct crypto_alg mv_cesa_ecb_des_alg;
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index 299106f..d8555c5 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -12,6 +12,7 @@
  * by the Free Software Foundation.
  */
 
+#include 
 #include 
 
 #include "cesa.h"
@@ -346,8 +347,16 @@ static int mv_cesa_ahash_process(struct 
crypto_async_request *req, u32 status)
   ahashreq->nbytes - creq->cache_ptr);
 
if (creq->last_req) {
-   for (i = 0; i < digsize / 4; i++)
-   creq->state[i] = cpu_to_be32(creq->state[i]);
+   for (i = 0; i < digsize / 4; i++) {
+   /*
+* Hardware provides MD5 digest in a different
+* endianness than SHA-1 and SHA-256 ones.
+*/
+   if (digsize == MD5_DIGEST_SIZE)
+   creq->state[i] = cpu_to_le32(creq->state[i]);
+   else
+   creq->state[i] = cpu_to_be32(creq->state[i]);
+   }
 
memcpy(ahashreq->result, creq->state, digsize);
}
@@ -788,6 +797,95 @@ static int mv_cesa_ahash_finup(struct ahash_request *req)
return ret;
 }
 
+static int mv_cesa_md5_init(struct ahash_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5);
+
+   mv_cesa_ahash_init(req, &tmpl);
+
+   return 0;
+}
+
+static int mv_cesa_md5_export(struct ahash_request *req, void *out)
+{
+   struct md5_state *out_state = out;
+   struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+   struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
+   unsigned int digsize = crypto_ahash_digestsize(ahash);
+
+   out_state->byte_count = creq->len;
+   memcpy(out_state->hash, creq->state, digsize);
+   memset(out_state->block, 0, sizeof(out_state->block));
+   if (creq->cache)
+   memcpy(out_state->block, creq->cache, creq->cache_ptr);
+
+   return 0;
+}
+
+static int mv_cesa_md5_import(struct ahash_request *req, const void *in)
+{
+   const struct md5_state *in_state = in;
+   struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+   struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
+   unsigned int digsize = crypto_ahash_digestsize(ahash);
+   unsigned int cache_ptr;
+   int ret;
+
+   creq->len = in_state->byte_count;
+   memcpy(creq->state, in_state->hash, digsize);
+   creq->cache_ptr = 0;
+
+   cache_ptr = creq->len % sizeof(in_state->block);
+   if (!cache_ptr)
+   return 0;
+
+   ret = mv_cesa_ahash_alloc_cache(req);
+   if (ret)
+   return ret;
+
+   memcpy(creq->cache, in_state->block, cache_ptr);
+   creq->cache_ptr = cache_ptr;
+
+   return 0;
+}
+
+static int mv_cesa_md5_digest(struct ahash_request *req)
+{
+   int ret;
+
+   ret = mv_cesa_md5_init(req);
+   if (ret)
+   return ret;
+
+   return mv_cesa_ahash_finup(req);
+}
+
+struct ahash_alg mv_md5_alg = {
+   .init = mv_cesa_md5_init,
+   .update = mv_cesa_ahash_update,
+   .final = mv_cesa_ahash_final,
+   .finup = mv_cesa_ahash_finup,
+   .digest = mv_cesa_md5_digest,
+   .export = mv_cesa_md5_export,
+   .import = mv_cesa_md5_import,
+   .halg = {
+   .digestsize = MD5_DIGEST_SIZE,
+   .base = {
+   .cra_name = "md5",
+   .cra_driver_name = "mv-md5",
+   .cra_priority = 300,
+   .cra_flags = CRYPTO_ALG_ASYNC |
+  

[PATCH v5 07/14] crypto: marvell/CESA: add Triple-DES support

2015-06-16 Thread Boris Brezillon
From: Arnaud Ebalard 

Add support for Triple-DES operations.

Signed-off-by: Arnaud Ebalard 
Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c   |   2 +
 drivers/crypto/marvell/cesa.h   |   2 +
 drivers/crypto/marvell/cipher.c | 147 
 3 files changed, 151 insertions(+)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 212840e..c0b1b49 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -171,6 +171,8 @@ static void mv_cesa_remove_algs(struct mv_cesa_dev *cesa)
 static struct crypto_alg *armada_370_cipher_algs[] = {
&mv_cesa_ecb_des_alg,
&mv_cesa_cbc_des_alg,
+   &mv_cesa_ecb_des3_ede_alg,
+   &mv_cesa_cbc_des3_ede_alg,
&mv_cesa_ecb_aes_alg,
&mv_cesa_cbc_aes_alg,
 };
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 2ee48fe..2e8b7fc 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -779,6 +779,8 @@ extern struct ahash_alg mv_ahmac_sha1_alg;
 
 extern struct crypto_alg mv_cesa_ecb_des_alg;
 extern struct crypto_alg mv_cesa_cbc_des_alg;
+extern struct crypto_alg mv_cesa_ecb_des3_ede_alg;
+extern struct crypto_alg mv_cesa_cbc_des3_ede_alg;
 extern struct crypto_alg mv_cesa_ecb_aes_alg;
 extern struct crypto_alg mv_cesa_cbc_aes_alg;
 
diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index 31b9311..e65592c 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -22,6 +22,11 @@ struct mv_cesa_des_ctx {
u8 key[DES_KEY_SIZE];
 };
 
+struct mv_cesa_des3_ctx {
+   struct mv_cesa_ctx base;
+   u8 key[DES3_EDE_KEY_SIZE];
+};
+
 struct mv_cesa_aes_ctx {
struct mv_cesa_ctx base;
struct crypto_aes_ctx aes;
@@ -261,6 +266,22 @@ static int mv_cesa_des_setkey(struct crypto_ablkcipher 
*cipher, const u8 *key,
return 0;
 }
 
+static int mv_cesa_des3_ede_setkey(struct crypto_ablkcipher *cipher,
+  const u8 *key, unsigned int len)
+{
+   struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+   struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(tfm);
+
+   if (len != DES3_EDE_KEY_SIZE) {
+   crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+   return -EINVAL;
+   }
+
+   memcpy(ctx->key, key, DES3_EDE_KEY_SIZE);
+
+   return 0;
+}
+
 static int mv_cesa_ablkcipher_dma_req_init(struct ablkcipher_request *req,
const struct mv_cesa_op_ctx *op_templ)
 {
@@ -501,6 +522,132 @@ struct crypto_alg mv_cesa_cbc_des_alg = {
},
 };
 
+static int mv_cesa_des3_op(struct ablkcipher_request *req,
+  struct mv_cesa_op_ctx *tmpl)
+{
+   struct mv_cesa_des3_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+   int ret;
+
+   mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_3DES,
+ CESA_SA_DESC_CFG_CRYPTM_MSK);
+
+   memcpy(tmpl->ctx.blkcipher.key, ctx->key, DES3_EDE_KEY_SIZE);
+
+   ret = mv_cesa_ablkcipher_req_init(req, tmpl);
+   if (ret)
+   return ret;
+
+   ret = mv_cesa_queue_req(&req->base);
+   if (ret && ret != -EINPROGRESS)
+   mv_cesa_ablkcipher_cleanup(req);
+
+   return ret;
+}
+
+static int mv_cesa_ecb_des3_ede_encrypt(struct ablkcipher_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl,
+  CESA_SA_DESC_CFG_CRYPTCM_ECB |
+  CESA_SA_DESC_CFG_3DES_EDE |
+  CESA_SA_DESC_CFG_DIR_ENC);
+
+   return mv_cesa_des3_op(req, &tmpl);
+}
+
+static int mv_cesa_ecb_des3_ede_decrypt(struct ablkcipher_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl,
+  CESA_SA_DESC_CFG_CRYPTCM_ECB |
+  CESA_SA_DESC_CFG_3DES_EDE |
+  CESA_SA_DESC_CFG_DIR_DEC);
+
+   return mv_cesa_des3_op(req, &tmpl);
+}
+
+struct crypto_alg mv_cesa_ecb_des3_ede_alg = {
+   .cra_name = "ecb(des3_ede)",
+   .cra_driver_name = "mv-ecb-des3-ede",
+   .cra_priority = 300,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC,
+   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+   .cra_ctxsize = sizeof(struct mv_cesa_des3_ctx),
+   .cra_alignmask = 0,
+   .cra_type = &crypto_ablkcipher_type,
+   .cra_module = THIS_MODULE,
+   .cra_init = mv_cesa_ablkcipher_cra_init,
+   .cra_u = {
+   .ablkcipher = {
+   .min_keysize = DES3_EDE_KEY_SIZE,
+   .max_keysize = DES3_EDE_KEY_SIZE,
+   .ivsize  = DES3_EDE_BLOCK_SIZE,
+   .setkey = mv_cesa_des3_ede_setkey,
+   .encrypt = mv_cesa_ecb_des3_ede_encrypt,
+

[PATCH v5 04/14] crypto: add a new driver for Marvell's CESA

2015-06-16 Thread Boris Brezillon
The existing mv_cesa driver supports some features of the CESA IP but is
quite limited, and reworking it to support new features (like involving the
TDMA engine to offload the CPU) is almost impossible.
This driver has been rewritten from scratch to take those new features into
account.

This commit introduce the base infrastructure allowing us to add support
for DMA optimization.
It also includes support for one hash (SHA1) and one cipher (AES)
algorithm, and enable those features on the Armada 370 SoC.

Other algorithms and platforms will be added later on.

Signed-off-by: Boris Brezillon 
Signed-off-by: Arnaud Ebalard 
---
 drivers/crypto/Kconfig  |  16 +
 drivers/crypto/Makefile |   1 +
 drivers/crypto/marvell/Makefile |   2 +
 drivers/crypto/marvell/cesa.c   | 417 +++
 drivers/crypto/marvell/cesa.h   | 554 +++
 drivers/crypto/marvell/cipher.c | 331 ++
 drivers/crypto/marvell/hash.c   | 720 
 7 files changed, 2041 insertions(+)
 create mode 100644 drivers/crypto/marvell/Makefile
 create mode 100644 drivers/crypto/marvell/cesa.c
 create mode 100644 drivers/crypto/marvell/cesa.h
 create mode 100644 drivers/crypto/marvell/cipher.c
 create mode 100644 drivers/crypto/marvell/hash.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index a6bbea8..c15c5a5 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -174,6 +174,22 @@ config CRYPTO_DEV_MV_CESA
 
  Currently the driver supports AES in ECB and CBC mode without DMA.
 
+config CRYPTO_DEV_MARVELL_CESA
+   tristate "New Marvell's Cryptographic Engine driver"
+   depends on (PLAT_ORION || ARCH_MVEBU || COMPILE_TEST) && HAS_DMA && 
HAS_IOMEM
+   select CRYPTO_ALGAPI
+   select CRYPTO_AES
+   select CRYPTO_DES
+   select CRYPTO_BLKCIPHER2
+   select CRYPTO_HASH
+   select SRAM
+   help
+ This driver allows you to utilize the Cryptographic Engines and
+ Security Accelerator (CESA) which can be found on the Armada 370.
+
+ This driver is aimed at replacing the mv_cesa driver. This will only
+ happen once it has received proper testing.
+
 config CRYPTO_DEV_NIAGARA2
tristate "Niagara2 Stream Processing Unit driver"
select CRYPTO_DES
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index fb84be7..e35c07a 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
 obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
 obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
 obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
+obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell/
 obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o
 obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o
 n2_crypto-y := n2_core.o n2_asm.o
diff --git a/drivers/crypto/marvell/Makefile b/drivers/crypto/marvell/Makefile
new file mode 100644
index 000..68d0982
--- /dev/null
+++ b/drivers/crypto/marvell/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell-cesa.o
+marvell-cesa-objs := cesa.o cipher.o hash.o
diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
new file mode 100644
index 000..76a6943
--- /dev/null
+++ b/drivers/crypto/marvell/cesa.c
@@ -0,0 +1,417 @@
+/*
+ * Support for Marvell's Cryptographic Engine and Security Accelerator (CESA)
+ * that can be found on the following platform: Orion, Kirkwood, Armada. This
+ * driver supports the TDMA engine on platforms on which it is available.
+ *
+ * Author: Boris Brezillon 
+ * Author: Arnaud Ebalard 
+ *
+ * This work is based on an initial version written by
+ * Sebastian Andrzej Siewior < sebastian at breakpoint dot cc >
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cesa.h"
+
+struct mv_cesa_dev *cesa_dev;
+
+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(&cesa_dev->lock);
+   backlog = crypto_get_backlog(&cesa_dev->queue);
+   req = crypto_dequeue_request(&cesa_dev->queue);
+   engine->req = req;
+   spin_unlock_bh(&cesa_dev->lock);
+
+   if (!req)
+   return;
+
+   if (backlog)
+   backlog->complete(backlog, -EINPROGRESS);
+
+   ctx = crypto_tfm_ctx(req->tfm);
+   ctx->ops->prepare(req, engine);
+   ctx->ops->step(req);
+}
+
+static irqreturn_t mv_cesa_int(int irq, void *priv)
+{
+   struct mv_cesa_engine *engine = priv;
+   struct crypto_async_request *req;
+   struct

[PATCH v5 10/14] crypto: marvell/CESA: add support for all armada SoCs

2015-06-16 Thread Boris Brezillon
Add CESA IP description for all the missing armada SoCs (XP, 375 and 38x).

Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 9c43cd7e..af590bf 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -195,8 +195,20 @@ static const struct mv_cesa_caps armada_370_caps = {
.has_tdma = true,
 };
 
+static const struct mv_cesa_caps armada_xp_caps = {
+   .nengines = 2,
+   .cipher_algs = armada_370_cipher_algs,
+   .ncipher_algs = ARRAY_SIZE(armada_370_cipher_algs),
+   .ahash_algs = armada_370_ahash_algs,
+   .nahash_algs = ARRAY_SIZE(armada_370_ahash_algs),
+   .has_tdma = true,
+};
+
 static const struct of_device_id mv_cesa_of_match_table[] = {
{ .compatible = "marvell,armada-370-crypto", .data = &armada_370_caps },
+   { .compatible = "marvell,armada-xp-crypto", .data = &armada_xp_caps },
+   { .compatible = "marvell,armada-375-crypto", .data = &armada_xp_caps },
+   { .compatible = "marvell,armada-38x-crypto", .data = &armada_xp_caps },
{}
 };
 MODULE_DEVICE_TABLE(of, mv_cesa_of_match_table);
-- 
1.9.1

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


[PATCH v5 06/14] crypto: marvell/CESA: add DES support

2015-06-16 Thread Boris Brezillon
Add support for DES operations.

Signed-off-by: Boris Brezillon 
Signed-off-by: Arnaud Ebalard 
---
 drivers/crypto/marvell/cesa.c   |   2 +
 drivers/crypto/marvell/cesa.h   |   2 +
 drivers/crypto/marvell/cipher.c | 150 
 3 files changed, 154 insertions(+)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 986f024..212840e 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -169,6 +169,8 @@ static void mv_cesa_remove_algs(struct mv_cesa_dev *cesa)
 }
 
 static struct crypto_alg *armada_370_cipher_algs[] = {
+   &mv_cesa_ecb_des_alg,
+   &mv_cesa_cbc_des_alg,
&mv_cesa_ecb_aes_alg,
&mv_cesa_cbc_aes_alg,
 };
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 1a48323..2ee48fe 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -777,6 +777,8 @@ int mv_cesa_dma_add_op_transfers(struct mv_cesa_tdma_chain 
*chain,
 extern struct ahash_alg mv_sha1_alg;
 extern struct ahash_alg mv_ahmac_sha1_alg;
 
+extern struct crypto_alg mv_cesa_ecb_des_alg;
+extern struct crypto_alg mv_cesa_cbc_des_alg;
 extern struct crypto_alg mv_cesa_ecb_aes_alg;
 extern struct crypto_alg mv_cesa_cbc_aes_alg;
 
diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c
index 233f5bf..31b9311 100644
--- a/drivers/crypto/marvell/cipher.c
+++ b/drivers/crypto/marvell/cipher.c
@@ -13,9 +13,15 @@
  */
 
 #include 
+#include 
 
 #include "cesa.h"
 
+struct mv_cesa_des_ctx {
+   struct mv_cesa_ctx base;
+   u8 key[DES_KEY_SIZE];
+};
+
 struct mv_cesa_aes_ctx {
struct mv_cesa_ctx base;
struct crypto_aes_ctx aes;
@@ -231,6 +237,30 @@ static int mv_cesa_aes_setkey(struct crypto_ablkcipher 
*cipher, const u8 *key,
return 0;
 }
 
+static int mv_cesa_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
+ unsigned int len)
+{
+   struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+   struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(tfm);
+   u32 tmp[DES_EXPKEY_WORDS];
+   int ret;
+
+   if (len != DES_KEY_SIZE) {
+   crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+   return -EINVAL;
+   }
+
+   ret = des_ekey(tmp, key);
+   if (!ret && (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
+   tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
+   return -EINVAL;
+   }
+
+   memcpy(ctx->key, key, DES_KEY_SIZE);
+
+   return 0;
+}
+
 static int mv_cesa_ablkcipher_dma_req_init(struct ablkcipher_request *req,
const struct mv_cesa_op_ctx *op_templ)
 {
@@ -351,6 +381,126 @@ static int mv_cesa_ablkcipher_req_init(struct 
ablkcipher_request *req,
return ret;
 }
 
+static int mv_cesa_des_op(struct ablkcipher_request *req,
+ struct mv_cesa_op_ctx *tmpl)
+{
+   struct mv_cesa_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+   int ret;
+
+   mv_cesa_update_op_cfg(tmpl, CESA_SA_DESC_CFG_CRYPTM_DES,
+ CESA_SA_DESC_CFG_CRYPTM_MSK);
+
+   memcpy(tmpl->ctx.blkcipher.key, ctx->key, DES_KEY_SIZE);
+
+   ret = mv_cesa_ablkcipher_req_init(req, tmpl);
+   if (ret)
+   return ret;
+
+   ret = mv_cesa_queue_req(&req->base);
+   if (ret && ret != -EINPROGRESS)
+   mv_cesa_ablkcipher_cleanup(req);
+
+   return ret;
+}
+
+static int mv_cesa_ecb_des_encrypt(struct ablkcipher_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl,
+  CESA_SA_DESC_CFG_CRYPTCM_ECB |
+  CESA_SA_DESC_CFG_DIR_ENC);
+
+   return mv_cesa_des_op(req, &tmpl);
+}
+
+static int mv_cesa_ecb_des_decrypt(struct ablkcipher_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl,
+  CESA_SA_DESC_CFG_CRYPTCM_ECB |
+  CESA_SA_DESC_CFG_DIR_DEC);
+
+   return mv_cesa_des_op(req, &tmpl);
+}
+
+struct crypto_alg mv_cesa_ecb_des_alg = {
+   .cra_name = "ecb(des)",
+   .cra_driver_name = "mv-ecb-des",
+   .cra_priority = 300,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC,
+   .cra_blocksize = DES_BLOCK_SIZE,
+   .cra_ctxsize = sizeof(struct mv_cesa_des_ctx),
+   .cra_alignmask = 0,
+   .cra_type = &crypto_ablkcipher_type,
+   .cra_module = THIS_MODULE,
+   .cra_init = mv_cesa_ablkcipher_cra_init,
+   .cra_u = {
+   .ablkcipher = {
+   .min_keysize = DES_KEY_SIZE,
+   .max_keysize = DES_KEY_SIZE,
+   .setkey = mv_cesa_des_setkey,
+   .encrypt = mv_cesa_ecb_des_encrypt,
+   .decrypt = mv_cesa_ecb_des_decrypt,
+   },
+   

[PATCH v5 14/14] crypto: marvell/CESA: add DT bindings documentation

2015-06-16 Thread Boris Brezillon
Add DT bindings documentation for the new marvell-cesa driver.

Signed-off-by: Boris Brezillon 
---
 .../devicetree/bindings/crypto/marvell-cesa.txt| 45 ++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/crypto/marvell-cesa.txt

diff --git a/Documentation/devicetree/bindings/crypto/marvell-cesa.txt 
b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt
new file mode 100644
index 000..c6c6a4a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt
@@ -0,0 +1,45 @@
+Marvell Cryptographic Engines And Security Accelerator
+
+Required properties:
+- compatible: should be one of the following string
+ "marvell,orion-crypto"
+ "marvell,kirkwood-crypto"
+ "marvell,dove-crypto"
+ "marvell,armada-370-crypto"
+ "marvell,armada-xp-crypto"
+ "marvell,armada-375-crypto"
+ "marvell,armada-38x-crypto"
+- reg: base physical address of the engine and length of memory mapped
+   region. Can also contain an entry for the SRAM attached to the CESA,
+   but this representation is deprecated and marvell,crypto-srams should
+   be used instead
+- reg-names: "regs". Can contain an "sram" entry, but this representation
+is deprecated and marvell,crypto-srams should be used instead
+- interrupts: interrupt number
+- clocks: reference to the crypto engines clocks. This property is not
+ required for orion and kirkwood platforms
+- clock-names: "cesaX" and "cesazX", X should be replaced by the crypto engine
+  id.
+  This property is not required for the orion and kirkwoord
+  platforms.
+  "cesazX" clocks are not required on armada-370 platforms
+- marvell,crypto-srams: phandle to crypto SRAM definitions
+
+Optional properties:
+- marvell,crypto-sram-size: SRAM size reserved for crypto operations, if not
+   specified the whole SRAM is used (2KB)
+
+
+Examples:
+
+   crypto@9 {
+   compatible = "marvell,armada-xp-crypto";
+   reg = <0x9 0x1>;
+   reg-names = "regs";
+   interrupts = <48>, <49>;
+   clocks = <&gateclk 23>, <&gateclk 23>;
+   clock-names = "cesa0", "cesa1";
+   marvell,crypto-srams = <&crypto_sram0>, <&crypto_sram1>;
+   marvell,crypto-sram-size = <0x600>;
+   status = "okay";
+   };
-- 
1.9.1

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


[PATCH v5 12/14] crypto: marvell/CESA: add support for Orion SoCs

2015-06-16 Thread Boris Brezillon
Add the Orion SoC description, and select this implementation by default
to support non-DT probing: Orion is the only platform where non-DT boards
are declaring the CESA block.

Control the allhwsupport module parameter to avoid probing the CESA IP when
the old CESA driver is enabled (unless it is explicitly requested to do
so).

Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c | 42 +++---
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index a05b5cb..8e5ea72 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -172,6 +172,22 @@ static void mv_cesa_remove_algs(struct mv_cesa_dev *cesa)
crypto_unregister_alg(cesa->caps->cipher_algs[i]);
 }
 
+static struct crypto_alg *orion_cipher_algs[] = {
+   &mv_cesa_ecb_des_alg,
+   &mv_cesa_cbc_des_alg,
+   &mv_cesa_ecb_des3_ede_alg,
+   &mv_cesa_cbc_des3_ede_alg,
+   &mv_cesa_ecb_aes_alg,
+   &mv_cesa_cbc_aes_alg,
+};
+
+static struct ahash_alg *orion_ahash_algs[] = {
+   &mv_md5_alg,
+   &mv_sha1_alg,
+   &mv_ahmac_md5_alg,
+   &mv_ahmac_sha1_alg,
+};
+
 static struct crypto_alg *armada_370_cipher_algs[] = {
&mv_cesa_ecb_des_alg,
&mv_cesa_cbc_des_alg,
@@ -190,6 +206,15 @@ static struct ahash_alg *armada_370_ahash_algs[] = {
&mv_ahmac_sha256_alg,
 };
 
+static const struct mv_cesa_caps orion_caps = {
+   .nengines = 1,
+   .cipher_algs = orion_cipher_algs,
+   .ncipher_algs = ARRAY_SIZE(orion_cipher_algs),
+   .ahash_algs = orion_ahash_algs,
+   .nahash_algs = ARRAY_SIZE(orion_ahash_algs),
+   .has_tdma = false,
+};
+
 static const struct mv_cesa_caps armada_370_caps = {
.nengines = 1,
.cipher_algs = armada_370_cipher_algs,
@@ -209,6 +234,7 @@ static const struct mv_cesa_caps armada_xp_caps = {
 };
 
 static const struct of_device_id mv_cesa_of_match_table[] = {
+   { .compatible = "marvell,orion-crypto", .data = &orion_caps },
{ .compatible = "marvell,armada-370-crypto", .data = &armada_370_caps },
{ .compatible = "marvell,armada-xp-crypto", .data = &armada_xp_caps },
{ .compatible = "marvell,armada-375-crypto", .data = &armada_xp_caps },
@@ -334,7 +360,7 @@ static void mv_cesa_put_sram(struct platform_device *pdev, 
int idx)
 
 static int mv_cesa_probe(struct platform_device *pdev)
 {
-   const struct mv_cesa_caps *caps = NULL;
+   const struct mv_cesa_caps *caps = &orion_caps;
const struct mbus_dram_target_info *dram;
const struct of_device_id *match;
struct device *dev = &pdev->dev;
@@ -349,14 +375,16 @@ static int mv_cesa_probe(struct platform_device *pdev)
return -EEXIST;
}
 
-   if (!dev->of_node)
-   return -ENOTSUPP;
+   if (dev->of_node) {
+   match = of_match_node(mv_cesa_of_match_table, dev->of_node);
+   if (!match || !match->data)
+   return -ENOTSUPP;
 
-   match = of_match_node(mv_cesa_of_match_table, dev->of_node);
-   if (!match || !match->data)
-   return -ENOTSUPP;
+   caps = match->data;
+   }
 
-   caps = match->data;
+   if (caps == &orion_caps && !allhwsupport)
+   return -ENOTSUPP;
 
cesa = devm_kzalloc(dev, sizeof(*cesa), GFP_KERNEL);
if (!cesa)
-- 
1.9.1

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


[PATCH v5 05/14] crypto: marvell/CESA: add TDMA support

2015-06-16 Thread Boris Brezillon
The CESA IP supports CPU offload through a dedicated DMA engine (TDMA)
which can control the crypto block.
When you use this mode, all the required data (operation metadata and
payload data) are transferred using DMA, and the results are retrieved
through DMA when possible (hash results are not retrieved through DMA yet),
thus reducing the involvement of the CPU and providing better performances
in most cases (for small requests, the cost of DMA preparation might
exceed the performance gain).

Note that some CESA IPs do not embed this dedicated DMA, hence the
activation of this feature on a per platform basis.

Signed-off-by: Boris Brezillon 
Signed-off-by: Arnaud Ebalard 
---
 drivers/crypto/Kconfig  |   1 +
 drivers/crypto/marvell/Makefile |   2 +-
 drivers/crypto/marvell/cesa.c   |  68 +++
 drivers/crypto/marvell/cesa.h   | 229 ++
 drivers/crypto/marvell/cipher.c | 166 +++-
 drivers/crypto/marvell/hash.c   | 414 +++-
 drivers/crypto/marvell/tdma.c   | 224 ++
 7 files changed, 1088 insertions(+), 16 deletions(-)
 create mode 100644 drivers/crypto/marvell/tdma.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index c15c5a5..cbf2957 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -186,6 +186,7 @@ config CRYPTO_DEV_MARVELL_CESA
help
  This driver allows you to utilize the Cryptographic Engines and
  Security Accelerator (CESA) which can be found on the Armada 370.
+ This driver supports CPU offload through DMA transfers.
 
  This driver is aimed at replacing the mv_cesa driver. This will only
  happen once it has received proper testing.
diff --git a/drivers/crypto/marvell/Makefile b/drivers/crypto/marvell/Makefile
index 68d0982..0c12b13 100644
--- a/drivers/crypto/marvell/Makefile
+++ b/drivers/crypto/marvell/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell-cesa.o
-marvell-cesa-objs := cesa.o cipher.o hash.o
+marvell-cesa-objs := cesa.o cipher.o hash.o tdma.o
diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 76a6943..986f024 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -184,6 +184,7 @@ static const struct mv_cesa_caps armada_370_caps = {
.ncipher_algs = ARRAY_SIZE(armada_370_cipher_algs),
.ahash_algs = armada_370_ahash_algs,
.nahash_algs = ARRAY_SIZE(armada_370_ahash_algs),
+   .has_tdma = true,
 };
 
 static const struct of_device_id mv_cesa_of_match_table[] = {
@@ -192,6 +193,66 @@ static const struct of_device_id mv_cesa_of_match_table[] 
= {
 };
 MODULE_DEVICE_TABLE(of, mv_cesa_of_match_table);
 
+static void
+mv_cesa_conf_mbus_windows(struct mv_cesa_engine *engine,
+ const struct mbus_dram_target_info *dram)
+{
+   void __iomem *iobase = engine->regs;
+   int i;
+
+   for (i = 0; i < 4; i++) {
+   writel(0, iobase + CESA_TDMA_WINDOW_CTRL(i));
+   writel(0, iobase + CESA_TDMA_WINDOW_BASE(i));
+   }
+
+   for (i = 0; i < dram->num_cs; i++) {
+   const struct mbus_dram_window *cs = dram->cs + i;
+
+   writel(((cs->size - 1) & 0x) |
+  (cs->mbus_attr << 8) |
+  (dram->mbus_dram_target_id << 4) | 1,
+  iobase + CESA_TDMA_WINDOW_CTRL(i));
+   writel(cs->base, iobase + CESA_TDMA_WINDOW_BASE(i));
+   }
+}
+
+static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
+{
+   struct device *dev = cesa->dev;
+   struct mv_cesa_dev_dma *dma;
+
+   if (!cesa->caps->has_tdma)
+   return 0;
+
+   dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+   if (!dma)
+   return -ENOMEM;
+
+   dma->tdma_desc_pool = dmam_pool_create("tdma_desc", dev,
+   sizeof(struct mv_cesa_tdma_desc),
+   16, 0);
+   if (!dma->tdma_desc_pool)
+   return -ENOMEM;
+
+   dma->op_pool = dmam_pool_create("cesa_op", dev,
+   sizeof(struct mv_cesa_op_ctx), 16, 0);
+   if (!dma->op_pool)
+   return -ENOMEM;
+
+   dma->cache_pool = dmam_pool_create("cesa_cache", dev,
+  CESA_MAX_HASH_BLOCK_SIZE, 1, 0);
+   if (!dma->cache_pool)
+   return -ENOMEM;
+
+   dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
+   if (!dma->cache_pool)
+   return -ENOMEM;
+
+   cesa->dma = dma;
+
+   return 0;
+}
+
 static int mv_cesa_get_sram(struct platform_device *pdev, int idx)
 {
struct mv_cesa_dev *cesa = platform_get_drvdata(pdev);
@@ -299,6 +360,10 @@ static int mv_cesa_probe(struct platform_device *pdev)
if (IS_ERR(cesa->regs))
return -ENOMEM;
 
+   ret = mv_cesa_de

[PATCH v5 13/14] crypto: marvell/CESA: add support for Kirkwood and Dove SoCs

2015-06-16 Thread Boris Brezillon
From: Arnaud Ebalard 

Add the Kirkwood and Dove SoC descriptions, and control the allhwsupport
module parameter to avoid probing the CESA IP when the old CESA driver is
enabled (unless it is explicitly requested to do so).

Signed-off-by: Arnaud Ebalard 
Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 8e5ea72..a432633 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -215,6 +215,15 @@ static const struct mv_cesa_caps orion_caps = {
.has_tdma = false,
 };
 
+static const struct mv_cesa_caps kirkwood_caps = {
+   .nengines = 1,
+   .cipher_algs = orion_cipher_algs,
+   .ncipher_algs = ARRAY_SIZE(orion_cipher_algs),
+   .ahash_algs = orion_ahash_algs,
+   .nahash_algs = ARRAY_SIZE(orion_ahash_algs),
+   .has_tdma = true,
+};
+
 static const struct mv_cesa_caps armada_370_caps = {
.nengines = 1,
.cipher_algs = armada_370_cipher_algs,
@@ -235,6 +244,8 @@ static const struct mv_cesa_caps armada_xp_caps = {
 
 static const struct of_device_id mv_cesa_of_match_table[] = {
{ .compatible = "marvell,orion-crypto", .data = &orion_caps },
+   { .compatible = "marvell,kirkwood-crypto", .data = &kirkwood_caps },
+   { .compatible = "marvell,dove-crypto", .data = &kirkwood_caps },
{ .compatible = "marvell,armada-370-crypto", .data = &armada_370_caps },
{ .compatible = "marvell,armada-xp-crypto", .data = &armada_xp_caps },
{ .compatible = "marvell,armada-375-crypto", .data = &armada_xp_caps },
@@ -383,7 +394,7 @@ static int mv_cesa_probe(struct platform_device *pdev)
caps = match->data;
}
 
-   if (caps == &orion_caps && !allhwsupport)
+   if ((caps == &orion_caps || caps == &kirkwood_caps) && !allhwsupport)
return -ENOTSUPP;
 
cesa = devm_kzalloc(dev, sizeof(*cesa), GFP_KERNEL);
-- 
1.9.1

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


[PATCH v5 11/14] crypto: marvell/CESA: add allhwsupport module parameter

2015-06-16 Thread Boris Brezillon
The old and new marvell CESA drivers both support Orion and Kirkwood SoCs.
Add a module parameter to choose whether these SoCs should be attached to
the new or the old driver.

The default policy is to keep attaching those IPs to the old driver if it
is enabled, until we decide the new CESA driver is stable/secure enough.

Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index af590bf..a05b5cb 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -31,6 +31,10 @@
 
 #include "cesa.h"
 
+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)");
+
 struct mv_cesa_dev *cesa_dev;
 
 static void mv_cesa_dequeue_req_unlocked(struct mv_cesa_engine *engine)
-- 
1.9.1

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


[PATCH v5 09/14] crypto: marvell/CESA: add SHA256 support

2015-06-16 Thread Boris Brezillon
From: Arnaud Ebalard 

Add support for SHA256 operations.

Signed-off-by: Arnaud Ebalard 
Signed-off-by: Boris Brezillon 
---
 drivers/crypto/marvell/cesa.c |   2 +
 drivers/crypto/marvell/cesa.h |   2 +
 drivers/crypto/marvell/hash.c | 159 ++
 3 files changed, 163 insertions(+)

diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
index 047c1c0..9c43cd7e 100644
--- a/drivers/crypto/marvell/cesa.c
+++ b/drivers/crypto/marvell/cesa.c
@@ -180,8 +180,10 @@ static struct crypto_alg *armada_370_cipher_algs[] = {
 static struct ahash_alg *armada_370_ahash_algs[] = {
&mv_md5_alg,
&mv_sha1_alg,
+   &mv_sha256_alg,
&mv_ahmac_md5_alg,
&mv_ahmac_sha1_alg,
+   &mv_ahmac_sha256_alg,
 };
 
 static const struct mv_cesa_caps armada_370_caps = {
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index 2a7e21a..a328938 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -776,8 +776,10 @@ int mv_cesa_dma_add_op_transfers(struct mv_cesa_tdma_chain 
*chain,
 
 extern struct ahash_alg mv_md5_alg;
 extern struct ahash_alg mv_sha1_alg;
+extern struct ahash_alg mv_sha256_alg;
 extern struct ahash_alg mv_ahmac_md5_alg;
 extern struct ahash_alg mv_ahmac_sha1_alg;
+extern struct ahash_alg mv_ahmac_sha256_alg;
 
 extern struct crypto_alg mv_cesa_ecb_des_alg;
 extern struct crypto_alg mv_cesa_cbc_des_alg;
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index d8555c5..73d3f6f 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -975,6 +975,95 @@ struct ahash_alg mv_sha1_alg = {
}
 };
 
+static int mv_cesa_sha256_init(struct ahash_request *req)
+{
+   struct mv_cesa_op_ctx tmpl;
+
+   mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256);
+
+   mv_cesa_ahash_init(req, &tmpl);
+
+   return 0;
+}
+
+static int mv_cesa_sha256_digest(struct ahash_request *req)
+{
+   int ret;
+
+   ret = mv_cesa_sha256_init(req);
+   if (ret)
+   return ret;
+
+   return mv_cesa_ahash_finup(req);
+}
+
+static int mv_cesa_sha256_export(struct ahash_request *req, void *out)
+{
+   struct sha256_state *out_state = out;
+   struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+   struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
+   unsigned int ds = crypto_ahash_digestsize(ahash);
+
+   out_state->count = creq->len;
+   memcpy(out_state->state, creq->state, ds);
+   memset(out_state->buf, 0, sizeof(out_state->buf));
+   if (creq->cache)
+   memcpy(out_state->buf, creq->cache, creq->cache_ptr);
+
+   return 0;
+}
+
+static int mv_cesa_sha256_import(struct ahash_request *req, const void *in)
+{
+   const struct sha256_state *in_state = in;
+   struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+   struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
+   unsigned int digsize = crypto_ahash_digestsize(ahash);
+   unsigned int cache_ptr;
+   int ret;
+
+   creq->len = in_state->count;
+   memcpy(creq->state, in_state->state, digsize);
+   creq->cache_ptr = 0;
+
+   cache_ptr = creq->len % SHA256_BLOCK_SIZE;
+   if (!cache_ptr)
+   return 0;
+
+   ret = mv_cesa_ahash_alloc_cache(req);
+   if (ret)
+   return ret;
+
+   memcpy(creq->cache, in_state->buf, cache_ptr);
+   creq->cache_ptr = cache_ptr;
+
+   return 0;
+}
+
+struct ahash_alg mv_sha256_alg = {
+   .init = mv_cesa_sha256_init,
+   .update = mv_cesa_ahash_update,
+   .final = mv_cesa_ahash_final,
+   .finup = mv_cesa_ahash_finup,
+   .digest = mv_cesa_sha256_digest,
+   .export = mv_cesa_sha256_export,
+   .import = mv_cesa_sha256_import,
+   .halg = {
+   .digestsize = SHA256_DIGEST_SIZE,
+   .base = {
+   .cra_name = "sha256",
+   .cra_driver_name = "mv-sha256",
+   .cra_priority = 300,
+   .cra_flags = CRYPTO_ALG_ASYNC |
+CRYPTO_ALG_KERN_DRIVER_ONLY,
+   .cra_blocksize = SHA256_BLOCK_SIZE,
+   .cra_ctxsize = sizeof(struct mv_cesa_hash_ctx),
+   .cra_init = mv_cesa_ahash_cra_init,
+   .cra_module = THIS_MODULE,
+}
+   }
+};
+
 struct mv_cesa_ahash_result {
struct completion completion;
int error;
@@ -1280,3 +1369,73 @@ struct ahash_alg mv_ahmac_sha1_alg = {
 }
}
 };
+
+static int mv_cesa_ahmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key,
+  unsigned int keylen)
+{
+   struct mv_cesa_hmac_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+   struct sha256_state istate, ostate;
+   int ret, i;
+
+   ret = mv_cesa_ahmac_setkey("mv-s

[PATCH v5 03/14] crypto: mv_cesa: explicitly define kirkwood and dove compatible strings

2015-06-16 Thread Boris Brezillon
We are about to add a new driver to support new features like using the
TDMA engine to offload the CPU.
Orion, Dove and Kirkwood platforms are already using the mv_cesa driver,
but Orion SoCs do not embed the TDMA engine, which means we will have to
differentiate them if we want to get TDMA support on Dove and Kirkwood.
In the other hand, the migration from the old driver to the new one is not
something all people are willing to do without first auditing the new
driver.
Hence we have to support the new compatible in the mv_cesa driver so that
new platforms with updated DTs can still attach their crypto engine device
to this driver.

Signed-off-by: Boris Brezillon 
---
 Documentation/devicetree/bindings/crypto/mv_cesa.txt | 5 -
 drivers/crypto/mv_cesa.c | 4 +++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt 
b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
index 13b8fc5..c0c35f0 100644
--- a/Documentation/devicetree/bindings/crypto/mv_cesa.txt
+++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
@@ -1,7 +1,10 @@
 Marvell Cryptographic Engines And Security Accelerator
 
 Required properties:
-- compatible : should be "marvell,orion-crypto"
+- compatible: should be one of the following string
+ "marvell,orion-crypto"
+ "marvell,kirkwood-crypto"
+ "marvell,dove-crypto"
 - reg: base physical address of the engine and length of memory mapped
region. Can also contain an entry for the SRAM attached to the CESA,
but this representation is deprecated and marvell,crypto-srams should
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index a4c8637..fcab963 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -1034,7 +1034,7 @@ static int mv_cesa_get_sram(struct platform_device *pdev,
 &sram_size);
 
cp->sram_size = sram_size;
-   cp->sram_pool = of_get_named_gen_pool(&pdev->dev.of_node,
+   cp->sram_pool = of_get_named_gen_pool(pdev->dev.of_node,
  "marvell,crypto-srams", 0);
if (cp->sram_pool) {
cp->sram = gen_pool_dma_alloc(cp->sram_pool, sram_size,
@@ -1197,6 +1197,8 @@ static int mv_remove(struct platform_device *pdev)
 
 static const struct of_device_id mv_cesa_of_match_table[] = {
{ .compatible = "marvell,orion-crypto", },
+   { .compatible = "marvell,kirkwood-crypto", },
+   { .compatible = "marvell,dove-crypto", },
{}
 };
 MODULE_DEVICE_TABLE(of, mv_cesa_of_match_table);
-- 
1.9.1

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


[PATCH v5 02/14] crypto: mv_cesa: use gen_pool to reserve the SRAM memory region

2015-06-16 Thread Boris Brezillon
The mv_cesa driver currently expects the SRAM memory region to be passed
as a platform device resource.

This approach implies two drawbacks:
- the DT representation is wrong
- the only one that can access the SRAM is the crypto engine

The last point is particularly annoying in some cases: for example on
armada 370, a small region of the crypto SRAM is used to implement the
cpuidle, which means you would not be able to enable both cpuidle and the
CESA driver.

To address that problem, we explicitly define the SRAM device in the DT
and then reference the sram node from the crypto engine node.

Also note that the old way of retrieving the SRAM memory region is still
supported, or in other words, backward compatibility is preserved.

Signed-off-by: Boris Brezillon 
---
 .../devicetree/bindings/crypto/mv_cesa.txt | 24 ++---
 drivers/crypto/Kconfig |  1 +
 drivers/crypto/mv_cesa.c   | 58 --
 3 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt 
b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
index eaa2873..13b8fc5 100644
--- a/Documentation/devicetree/bindings/crypto/mv_cesa.txt
+++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
@@ -2,21 +2,29 @@ Marvell Cryptographic Engines And Security Accelerator
 
 Required properties:
 - compatible : should be "marvell,orion-crypto"
-- reg : base physical address of the engine and length of memory mapped
-region, followed by base physical address of sram and its memory
-length
-- reg-names : "regs" , "sram";
-- interrupts : interrupt number
+- reg: base physical address of the engine and length of memory mapped
+   region. Can also contain an entry for the SRAM attached to the CESA,
+   but this representation is deprecated and marvell,crypto-srams should
+   be used instead
+- reg-names: "regs". Can contain an "sram" entry, but this representation
+is deprecated and marvell,crypto-srams should be used instead
+- interrupts: interrupt number
 - clocks: reference to the crypto engines clocks. This property is only
  required for Dove platforms
+- marvell,crypto-srams: phandle to crypto SRAM definitions
+
+Optional properties:
+- marvell,crypto-sram-size: SRAM size reserved for crypto operations, if not
+   specified the whole SRAM is used (2KB)
 
 Examples:
 
crypto@3 {
compatible = "marvell,orion-crypto";
-   reg = <0x3 0x1>,
- <0x400 0x800>;
-   reg-names = "regs" , "sram";
+   reg = <0x3 0x1>;
+   reg-names = "regs";
interrupts = <22>;
+   marvell,crypto-srams = <&crypto_sram>;
+   marvell,crypto-sram-size = <0x600>;
status = "okay";
};
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 033c0c8..a6bbea8 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -166,6 +166,7 @@ config CRYPTO_DEV_MV_CESA
select CRYPTO_AES
select CRYPTO_BLKCIPHER2
select CRYPTO_HASH
+   select SRAM
help
  This driver allows you to utilize the Cryptographic Engines and
  Security Accelerator (CESA) which can be found on the Marvell Orion
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 27b2373..a4c8637 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -29,6 +30,8 @@
 #define MAX_HW_HASH_SIZE   0x
 #define MV_CESA_EXPIRE 500 /* msec */
 
+#define MV_CESA_DEFAULT_SRAM_SIZE  2048
+
 /*
  * STM:
  *   /---\
@@ -83,6 +86,8 @@ struct req_progress {
 struct crypto_priv {
void __iomem *reg;
void __iomem *sram;
+   struct gen_pool *sram_pool;
+   dma_addr_t sram_dma;
int irq;
struct clk *clk;
struct task_struct *queue_th;
@@ -1019,6 +1024,39 @@ static struct ahash_alg mv_hmac_sha1_alg = {
 }
 };
 
+static int mv_cesa_get_sram(struct platform_device *pdev,
+   struct crypto_priv *cp)
+{
+   struct resource *res;
+   u32 sram_size = MV_CESA_DEFAULT_SRAM_SIZE;
+
+   of_property_read_u32(pdev->dev.of_node, "marvell,crypto-sram-size",
+&sram_size);
+
+   cp->sram_size = sram_size;
+   cp->sram_pool = of_get_named_gen_pool(&pdev->dev.of_node,
+ "marvell,crypto-srams", 0);
+   if (cp->sram_pool) {
+   cp->sram = gen_pool_dma_alloc(cp->sram_pool, sram_size,
+ &cp->sram_dma);
+   if (cp->sram)
+   return 0;
+
+   return -ENOMEM;
+   }
+
+   res = 

[PATCH v5 01/14] crypto: mv_cesa: document the clocks property

2015-06-16 Thread Boris Brezillon
On Dove platforms, the crypto engine requires a clock. Document this
clocks property in the mv_cesa bindings doc.

Signed-off-by: Boris Brezillon 
---
 Documentation/devicetree/bindings/crypto/mv_cesa.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt 
b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
index 47229b1..eaa2873 100644
--- a/Documentation/devicetree/bindings/crypto/mv_cesa.txt
+++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
@@ -7,6 +7,8 @@ Required properties:
 length
 - reg-names : "regs" , "sram";
 - interrupts : interrupt number
+- clocks: reference to the crypto engines clocks. This property is only
+ required for Dove platforms
 
 Examples:
 
-- 
1.9.1

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


[PATCH v5 00/14] crypto: add a new driver for Marvell's CESA

2015-06-16 Thread Boris Brezillon
Hello,

This patch series adds a new driver supporting Marvell's CESA IP.
This driver addresses some limitations of the existing one.
>From a performance and CPU load point of view the most important
limitation in the existing driver is the lack of DMA support, thus
preventing us from chaining crypto operations.

I know we usually try to adapt existing drivers instead of replacing them
by new ones, but after trying to refactor the mv_cesa driver I realized it
would take longer than writing an new one from scratch.

Here are the main features brought by this new driver:
- support for armada SoCs (up to 38x) while keeping support for older ones
  (Orion and Kirkwood). Note that old DT bindings (those used on Orion and
  Kirkwood platforms) are supported, or IOTW, old DTs are compatible with
  this new driver.
- DMA mode to offload the CPU in case of intensive crypto usage
- new algorithms: SHA256, DES and 3DES

I'd like to thank Arnaud, who has carefully reviewed several iterations of
this driver, helped me improved my implementation, provided support for
several crypto algorithms, provided support for armada-370 and tested
the driver on different platforms, hence the SoB and dual MODULE_AUTHOR
in the driver code.

In this version I dropped the DT changes, but you'll find them in my
cesa-v4 branch [1]. In this branch you'll find everything you need to
test on all Marvell platforms (including the old ones).
I'll post a series updating all the DTs once this driver has been merged.

Best Regards,

Boris

[1]https://github.com/bbrezillon/linux-marvell/tree/cesa-v5

Changes since v4:
- fix the dma_map_sg return code check
- add import/export functions to all HMAC algos
- update the passed IV when handling cipher requests
- properly handle requests in the crypto queue backlog
- use sg_nents_for_len

Changes since v3:
- add import functions for hash algorithms
- patch mv_cesa driver to support the new DT bindings
- few fixes in the documentation
- replace mv_mbus_dram_info() call by mv_mbus_dram_info_nooverlap()
- remove DT updates from the series

Changes since v2:
- fixes in the cipher code (->dst_nents was assigned the ->src_nents
  value and CBC state was overwritten by the IV after each chunk
  operation)
- spit the code as suggested by Sebastian

Changes since v1:
- (suggested by Jason) kept the existing CESA driver and added a mechanism
  to prevent the new driver from probing devices handled my the existing
  one (Orion and Kirkwood platforms)
- (reported by Paul) addressed a few Kconfig and module definition issues
- (suggested by Andrew) added DT changes to the series

Arnaud Ebalard (4):
  crypto: marvell/CESA: add Triple-DES support
  crypto: marvell/CESA: add MD5 support
  crypto: marvell/CESA: add SHA256 support
  crypto: marvell/CESA: add support for Kirkwood and Dove SoCs

Boris Brezillon (10):
  crypto: mv_cesa: document the clocks property
  crypto: mv_cesa: use gen_pool to reserve the SRAM memory region
  crypto: mv_cesa: explicitly define kirkwood and dove compatible
strings
  crypto: add a new driver for Marvell's CESA
  crypto: marvell/CESA: add TDMA support
  crypto: marvell/CESA: add DES support
  crypto: marvell/CESA: add support for all armada SoCs
  crypto: marvell/CESA: add allhwsupport module parameter
  crypto: marvell/CESA: add support for Orion SoCs
  crypto: marvell/CESA: add DT bindings documentation

 .../devicetree/bindings/crypto/marvell-cesa.txt|   45 +
 .../devicetree/bindings/crypto/mv_cesa.txt |   31 +-
 drivers/crypto/Kconfig |   18 +
 drivers/crypto/Makefile|1 +
 drivers/crypto/marvell/Makefile|2 +
 drivers/crypto/marvell/cesa.c  |  548 
 drivers/crypto/marvell/cesa.h  |  791 +++
 drivers/crypto/marvell/cipher.c|  784 +++
 drivers/crypto/marvell/hash.c  | 1441 
 drivers/crypto/marvell/tdma.c  |  224 +++
 drivers/crypto/mv_cesa.c   |   60 +-
 11 files changed, 3921 insertions(+), 24 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/marvell-cesa.txt
 create mode 100644 drivers/crypto/marvell/Makefile
 create mode 100644 drivers/crypto/marvell/cesa.c
 create mode 100644 drivers/crypto/marvell/cesa.h
 create mode 100644 drivers/crypto/marvell/cipher.c
 create mode 100644 drivers/crypto/marvell/hash.c
 create mode 100644 drivers/crypto/marvell/tdma.c

-- 
1.9.1

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


[PATCH 2/2] crypto: testmgr: add iv_out information for all CBC testvec

2015-06-16 Thread Boris Brezillon
Add iv_out information to all CBC testvec so that the testmgr can verify
the IV value after each cipher request.

Signed-off-by: Boris Brezillon 
---
 crypto/testmgr.h | 81 
 1 file changed, 81 insertions(+)

diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 03320f9..682e464 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -3274,6 +3274,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+   .iv_out = "\x46\x8e\x91\x15\x78\x88\xba\x68",
.input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
  "\x4e\x6f\x77\x20\x69\x73\x20\x74"
  "\x68\x65\x20\x74\x69\x6d\x65\x20",
@@ -3286,6 +3287,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+   .iv_out = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
.input  = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
.ilen   = 8,
.result = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
@@ -3294,6 +3296,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+   .iv_out = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
.input  = "\x68\x65\x20\x74\x69\x6d\x65\x20",
.ilen   = 8,
.result = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
@@ -3302,6 +3305,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+   .iv_out = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
.input  = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
.ilen   = 8,
.result = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
@@ -3311,6 +3315,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+   .iv_out = "\x46\x8e\x91\x15\x78\x88\xba\x68",
.input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
  "\x4e\x6f\x77\x20\x69\x73\x20\x74"
  "\x68\x65\x20\x74\x69\x6d\x65\x20",
@@ -3325,6 +3330,7 @@ static struct cipher_testvec des_cbc_enc_tv_template[] = {
.key= "\xC9\x83\xA6\xC9\xEC\x0F\x32\x55",
.klen   = 8,
.iv = "\xE7\x82\x1D\xB8\x53\x11\xAC\x47",
+   .iv_out = "\xC6\x4A\xF3\x55\xC7\x29\x2E\x63",
.input  = "\x50\xB9\x22\xAE\x17\x80\x0C\x75"
  "\xDE\x47\xD3\x3C\xA5\x0E\x9A\x03"
  "\x6C\xF8\x61\xCA\x33\xBF\x28\x91"
@@ -3400,6 +3406,7 @@ static struct cipher_testvec des_cbc_dec_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+   .iv_out = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
.input  = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
.ilen   = 8,
.result = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
@@ -3408,6 +3415,7 @@ static struct cipher_testvec des_cbc_dec_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+   .iv_out = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
.input  = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
.ilen   = 8,
.result = "\x68\x65\x20\x74\x69\x6d\x65\x20",
@@ -3416,6 +3424,7 @@ static struct cipher_testvec des_cbc_dec_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+   .iv_out = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
.input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
.ilen   = 8,
.result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
@@ -3424,6 +3433,7 @@ static struct cipher_testvec des_cbc_dec_tv_template[] = {
.key= "\x01\x23\x45\x67\x89\xab\xcd\xef",
.klen   = 8,
.iv = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+   .iv_out = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
.input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
.ilen   = 8,
.result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
@@ -3434,6 +3444,7 @@ stati

[PATCH 0/2] crypto: testmgr: test IV value after a cipher operation

2015-06-16 Thread Boris Brezillon
Hello,

Crypto drivers are supposed to update the IV passed to a cipher request
but it appears that some of them are not updating it.
The first patch of this series adds a new test for cipher algo (test the IV
value after a cipher operation) and the second one adds the expected IV value
to all the CBC test vectors.

Other cipher modes (LRW, CTR, ...) should be updated too.

Best Regards,

Boris

Boris Brezillon (2):
  crypto: testmgr: test IV value after a cipher operation
  crypto: testmgr: add iv_out information for all CBC testvec

 crypto/testmgr.c | 12 -
 crypto/testmgr.h | 82 
 2 files changed, 93 insertions(+), 1 deletion(-)

-- 
1.9.1

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


[PATCH 1/2] crypto: testmgr: test IV value after a cipher operation

2015-06-16 Thread Boris Brezillon
The crypto drivers are supposed to update the IV passed to the crypto
request before calling the completion callback.
Test for the IV value before considering the test as successful.

Signed-off-by: Boris Brezillon 
---
 crypto/testmgr.c | 12 +++-
 crypto/testmgr.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index f9bce3d..e6b5f24 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1013,12 +1013,22 @@ static int __test_skcipher(struct crypto_ablkcipher 
*tfm, int enc,
 
q = data;
if (memcmp(q, template[i].result, template[i].rlen)) {
-   pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
+   pr_err("alg: skcipher%s: Test %d failed (invalid 
result) on %s for %s\n",
   d, j, e, algo);
hexdump(q, template[i].rlen);
ret = -EINVAL;
goto out;
}
+
+   if (template[i].iv_out &&
+   memcmp(iv, template[i].iv_out,
+  crypto_ablkcipher_ivsize(tfm))) {
+   pr_err("alg: skcipher%s: Test %d failed (invalid output 
IV) on %s for %s\n",
+  d, j, e, algo);
+   hexdump(iv, crypto_ablkcipher_ivsize(tfm));
+   ret = -EINVAL;
+   goto out;
+   }
}
 
j = 0;
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 62e2485..03320f9 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -49,6 +49,7 @@ struct hash_testvec {
 struct cipher_testvec {
char *key;
char *iv;
+   char *iv_out;
char *input;
char *result;
unsigned short tap[MAX_TAP];
-- 
1.9.1

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


[PATCH] crypto: poly1305 - Pass key as first two message blocks to each desc_ctx

2015-06-16 Thread Martin Willi
The Poly1305 authenticator requires a unique key for each generated tag. This
implies that we can't set the key per tfm, as multiple users set individual
keys. Instead we pass a desc specific key as the first two blocks of the
message to authenticate in update().

Signed-off-by: Martin Willi 
---
 crypto/chacha20poly1305.c | 54 +++---
 crypto/poly1305_generic.c | 97 --
 crypto/testmgr.h  | 99 +--
 3 files changed, 134 insertions(+), 116 deletions(-)

diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index 05fbc59..7b46ed7 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -54,14 +54,14 @@ struct poly_req {
 };
 
 struct chacha_req {
-   /* the key we generate for Poly1305 using Chacha20 */
-   u8 key[POLY1305_KEY_SIZE];
u8 iv[CHACHA20_IV_SIZE];
struct scatterlist src[1];
struct ablkcipher_request req; /* must be last member */
 };
 
 struct chachapoly_req_ctx {
+   /* the key we generate for Poly1305 using Chacha20 */
+   u8 key[POLY1305_KEY_SIZE];
/* calculated Poly1305 tag */
u8 tag[POLY1305_DIGEST_SIZE];
/* length of data to en/decrypt, without ICV */
@@ -294,53 +294,59 @@ static int poly_ad(struct aead_request *req)
return poly_adpad(req);
 }
 
-static void poly_init_done(struct crypto_async_request *areq, int err)
+static void poly_setkey_done(struct crypto_async_request *areq, int err)
 {
async_done_continue(areq->data, err, poly_ad);
 }
 
-static int poly_init(struct aead_request *req)
+static int poly_setkey(struct aead_request *req)
 {
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
struct poly_req *preq = &rctx->u.poly;
int err;
 
+   sg_init_table(preq->src, 1);
+   sg_set_buf(preq->src, rctx->key, sizeof(rctx->key));
+
ahash_request_set_callback(&preq->req, aead_request_flags(req),
-  poly_init_done, req);
+  poly_setkey_done, req);
ahash_request_set_tfm(&preq->req, ctx->poly);
+   ahash_request_set_crypt(&preq->req, preq->src, NULL, sizeof(rctx->key));
 
-   err = crypto_ahash_init(&preq->req);
+   err = crypto_ahash_update(&preq->req);
if (err)
return err;
 
return poly_ad(req);
 }
 
-static int poly_genkey_continue(struct aead_request *req)
+static void poly_init_done(struct crypto_async_request *areq, int err)
 {
-   struct crypto_aead *aead = crypto_aead_reqtfm(req);
-   struct chachapoly_ctx *ctx = crypto_aead_ctx(aead);
+   async_done_continue(areq->data, err, poly_setkey);
+}
+
+static int poly_init(struct aead_request *req)
+{
+   struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
-   struct chacha_req *creq = &rctx->u.chacha;
+   struct poly_req *preq = &rctx->u.poly;
int err;
 
-   crypto_ahash_clear_flags(ctx->poly, CRYPTO_TFM_REQ_MASK);
-   crypto_ahash_set_flags(ctx->poly, crypto_aead_get_flags(aead) &
-  CRYPTO_TFM_REQ_MASK);
+   ahash_request_set_callback(&preq->req, aead_request_flags(req),
+  poly_init_done, req);
+   ahash_request_set_tfm(&preq->req, ctx->poly);
 
-   err = crypto_ahash_setkey(ctx->poly, creq->key, sizeof(creq->key));
-   crypto_aead_set_flags(aead, crypto_ahash_get_flags(ctx->poly) &
- CRYPTO_TFM_RES_MASK);
+   err = crypto_ahash_init(&preq->req);
if (err)
return err;
 
-   return poly_init(req);
+   return poly_setkey(req);
 }
 
 static void poly_genkey_done(struct crypto_async_request *areq, int err)
 {
-   async_done_continue(areq->data, err, poly_genkey_continue);
+   async_done_continue(areq->data, err, poly_init);
 }
 
 static int poly_genkey(struct aead_request *req)
@@ -351,8 +357,8 @@ static int poly_genkey(struct aead_request *req)
int err;
 
sg_init_table(creq->src, 1);
-   memset(creq->key, 0, sizeof(creq->key));
-   sg_set_buf(creq->src, creq->key, sizeof(creq->key));
+   memset(rctx->key, 0, sizeof(rctx->key));
+   sg_set_buf(creq->src, rctx->key, sizeof(rctx->key));
 
chacha_iv(creq->iv, req, 0);
 
@@ -366,7 +372,7 @@ static int poly_genkey(struct aead_request *req)
if (err)
return err;
 
-   return poly_genkey_continue(req);
+   return poly_init(req);
 }
 
 static void chacha_encrypt_done(struct crypto_async_request *areq, int err)
@@ -403,8 +409,9 @@ static int chachapoly_encrypt(struct aead_request *req)
 
/* encrypt call chain:
 * - chacha_encrypt/done()
-* - poly_genkey/done/continue()
+* - poly_ge

Re: [PATCH RFC v6 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Herbert Xu
On Tue, Jun 16, 2015 at 01:02:05AM -0700, Tadeusz Struk wrote:
>
> + if (!pkey->n || !pkey->e || !req->dst_len)
> + return -EINVAL;

You leaked m.

> + if (*req->dst_len < mpi_get_size(pkey->n)) {
> + *req->dst_len = mpi_get_size(pkey->n);
> + return -EINVAL;
> + }

This needs to be an error that's distinct from real errors.  So
perhaps pick EOVERFLOW.

> +static int rsa_init_tfm(struct crypto_tfm *_tfm)
> +{
> + return 0;
> +}

The init function is optional.  So just drop it if there is nothing
to be done.

> + .encrypt = rsa_enc,
> + .decrypt = rsa_dec,
> + .sign = rsa_sign,
> + .verify = rsa_verify,
> + .setkey = rsa_setkey,
> + .base = {
> + .cra_name = "rsa",
> + .cra_driver_name = "rsa-generic",
> + .cra_priority = 100,
> + .cra_ctxsize = 0,
> + .cra_alignmask = 0,
> + .cra_module = THIS_MODULE,
> + .cra_ctxsize = sizeof(struct rsa_key),

You're initialising cra_ctxsize twice.  Also please drop the
alignmask since the default is zero.

> + .cra_init = rsa_init_tfm,
> + .cra_exit = rsa_exit_tfm,
> + },
> +};

Please drop cra_init/cra_exit and add type-safe init/exit functions
like I did in 5eb8ec6dc857d5027bc8cf7268a199107a583ae5

> diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
> new file mode 100644
> index 000..103dd2e
> --- /dev/null
> +++ b/crypto/rsa_helper.c
> @@ -0,0 +1,124 @@
> +/*
> + * RSA key extract helper
> + *
> + * Copyright (c) 2015, Intel Corporation
> + * Authors: Tadeusz Struk 
> + *
> + * 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 "rsakey-asn1.h"

Need export.h.

> +static void free_mpis(struct rsa_key *key)
> +{
> + if (key->n)
> + mpi_free(key->n);

mpi_free already checks for NULL, so you can remove the check
here.

> diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
> new file mode 100644
> index 000..018f373
> --- /dev/null
> +++ b/include/crypto/internal/rsa.h
> @@ -0,0 +1,28 @@
> +/*
> + * RSA internal helpers
> + *
> + * Copyright (c) 2015, Intel Corporation
> + * Authors: Tadeusz Struk 
> + *
> + * 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.
> + *
> + */
> +#ifndef _RSA_HELPER_
> +#define _RSA_HELPER_
> +#include 
> +#include 

You should drop akcipher.h since nothing in this file uses it.

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 RFC v6 1/3] crypto: add PKE API

2015-06-16 Thread Herbert Xu
On Tue, Jun 16, 2015 at 01:01:59AM -0700, Tadeusz Struk wrote:
>
> @@ -28,6 +28,7 @@ crypto_hash-y += shash.o
>  obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
>  
>  obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
> +obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o

s/AKCIPHER/AKCIPHER2/

> +/**
> + * struct akcipher_request - public key request
> + *
> + * @base:Common attributes for async crypto requests
> + * @src: Pointer to memory containing the input parameters
> + *   The format of the parameter(s) is expeted to be Octet String
> + * @dst: Pointer to memory whare the result will be stored
> + * @src_len: Size of the input parameter
> + * @dst_len: Size of the output buffer. It needs to be at leaset
> + *   as big as the expected result depending on the operation
> + *   After operation it will be updated with the acctual size of the
> + *   result. In case of error, where the dst_len was insufficient,
> + *   it will be updated to the size required for the operation.
> + * @result_len: If not NULL this will be updated by the implementation to
> + *   reflect the acctual size of the result

result_len is still here.

> + * @__ctx:   Start of private context data
> + */
> +struct akcipher_request {
> + struct crypto_async_request base;
> + void *src;
> + void *dst;
> + unsigned int src_len;
> + unsigned int *dst_len;

dst_len doesn't need to be a pointer.  A simple int will do.

> +static inline int crypto_akcipher_encrypt(struct akcipher_request *req)
> +{
> + struct crypto_akcipher *tfm = __crypto_akcipher_tfm(req->base.tfm);

You should add a reqtfm helper like crypto_aead_reqtfm so that
implementors don't need to do this ugly __crypto_akcipher_tfm.

In fact you already have that helper so you just need to use it.

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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: [BUG?] crypto: caam: little/big endianness on ARM vs PPC

2015-06-16 Thread Jon Nettleton
Victoria,

I was hoping you would join the conversation.  I know you have a
series of patches in Freescale's 3.14 git repository.  Have you
updated those for mainline and published them for review and inclusion
in the upstream kernel?  If yes to any could you post a link?

-Jon

On Tue, Jun 16, 2015 at 5:27 AM, Victoria Milhoan
 wrote:
> All,
>
> Freescale has been adding i.MX6 support to the CAAM driver and testing on 
> both i.MX6 and QorIQ platforms. The patch series is now available for review. 
> Your feedback for the provided patches is appreciated.
>
> Thanks,
> Victoria
>
> -Original Message-
> From: linux-crypto-ow...@vger.kernel.org 
> [mailto:linux-crypto-ow...@vger.kernel.org] On Behalf Of Herbert Xu
> Sent: Monday, June 15, 2015 3:05 PM
> To: Steffen Trumtrar
> Cc: linux-ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; 
> linux-crypto@vger.kernel.org; Gupta Ruchika-R66431; ker...@pengutronix.de; 
> Geanta Neag Horia Ioan-B05471; Kim Phillips
> Subject: Re: [BUG?] crypto: caam: little/big endianness on ARM vs PPC
>
> On Mon, Jun 15, 2015 at 05:59:07PM +0200, Steffen Trumtrar wrote:
>> Hi!
>>
>> I'm working on CAAM support for the ARM-based i.MX6 SoCs. The current
>> drivers/crypto/caam driver only works for PowerPC AFAIK.
>> Actually, there isn't that much to do, to get support for the i.MX6
>> but one patch breaks the driver severely:
>>
>>   commit ef94b1d834aace7101de77c3a7c2631b9ae9c5f6
>>   crypto: caam - Add definition of rd/wr_reg64 for little endian
>> platform
>>
>> This patch adds
>>
>> +#ifdef __LITTLE_ENDIAN
>> +static inline void wr_reg64(u64 __iomem *reg, u64 data) {
>> + wr_reg32((u32 __iomem *)reg + 1, (data & 0xull) >> 32);
>> + wr_reg32((u32 __iomem *)reg, data & 0xull); }
>>
>> The wr_reg64 function is only used in one place in the
>> drivers/crypto/caam/jr.c
>> driver: to write the dma_addr_t to the register. Without that patch
>> everything works fine on ARM (little endian, 32bit), with that patch
>> the driver will write 0's into the register that holds the DMA address (the 
>> numerically-higher) -> kernel hangs.
>> Also, from my understanding, the comment above the defines, stating
>> that you have to first write the numerically-lower and then the
>> numerically-higher address on 32bit systems doesn't match with the 
>> implementation.
>>
>> What I don't know/understand is if this makes any sense for any PowerPC 
>> implementation.
>>
>> So, the question is, how to fix this? I'd prefer to do it directly in
>> the jr driver instead of the ifdef-ery.
>>
>> Something like
>>   if (sizeof(dma_addr_t) == sizeof(u32))
>>   wr_reg32(&jrp->rregs->inpring_base + 1, inpbusaddr);
>>   else if (sizeof(dma_addr_t) == sizeof(u64))
>>   wr_reg64(...)
>>
>> or just go by DT compatible and then remove the inline function definitions.
>>
>> As far as I can tell, the compatible wouldn't be needed for anything
>> else in the jr driver, so maybe that is not optimal. On the other hand
>> the sizeof(..) solution would only catch little endian on 32bit and
>> not big endian (?!) I however don't know what combinations actually
>> *have* to be caught, as I don't know, which exist.
>>
>> So, what do you think people?
>
> I'm adding a couple of CCs.
>
> Thanks,
> --
> Email: Herbert Xu  Home Page: 
> http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
> --
> 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
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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 RFC v6 3/3] crypto: add tests vectors for RSA

2015-06-16 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig   |1 
 crypto/testmgr.c |  161 ++
 crypto/testmgr.h |  187 ++
 3 files changed, 349 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 52467cf..9471ac8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -122,6 +122,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
+   select CRYPTO_AKCIPHER2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..c773424 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1832,150 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int out_len_max, out_len = 0;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   init_completion(&result.completion);
+   err = crypto_akcipher_setkey(tfm, vecs->key, vecs->key_len);
+   if (err)
+   goto free_req;
+
+   akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
+  &out_len);
+   /* expect this to fail, and update the required buf len */
+   crypto_akcipher_encrypt(req);
+   if (!out_len) {
+   err = -EINVAL;
+   goto free_req;
+   }
+
+   out_len_max = out_len;
+
+   err = -ENOMEM;
+   outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_enc)
+   goto free_req;
+
+   akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
+  &out_len);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(&result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err("alg: rsa: encrypt test failed. err %d\n", err);
+   goto free_all;
+   }
+
+   if (out_len != vecs->c_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that encrypted message is equal to expected */
+   if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
+   pr_err("alg: rsa: encrypt test failed. Invalid output\n");
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* Don't invoke decrypt for vectors with public key */
+   if (vecs->public_key_test) {
+   err = 0;
+   goto free_all;
+   }
+
+   outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+
+   init_completion(&result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
+  &out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(&result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err("alg: rsa: decrypt test failed. err %d\n", err);
+   goto free_all;
+   }
+
+   if (out_len != vecs->m_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs->m, outbuf_dec, vecs->m_size)) {
+   pr_err("alg: rsa: encrypt test failed. Invalid output\n");
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct akcipher_testvec *vecs,
+   unsigned int tcount)
+{
+   int ret, i;
+
+   for (i = 0; i < tcount; i++) {
+   ret = do_test_rsa(tfm, vecs++);
+ 

[PATCH RFC v6 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig|7 +
 crypto/Makefile   |8 +
 crypto/rsa.c  |  313 +
 crypto/rsa_helper.c   |  124 
 crypto/rsakey.asn1|5 +
 include/crypto/internal/rsa.h |   28 
 6 files changed, 485 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/internal/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 264dadb..52467cf 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,6 +102,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate "RSA algorithm"
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 6f2940a..c6217ea 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
+$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
+clean-files += rsakey-asn1.c rsakey-asn1.h
+
+rsa_generic-y := rsakey-asn1.o
+rsa_generic-y += rsa.o
+rsa_generic-y += rsa_helper.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+
 cryptomgr-y := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..33bb7f0
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,313 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk 
+ *
+ * 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 
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 <= m < n */
+   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key->e, key->n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 <= c < n */
+   if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key->d, key->n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 <= m < n */
+   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key->d, key->n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 <= s < n */
+   if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key->e, key->n);
+}
+
+static struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct rsa_key *pkey = rsa_get_key(tfm);
+   MPI m, c = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (!pkey->n || !pkey->e || !req->dst_len)
+   return -EINVAL;
+
+   if (*req->dst_len < mpi_get_size(pkey->n)) {
+   *req->dst_len = mpi_get_size(pkey->n);
+   return -EINVAL;
+   }
+
+   m = mpi_read_raw_data(req->src, req->src_len);
+   if (!m) {
+   ret = -ENOMEM;
+   goto err_free_c;
+   }
+
+   ret = _rsa_enc(pkey, c, m);
+   if (ret)
+   goto err_free_m;
+
+   ret = mpi_read_buffer(c, req->dst, *req->dst_len, req->dst_len, &sign);
+   if (ret)
+   goto err_free_m;
+
+   if (sign < 0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+err_free_m:
+   mpi_free(m);
+err_free_c:
+   mpi_free(c);
+   return ret;
+}
+
+static int rsa_dec(struct akcipher_request *req)
+{
+   struct crypt

[PATCH RFC v6 0/3] crypto: Introduce Public Key Encryption API

2015-06-16 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

The benefits it gives interface are:
- drivers can add many implementations of RSA or DSA
  algorithms and user will allocate instances (tfms) of these, base on
  algorithm priority, in the same way as it is with the symmetric ciphers.
- the new interface allows for asynchronous implementations that
  can use crypto hardware to offload the calculations to.
- integrating it with linux crypto api allows using all its benefits
  i.e. managing algorithms using NETLINK_CRYPTO, monitoring implementations
  using /proc/crypto. etc

New helper functions have been added to allocate crypto_akcipher instances
and invoke the operations to make it easier to use.
For instance to verify a public_signature against a public_key using
the RSA algorithm a user would do:

struct crypto_akcipher *tfm = crypto_alloc_akcipher("rsa", 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, &res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

Changes in v6:
 - in FIPS mode only allow key sizes 2K & 3K
 - remove result_len and use dst_len as in/out param
 - remove subtype from akcipher reports
 - store rsa_key in tfm ctx and change ras_parse_key to take struct rsa_key
   instead of tfm. 
 - export rsa_free_key, which free memory allocated by ras_parse_key.
 - split akcipher.h into public and internal with public key specific helpers
 - remove maxsize() and set the required size in enc/dec/sign/verify instead
 - add public key vector
 - split AKCIPHER into AKCIPHER and AKCIPHER2 in Kconfig
 - remove MPI patch from the series - already applied

Changes in v5:
 - make mpi_get_size() function inline.
 - add a setkey function to the algorithm and rsa_parse_key() helper to
   parse rsa keys from BER encoded to MPI. The helper will also validate
   the given key if it is strong enough in case FIPS mode is enabled.
 - change the format of the key from struct public_key * to void * BER encoded
   buffer.
 - change the format of the rsa keys in testmgr to BER encoded form.
 - change mpi_free to use kzfree instead of kfree because it is used to free
   crypto keys

Changes in v4:
 - add an rsa generic implementation
 - don't convert the existing public_key implementation to the new interface.
   This will be done after the new interface is accepted.
 - add new mpi_get_buf(), mpi_copy() and mpi_get_size() mpi helpers 
 - on set key the ftm now will clone the key instead of just setting a ptr
 - add a check on enc/dec/sign/veryfi to make sure a valid (public or private)
   key is setup
 - add maxsize fn into algorith that will be used to query implementation
   what is the max size of a result for a give public key that the user needs
   to allocate
 - removed private ctx from crypto_akcipher as the crypto_tfm base has one
   already
 - add 2K bit RSA test vectors
 - add cipher text validation in crypto test mgr as (required for FIPS)

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len & dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (3):
  crypto: add PKE API
  crypto: rsa: add a new rsa generic implementation
  crypto: add tests vectors for RSA


 crypto/Kconfig |   19 ++
 crypto/Makefile|9 +
 crypto/akcipher.c  |  100 +++
 crypto/crypto_user.c   |   22 ++
 crypto/rsa.c   |  313 +++
 crypto/rsa_helper.c|  124 ++
 crypto/rsakey.asn1 |5 +
 crypto/testmgr.c   |  161 ++
 crypto/testmgr.h   |  187 +
 include/crypto/akc

[PATCH RFC v6 1/3] crypto: add PKE API

2015-06-16 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk 
---
 crypto/Kconfig |   11 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  100 +++
 crypto/crypto_user.c   |   22 ++
 include/crypto/akcipher.h  |  323 
 include/crypto/internal/akcipher.h |   66 +++
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |5 +
 8 files changed, 529 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h
 create mode 100644 include/crypto/internal/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..264dadb 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,17 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_AKCIPHER
+   tristate "Public Key Algorithms API"
+   select CRYPTO_AKCIPHER2
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..6f2940a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..eefcc49
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,100 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk 
+ *
+ * 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_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), &rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, "type : akcipher\n");
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, &crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = &alg->base;
+
+   base->cra_type = &crypto_akcipher_type;
+   base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+   base->cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+   crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic public key cihper type");
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..11dbd5a 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -110,6 +111,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+
+   if (nla_pu

Re: [BUG?] crypto: caam: little/big endianness on ARM vs PPC

2015-06-16 Thread Steffen Trumtrar
Hi!

On Mon, Jun 15, 2015 at 05:28:16PM +0100, Russell King - ARM Linux wrote:
> On Mon, Jun 15, 2015 at 05:59:07PM +0200, Steffen Trumtrar wrote:
> > I'm working on CAAM support for the ARM-based i.MX6 SoCs. The current
> > drivers/crypto/caam driver only works for PowerPC AFAIK.
> > Actually, there isn't that much to do, to get support for the i.MX6 but
> > one patch breaks the driver severely:
> > 
> > commit ef94b1d834aace7101de77c3a7c2631b9ae9c5f6
> > crypto: caam - Add definition of rd/wr_reg64 for little endian platform
> 
> You're not the only one who's hitting problems with this - Jon Nettleton
> has been working on it recently.
> 
> The way this has been done is fairly yucky to start with: several things
> about it are particularly horrid.  The first is the repetitive code
> for the BE and LE cases, when all that's actually different is the
> register order between the two code cases.
> 
> The second thing is the excessive use of masking - I'm pretty sure the
> compiler won't complain with the below.
> 
> diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
> index 378ddc17f60e..ba0fa630a25d 100644
> --- a/drivers/crypto/caam/regs.h
> +++ b/drivers/crypto/caam/regs.h
> @@ -84,34 +84,28 @@
>  #endif
>  
>  #ifndef CONFIG_64BIT
> -#ifdef __BIG_ENDIAN
> -static inline void wr_reg64(u64 __iomem *reg, u64 data)
> -{
> - wr_reg32((u32 __iomem *)reg, (data & 0xull) >> 32);
> - wr_reg32((u32 __iomem *)reg + 1, data & 0xull);
> -}
> -
> -static inline u64 rd_reg64(u64 __iomem *reg)
> -{
> - return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) |
> - ((u64)rd_reg32((u32 __iomem *)reg + 1));
> -}
> +#if defined(__BIG_ENDIAN)
> +#define REG64_HI32(reg) ((u32 __iomem *)(reg))
> +#define REG64_LO32(reg) ((u32 __iomem *)(reg) + 1)
> +#elif defined(__LITTLE_ENDIAN)
> +#define REG64_HI32(reg) ((u32 __iomem *)(reg) + 1)
> +#define REG64_LO32(reg) ((u32 __iomem *)(reg))
>  #else
> -#ifdef __LITTLE_ENDIAN
> +#error Broken endian?
> +#endif
> +
>  static inline void wr_reg64(u64 __iomem *reg, u64 data)
>  {
> - wr_reg32((u32 __iomem *)reg + 1, (data & 0xull) >> 32);
> - wr_reg32((u32 __iomem *)reg, data & 0xull);
> + wr_reg32(REG64_HI32(reg), data >> 32);
> + wr_reg32(REG64_LO32(reg), data);
>  }
>  
>  static inline u64 rd_reg64(u64 __iomem *reg)
>  {
> - return (((u64)rd_reg32((u32 __iomem *)reg + 1)) << 32) |
> - ((u64)rd_reg32((u32 __iomem *)reg));
> + return ((u64)rd_reg32(REG64_HI32(reg))) << 32 |
> + rd_reg32(REG64_LO32(reg));
>  }
>  #endif
> -#endif
> -#endif
>  
>  /*
>   * jr_outentry
> 
> The second issue is that apparently, the register order doesn't actually
> change for LE devices - in other words, the byte order within each register
> does change, but they aren't a 64-bit register, they're two separate 32-bit
> registers.  So, they should always be written as such.
> 
> So, I'd get rid of the #if defined(__BIG_ENDIAN) stuff and instead have:
> 
> +/*
> + * The DMA address register is a pair of 32-bit registers, and should
> + * always be accessed as such.
> + */
> +#define REG64_HI32(reg) ((u32 __iomem *)(reg))
> +#define REG64_LO32(reg) ((u32 __iomem *)(reg) + 1)
> 

Thanks for all your explanations (in the other mail, too).
I, personally, like this approach the best; at least in the current state
of the driver.

Thanks,
Steffen

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
--
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