[RFC PATCH v6] Crypto: rockchip/crypto - add hash support for crypto engine in rk3288

2016-02-15 Thread Zain Wang
From: Zain Wang 

Add md5 sha1 sha256 support for crypto engine in rk3288.

Signed-off-by: Zain Wang 
---
Changes in V6:
- add software fallback.
- add import/export functions.

Changes in V5:
- fix some mistakes with applying.

Changes in V4:
- remove CRYPTO_ALG_NEED_FALLBACK.

Changes in V3:
- add switch instead of multiple if.

Changes in V2:
- add some comments to code.
- fix some issues about zero message process.

 drivers/crypto/Kconfig |   4 +
 drivers/crypto/rockchip/Makefile   |   1 +
 drivers/crypto/rockchip/rk3288_crypto.c|  28 +-
 drivers/crypto/rockchip/rk3288_crypto.h|  56 ++-
 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c |  20 +-
 drivers/crypto/rockchip/rk3288_crypto_ahash.c  | 404 +
 6 files changed, 499 insertions(+), 14 deletions(-)
 create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ahash.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 3dd69df..e662568 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -506,6 +506,10 @@ config CRYPTO_DEV_ROCKCHIP
depends on OF && ARCH_ROCKCHIP
select CRYPTO_AES
select CRYPTO_DES
+   select CRYPTO_MD5
+   select CRYPTO_SHA1
+   select CRYPTO_SHA256
+   select CRYPTO_HASH
select CRYPTO_BLKCIPHER
 
help
diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile
index 7051c6c..30f9129 100644
--- a/drivers/crypto/rockchip/Makefile
+++ b/drivers/crypto/rockchip/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o
 rk_crypto-objs := rk3288_crypto.o \
  rk3288_crypto_ablkcipher.o \
+ rk3288_crypto_ahash.o
diff --git a/drivers/crypto/rockchip/rk3288_crypto.c 
b/drivers/crypto/rockchip/rk3288_crypto.c
index da9c73d..af50825 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -208,6 +208,8 @@ static void rk_crypto_tasklet_cb(unsigned long data)
 
if (crypto_tfm_alg_type(async_req->tfm) == CRYPTO_ALG_TYPE_ABLKCIPHER)
dev->ablk_req = ablkcipher_request_cast(async_req);
+   else
+   dev->ahash_req = ahash_request_cast(async_req);
err = dev->start(dev);
if (err)
dev->complete(dev, err);
@@ -220,6 +222,9 @@ static struct rk_crypto_tmp *rk_cipher_algs[] = {
_cbc_des_alg,
_ecb_des3_ede_alg,
_cbc_des3_ede_alg,
+   _ahash_sha1,
+   _ahash_sha256,
+   _ahash_md5,
 };
 
 static int rk_crypto_register(struct rk_crypto_info *crypto_info)
@@ -229,15 +234,24 @@ static int rk_crypto_register(struct rk_crypto_info 
*crypto_info)
 
for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
rk_cipher_algs[i]->dev = crypto_info;
-   err = crypto_register_alg(_cipher_algs[i]->alg);
+   if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+   err = crypto_register_alg(
+   _cipher_algs[i]->alg.crypto);
+   else
+   err = crypto_register_ahash(
+   _cipher_algs[i]->alg.hash);
if (err)
goto err_cipher_algs;
}
return 0;
 
 err_cipher_algs:
-   for (k = 0; k < i; k++)
-   crypto_unregister_alg(_cipher_algs[k]->alg);
+   for (k = 0; k < i; k++) {
+   if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+   crypto_unregister_alg(_cipher_algs[k]->alg.crypto);
+   else
+   crypto_unregister_ahash(_cipher_algs[i]->alg.hash);
+   }
return err;
 }
 
@@ -245,8 +259,12 @@ static void rk_crypto_unregister(void)
 {
unsigned int i;
 
-   for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++)
-   crypto_unregister_alg(_cipher_algs[i]->alg);
+   for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
+   if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+   crypto_unregister_alg(_cipher_algs[i]->alg.crypto);
+   else
+   crypto_unregister_ahash(_cipher_algs[i]->alg.hash);
+   }
 }
 
 static void rk_crypto_action(void *data)
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h 
b/drivers/crypto/rockchip/rk3288_crypto.h
index e499c2c..d7b71fe 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -6,6 +6,10 @@
 #include 
 #include 
 #include 
+#include 
+
+#include 
+#include 
 
 #define _SBF(v, f) ((v) << (f))
 
@@ -149,6 +153,28 @@
 #define RK_CRYPTO_TDES_KEY3_0  0x0130
 #define RK_CRYPTO_TDES_KEY3_1  0x0134
 
+/* HASH */
+#define RK_CRYPTO_HASH_CTRL0x0180
+#define RK_CRYPTO_HASH_SWAP_DO BIT(3)
+#define RK_CRYPTO_HASH_SWAP_DI BIT(2)

Re: [PATCH] arm/arm64/crypto: assure that ECB modes don't require an IV

2016-02-15 Thread Will Deacon
On Fri, Feb 12, 2016 at 06:00:01PM +0100, Ard Biesheuvel wrote:
> On 12 February 2016 at 16:47, Jeremy Linton  wrote:
> > ECB modes don't use an initialization vector. The kernel
> > /proc/crypto interface doesn't reflect this properly.
> >
> > Signed-off-by: Jeremy Linton 
> 
> Thanks for spotting that!
> 
> Acked-by: Ard Biesheuvel 

