Commit 7883d1b2 authored by Jia Jie Ho's avatar Jia Jie Ho Committed by Herbert Xu
Browse files

crypto: starfive - Add hash and HMAC support



Adding hash/HMAC support for SHA-2 and SM3 to StarFive cryptographic
module.

Co-developed-by: default avatarHuan Feng <huan.feng@starfivetech.com>
Signed-off-by: default avatarHuan Feng <huan.feng@starfivetech.com>
Signed-off-by: default avatarJia Jie Ho <jiajie.ho@starfivetech.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 42ef0e94
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -6,6 +6,10 @@ config CRYPTO_DEV_JH7110
	tristate "StarFive JH7110 cryptographic engine driver"
	depends on SOC_STARFIVE || COMPILE_TEST
	select CRYPTO_ENGINE
	select CRYPTO_HMAC
	select CRYPTO_SHA256
	select CRYPTO_SHA512
	select CRYPTO_SM3_GENERIC
	select ARM_AMBA
	select DMADEVICES
	select AMBA_PL08X
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
jh7110-crypto-objs := jh7110-cryp.o
jh7110-crypto-objs := jh7110-cryp.o jh7110-hash.o
+39 −0
Original line number Diff line number Diff line
@@ -79,10 +79,25 @@ static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
	dma_release_channel(cryp->rx);
}

static irqreturn_t starfive_cryp_irq(int irq, void *priv)
{
	u32 status;
	struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)priv;

	status = readl(cryp->base + STARFIVE_IE_FLAG_OFFSET);
	if (status & STARFIVE_IE_FLAG_HASH_DONE) {
		writel(STARFIVE_IE_MASK_HASH_DONE, cryp->base + STARFIVE_IE_MASK_OFFSET);
		tasklet_schedule(&cryp->hash_done);
	}

	return IRQ_HANDLED;
}

static int starfive_cryp_probe(struct platform_device *pdev)
{
	struct starfive_cryp_dev *cryp;
	struct resource *res;
	int irq;
	int ret;

	cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL);
@@ -97,6 +112,8 @@ static int starfive_cryp_probe(struct platform_device *pdev)
		return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base),
				     "Error remapping memory for platform device\n");

	tasklet_init(&cryp->hash_done, starfive_hash_done_task, (unsigned long)cryp);

	cryp->phys_base = res->start;
	cryp->dma_maxburst = 32;

@@ -115,6 +132,16 @@ static int starfive_cryp_probe(struct platform_device *pdev)
		return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
				     "Error getting hardware reset line\n");

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ret = devm_request_irq(&pdev->dev, irq, starfive_cryp_irq, 0, pdev->name,
			       (void *)cryp);
	if (ret)
		return dev_err_probe(&pdev->dev, irq,
				     "Failed to register interrupt handler\n");

	clk_prepare_enable(cryp->hclk);
	clk_prepare_enable(cryp->ahb);
	reset_control_deassert(cryp->rst);
@@ -142,8 +169,14 @@ static int starfive_cryp_probe(struct platform_device *pdev)
	if (ret)
		goto err_engine_start;

	ret = starfive_hash_register_algs();
	if (ret)
		goto err_algs_hash;

	return 0;

err_algs_hash:
	crypto_engine_stop(cryp->engine);
err_engine_start:
	crypto_engine_exit(cryp->engine);
err_engine:
@@ -156,6 +189,8 @@ static int starfive_cryp_probe(struct platform_device *pdev)
	clk_disable_unprepare(cryp->hclk);
	clk_disable_unprepare(cryp->ahb);
	reset_control_assert(cryp->rst);

	tasklet_kill(&cryp->hash_done);
err_probe_defer:
	return ret;
}
@@ -164,6 +199,10 @@ static int starfive_cryp_remove(struct platform_device *pdev)
{
	struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);

	starfive_hash_unregister_algs();

	tasklet_kill(&cryp->hash_done);

	crypto_engine_stop(cryp->engine);
	crypto_engine_exit(cryp->engine);

+67 −3
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#include <linux/dmaengine.h>

#include <crypto/engine.h>
#include <crypto/sha2.h>
#include <crypto/sm3.h>

#define STARFIVE_ALG_CR_OFFSET			0x0
#define STARFIVE_ALG_FIFO_OFFSET		0x4
@@ -15,7 +17,43 @@
#define STARFIVE_DMA_IN_LEN_OFFSET		0x10
#define STARFIVE_DMA_OUT_LEN_OFFSET		0x14

#define STARFIVE_IE_MASK_HASH_DONE		0x4
#define STARFIVE_IE_FLAG_HASH_DONE		0x4

#define STARFIVE_MSG_BUFFER_SIZE		SZ_16K
#define MAX_KEY_SIZE				SHA512_BLOCK_SIZE

union starfive_hash_csr {
	u32 v;
	struct {
		u32 start			:1;
		u32 reset			:1;
		u32 ie				:1;
		u32 firstb			:1;
#define STARFIVE_HASH_SM3			0x0
#define STARFIVE_HASH_SHA224			0x3
#define STARFIVE_HASH_SHA256			0x4
#define STARFIVE_HASH_SHA384			0x5
#define STARFIVE_HASH_SHA512			0x6
#define STARFIVE_HASH_MODE_MASK			0x7
		u32 mode			:3;
		u32 rsvd_1			:1;
		u32 final			:1;
		u32 rsvd_2			:2;
#define STARFIVE_HASH_HMAC_FLAGS		0x800
		u32 hmac			:1;
		u32 rsvd_3			:1;
#define STARFIVE_HASH_KEY_DONE			BIT(13)
		u32 key_done			:1;
		u32 key_flag			:1;
		u32 hmac_done			:1;
#define STARFIVE_HASH_BUSY			BIT(16)
		u32 busy			:1;
		u32 hashdone			:1;
		u32 rsvd_4			:14;
	};
};


union starfive_alg_cr {
	u32 v;
@@ -34,12 +72,18 @@ union starfive_alg_cr {
struct starfive_cryp_ctx {
	struct crypto_engine_ctx		enginectx;
	struct starfive_cryp_dev		*cryp;
	struct starfive_cryp_request_ctx	*rctx;

	unsigned int				hash_mode;
	u8					key[MAX_KEY_SIZE];
	int					keylen;
	bool					is_hmac;
	struct crypto_ahash			*ahash_fbk;
};

struct starfive_cryp_dev {
	struct list_head			list;
	struct device				*dev;

	struct clk				*hclk;
	struct clk				*ahb;
	struct reset_control			*rst;
@@ -52,12 +96,32 @@ struct starfive_cryp_dev {
	struct dma_chan				*rx;
	struct dma_slave_config			cfg_in;
	struct dma_slave_config			cfg_out;

	struct crypto_engine			*engine;

	struct tasklet_struct			hash_done;
	int					err;
	union starfive_alg_cr			alg_cr;
	union {
		struct ahash_request		*hreq;
	} req;
};

struct starfive_cryp_request_ctx {
	union {
		union starfive_hash_csr		hash;
	} csr;

	struct scatterlist			*in_sg;
	struct ahash_request			ahash_fbk_req;
	size_t					total;
	unsigned int				blksize;
	unsigned int				digsize;
	unsigned long				in_sg_len;
};

struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);

int starfive_hash_register_algs(void);
void starfive_hash_unregister_algs(void);

void starfive_hash_done_task(unsigned long param);
#endif
+892 −0

File added.

Preview size limit exceeded, changes collapsed.