Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfd927ff authored by Zain Wang's avatar Zain Wang Committed by Herbert Xu
Browse files

crypto: rockchip - add hash support for crypto engine in rk3288



Add md5 sha1 sha256 support for crypto engine in rk3288.

Signed-off-by: default avatarZain Wang <zain.wang@rock-chips.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 49abc0d2
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -508,6 +508,10 @@ config CRYPTO_DEV_ROCKCHIP
	depends on OF && ARCH_ROCKCHIP
	depends on OF && ARCH_ROCKCHIP
	select CRYPTO_AES
	select CRYPTO_AES
	select CRYPTO_DES
	select CRYPTO_DES
	select CRYPTO_MD5
	select CRYPTO_SHA1
	select CRYPTO_SHA256
	select CRYPTO_HASH
	select CRYPTO_BLKCIPHER
	select CRYPTO_BLKCIPHER


	help
	help
+1 −0
Original line number Original line Diff line number Diff line
obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o
obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o
rk_crypto-objs := rk3288_crypto.o \
rk_crypto-objs := rk3288_crypto.o \
		  rk3288_crypto_ablkcipher.o \
		  rk3288_crypto_ablkcipher.o \
		  rk3288_crypto_ahash.o
+23 −5
Original line number Original line Diff line number Diff line
@@ -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)
	if (crypto_tfm_alg_type(async_req->tfm) == CRYPTO_ALG_TYPE_ABLKCIPHER)
		dev->ablk_req = ablkcipher_request_cast(async_req);
		dev->ablk_req = ablkcipher_request_cast(async_req);
	else
		dev->ahash_req = ahash_request_cast(async_req);
	err = dev->start(dev);
	err = dev->start(dev);
	if (err)
	if (err)
		dev->complete(dev, err);
		dev->complete(dev, err);
@@ -220,6 +222,9 @@ static struct rk_crypto_tmp *rk_cipher_algs[] = {
	&rk_cbc_des_alg,
	&rk_cbc_des_alg,
	&rk_ecb_des3_ede_alg,
	&rk_ecb_des3_ede_alg,
	&rk_cbc_des3_ede_alg,
	&rk_cbc_des3_ede_alg,
	&rk_ahash_sha1,
	&rk_ahash_sha256,
	&rk_ahash_md5,
};
};


static int rk_crypto_register(struct rk_crypto_info *crypto_info)
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++) {
	for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
		rk_cipher_algs[i]->dev = crypto_info;
		rk_cipher_algs[i]->dev = crypto_info;
		err = crypto_register_alg(&rk_cipher_algs[i]->alg);
		if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
			err = crypto_register_alg(
					&rk_cipher_algs[i]->alg.crypto);
		else
			err = crypto_register_ahash(
					&rk_cipher_algs[i]->alg.hash);
		if (err)
		if (err)
			goto err_cipher_algs;
			goto err_cipher_algs;
	}
	}
	return 0;
	return 0;


err_cipher_algs:
err_cipher_algs:
	for (k = 0; k < i; k++)
	for (k = 0; k < i; k++) {
		crypto_unregister_alg(&rk_cipher_algs[k]->alg);
		if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
			crypto_unregister_alg(&rk_cipher_algs[k]->alg.crypto);
		else
			crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
	}
	return err;
	return err;
}
}


@@ -245,8 +259,12 @@ static void rk_crypto_unregister(void)
{
{
	unsigned int i;
	unsigned int i;


	for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++)
	for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
		crypto_unregister_alg(&rk_cipher_algs[i]->alg);
		if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
			crypto_unregister_alg(&rk_cipher_algs[i]->alg.crypto);
		else
			crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
	}
}
}


static void rk_crypto_action(void *data)
static void rk_crypto_action(void *data)
+54 −2
Original line number Original line Diff line number Diff line
@@ -6,6 +6,10 @@
#include <crypto/algapi.h>
#include <crypto/algapi.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <crypto/internal/hash.h>

#include <crypto/md5.h>
#include <crypto/sha.h>


#define _SBF(v, f)			((v) << (f))
#define _SBF(v, f)			((v) << (f))


@@ -149,6 +153,28 @@
#define RK_CRYPTO_TDES_KEY3_0		0x0130
#define RK_CRYPTO_TDES_KEY3_0		0x0130
#define RK_CRYPTO_TDES_KEY3_1		0x0134
#define RK_CRYPTO_TDES_KEY3_1		0x0134


/* HASH */
#define RK_CRYPTO_HASH_CTRL		0x0180
#define RK_CRYPTO_HASH_SWAP_DO		BIT(3)
#define RK_CRYPTO_HASH_SWAP_DI		BIT(2)
#define RK_CRYPTO_HASH_SHA1		_SBF(0x00, 0)
#define RK_CRYPTO_HASH_MD5		_SBF(0x01, 0)
#define RK_CRYPTO_HASH_SHA256		_SBF(0x02, 0)
#define RK_CRYPTO_HASH_PRNG		_SBF(0x03, 0)

#define RK_CRYPTO_HASH_STS		0x0184
#define RK_CRYPTO_HASH_DONE		BIT(0)

#define RK_CRYPTO_HASH_MSG_LEN		0x0188
#define RK_CRYPTO_HASH_DOUT_0		0x018c
#define RK_CRYPTO_HASH_DOUT_1		0x0190
#define RK_CRYPTO_HASH_DOUT_2		0x0194
#define RK_CRYPTO_HASH_DOUT_3		0x0198
#define RK_CRYPTO_HASH_DOUT_4		0x019c
#define RK_CRYPTO_HASH_DOUT_5		0x01a0
#define RK_CRYPTO_HASH_DOUT_6		0x01a4
#define RK_CRYPTO_HASH_DOUT_7		0x01a8