Thanks, I'll queue this for -rc5.

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


Re: [PATCH] crypto: implement DH primitives under akcipher API

2016-02-15 Thread Stephan Mueller
Am Montag, 15. Februar 2016, 09:01:55 schrieb Salvatore Benedetto:

Hi Salvatore, Herbert,

> Implement Diffie-Hellman primitives required by the scheme under the
> akcipher API. Here is how it works.
> 1) Call set_pub_key() by passing DH parameters (p,g) in PKCS3 format
> 2) Call set_priv_key() to set your own private key (xa) in raw format
> 3) Call decrypt() without passing any data as input to get back the
>public part which will be computed as g^xa mod p
> 4) Call encrypt() by passing the counter part public key (yb) in raw format
>as input to get back the shared secret calculated as zz = yb^xa mod p
> 
> A test is included in the patch. Test vector has been generated with
> openssl

Herbert, as this is a raw DH operation where the shared secret must be 
subjected to a KDF, I guess the KDF patch I provided some time ago may become 
of interest again?
> 
> Signed-off-by: Salvatore Benedetto 
> ---
>  crypto/Kconfig|   8 ++
>  crypto/Makefile   |   7 ++
>  crypto/dh.c   | 264
> ++ crypto/pkcs3.asn1 | 
>  5 ++
>  crypto/tcrypt.c   |   4 +
>  crypto/testmgr.c  | 140 +++--
>  crypto/testmgr.h  | 208 +-
>  7 files changed, 627 insertions(+), 9 deletions(-)
>  create mode 100644 crypto/dh.c
>  create mode 100644 crypto/pkcs3.asn1
> 
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index f6bfdda..fd5b78d 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -101,6 +101,14 @@ config CRYPTO_RSA
>   help
> Generic implementation of the RSA public key algorithm.
> 
> +config CRYPTO_DH
> + tristate "Diffie-Hellman algorithm"
> + select CRYPTO_AKCIPHER
> + select MPILIB
> + select ASN1
> + help
> +   Generic implementation of the Diffie-Hellman algorithm.
> +
>  config CRYPTO_MANAGER
>   tristate "Cryptographic algorithm manager"
>   select CRYPTO_MANAGER2
> diff --git a/crypto/Makefile b/crypto/Makefile
> index 4f4ef7e..ee73489 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -31,6 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
> 
>  obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
> 
> +$(obj)/pkcs3-asn1.o: $(obj)/pkcs3-asn1.c $(obj)/pkcs3-asn1.h
> +clean-files += pkcs3-asn1.c pkcs3-asn1.h
> +
> +dh_generic-y := pkcs3-asn1.o
> +dh_generic-y += dh.o
> +obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
> +
>  $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
>  $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
> clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
> diff --git a/crypto/dh.c b/crypto/dh.c
> new file mode 100644
> index 000..614c4f1
> --- /dev/null
> +++ b/crypto/dh.c
> @@ -0,0 +1,264 @@
> +/*  Diffie-Hellman Key Agreement Method [RFC2631]
> + *
> + * Copyright (c) 2016, Intel Corporation
> + * Authors: Salvatore Benedetto 
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public Licence
> + * as published by the Free Software Foundation; either version
> + * 2 of the Licence, or (at your option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "pkcs3-asn1.h"
> +
> +struct dh_params {
> + MPI p;
> + MPI g;
> + MPI xa;
> +};
> +
> +int dh_get_g(void *context, size_t hdrlen, unsigned char tag, const void
> *value, +  size_t vlen)
> +{
> + struct dh_params *params = context;
> +
> + params->g = mpi_read_raw_data(value, vlen);
> +
> + if (!params->g)
> + return -ENOMEM;
> +
> + return 0;
> +}
> +
> +int dh_get_p(void *context, size_t hdrlen, unsigned char tag, const void
> *value, +  size_t vlen)
> +{
> + struct dh_params *params = context;
> +
> + params->p = mpi_read_raw_data(value, vlen);
> +
> + if (!params->p)
> + return -ENOMEM;
> +
> + return 0;
> +}
> +
> +static int dh_parse_params(struct dh_params *params, const void *key,
> +unsigned int keylen)
> +{
> + int ret;
> +
> + mpi_free(params->p);
> + mpi_free(params->g);
> +
> + ret = asn1_ber_decoder(_decoder, params, key, keylen);
> +
> + return ret;
> +}
> +
> +static void dh_free_params(struct dh_params *params)
> +{
> + mpi_free(params->p);
> + mpi_free(params->g);
> + mpi_free(params->xa);
> + params->p = NULL;
> + params->g = NULL;
> + params->xa = NULL;
> +}
> +
> +/*
> + * Public key generation function [RFC2631 sec 2.1.1]
> + * ya = g^xa mod p;
> + */
> +static int _generate_public_key(const struct dh_params *params, MPI ya)
> +{
> + /* ya = g^xa mod p */
> + return mpi_powm(ya, params->g, params->xa, params->p);
> +}
> +
> +/*
> + * ZZ generation function [RFC2631 sec 2.1.1]
> + * ZZ = yb^xa mod p;
> + */
> +static int _compute_shared_secret(const struct