#define CRYPTO_READ(dev, offset)		  \
#define CRYPTO_READ(dev, offset)		  \
		readl_relaxed(((dev)->reg + (offset)))
		readl_relaxed(((dev)->reg + (offset)))
#define CRYPTO_WRITE(dev, offset, val)	  \
#define CRYPTO_WRITE(dev, offset, val)	  \
@@ -166,6 +192,7 @@ struct rk_crypto_info {
	struct crypto_queue		queue;
	struct crypto_queue		queue;
	struct tasklet_struct		crypto_tasklet;
	struct tasklet_struct		crypto_tasklet;
	struct ablkcipher_request	*ablk_req;
	struct ablkcipher_request	*ablk_req;
	struct ahash_request		*ahash_req;
	/* device lock */
	/* device lock */
	spinlock_t			lock;
	spinlock_t			lock;


@@ -195,15 +222,36 @@ struct rk_crypto_info {
	void (*unload_data)(struct rk_crypto_info *dev);
	void (*unload_data)(struct rk_crypto_info *dev);
};
};


/* the private variable of hash */
struct rk_ahash_ctx {
	struct rk_crypto_info		*dev;
	/* for fallback */
	struct crypto_ahash		*fallback_tfm;
};

/* the privete variable of hash for fallback */
struct rk_ahash_rctx {
	struct ahash_request		fallback_req;
};

/* the private variable of cipher */
/* the private variable of cipher */
struct rk_cipher_ctx {
struct rk_cipher_ctx {
	struct rk_crypto_info		*dev;
	struct rk_crypto_info		*dev;
	unsigned int			keylen;
	unsigned int			keylen;
};
};


enum alg_type {
	ALG_TYPE_HASH,
	ALG_TYPE_CIPHER,
};

struct rk_crypto_tmp {
struct rk_crypto_tmp {
	struct rk_crypto_info		*dev;
	struct rk_crypto_info		*dev;
	struct crypto_alg alg;
	union {
		struct crypto_alg	crypto;
		struct ahash_alg	hash;
	} alg;
	enum alg_type			type;
};
};


extern struct rk_crypto_tmp rk_ecb_aes_alg;
extern struct rk_crypto_tmp rk_ecb_aes_alg;
@@ -213,4 +261,8 @@ extern struct rk_crypto_tmp rk_cbc_des_alg;
extern struct rk_crypto_tmp rk_ecb_des3_ede_alg;
extern struct rk_crypto_tmp rk_ecb_des3_ede_alg;
extern struct rk_crypto_tmp rk_cbc_des3_ede_alg;
extern struct rk_crypto_tmp rk_cbc_des3_ede_alg;


extern struct rk_crypto_tmp rk_ahash_sha1;
extern struct rk_crypto_tmp rk_ahash_sha256;
extern struct rk_crypto_tmp rk_ahash_md5;

#endif
#endif
+13 −7
Original line number Original line Diff line number Diff line
@@ -336,7 +336,7 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm)
	struct crypto_alg *alg = tfm->__crt_alg;
	struct crypto_alg *alg = tfm->__crt_alg;
	struct rk_crypto_tmp *algt;
	struct rk_crypto_tmp *algt;


	algt = container_of(alg, struct rk_crypto_tmp, alg);
	algt = container_of(alg, struct rk_crypto_tmp, alg.crypto);


	ctx->dev = algt->dev;
	ctx->dev = algt->dev;
	ctx->dev->align_size = crypto_tfm_alg_alignmask(tfm) + 1;
	ctx->dev->align_size = crypto_tfm_alg_alignmask(tfm) + 1;
@@ -357,7 +357,8 @@ static void rk_ablk_cra_exit(struct crypto_tfm *tfm)
}
}


struct rk_crypto_tmp rk_ecb_aes_alg = {
struct rk_crypto_tmp rk_ecb_aes_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "ecb(aes)",
		.cra_name		= "ecb(aes)",
		.cra_driver_name	= "ecb-aes-rk",
		.cra_driver_name	= "ecb-aes-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
@@ -381,7 +382,8 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
};
};


struct rk_crypto_tmp rk_cbc_aes_alg = {
struct rk_crypto_tmp rk_cbc_aes_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "cbc(aes)",
		.cra_name		= "cbc(aes)",
		.cra_driver_name	= "cbc-aes-rk",
		.cra_driver_name	= "cbc-aes-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
@@ -406,7 +408,8 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
};
};


struct rk_crypto_tmp rk_ecb_des_alg = {
struct rk_crypto_tmp rk_ecb_des_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "ecb(des)",
		.cra_name		= "ecb(des)",
		.cra_driver_name	= "ecb-des-rk",
		.cra_driver_name	= "ecb-des-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
@@ -430,7 +433,8 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
};
};


struct rk_crypto_tmp rk_cbc_des_alg = {
struct rk_crypto_tmp rk_cbc_des_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "cbc(des)",
		.cra_name		= "cbc(des)",
		.cra_driver_name	= "cbc-des-rk",
		.cra_driver_name	= "cbc-des-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
@@ -455,7 +459,8 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
};
};


struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "ecb(des3_ede)",
		.cra_name		= "ecb(des3_ede)",
		.cra_driver_name	= "ecb-des3-ede-rk",
		.cra_driver_name	= "ecb-des3-ede-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
@@ -480,7 +485,8 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
};
};


struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
	.alg = {
	.type = ALG_TYPE_CIPHER,
	.alg.crypto = {
		.cra_name		= "cbc(des3_ede)",
		.cra_name		= "cbc(des3_ede)",
		.cra_driver_name	= "cbc-des3-ede-rk",
		.cra_driver_name	= "cbc-des3-ede-rk",
		.cra_priority		= 300,
		.cra_priority		= 300,
Loading