mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
crypto: starfive - Add AES skcipher and aead support
Adding AES skcipher and aead support to Starfive crypto module. Skcipher modes of operation include ecb, cbc, ctr, ofb, cfb. Aead modes include ccm and gcm. v1->v2: - Add include interrupt.h to fix compile error. (Herbert) Co-developed-by: Huan Feng <huan.feng@starfivetech.com> Signed-off-by: Huan Feng <huan.feng@starfivetech.com> Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
dd105461ad
commit
e22471c233
@ -12,6 +12,8 @@ config CRYPTO_DEV_JH7110
|
||||
select CRYPTO_SHA512
|
||||
select CRYPTO_SM3_GENERIC
|
||||
select CRYPTO_RSA
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CCM
|
||||
help
|
||||
Support for StarFive JH7110 crypto hardware acceleration engine.
|
||||
This module provides acceleration for public key algo,
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
|
||||
jh7110-crypto-objs := jh7110-cryp.o jh7110-hash.o jh7110-rsa.o
|
||||
jh7110-crypto-objs := jh7110-cryp.o jh7110-hash.o jh7110-rsa.o jh7110-aes.o
|
||||
|
1034
drivers/crypto/starfive/jh7110-aes.c
Normal file
1034
drivers/crypto/starfive/jh7110-aes.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -51,6 +51,13 @@ struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx)
|
||||
return cryp;
|
||||
}
|
||||
|
||||
static u16 side_chan;
|
||||
module_param(side_chan, ushort, 0);
|
||||
MODULE_PARM_DESC(side_chan, "Enable side channel mitigation for AES module.\n"
|
||||
"Enabling this feature will reduce speed performance.\n"
|
||||
" 0 - Disabled\n"
|
||||
" other - Enabled");
|
||||
|
||||
static int starfive_dma_init(struct starfive_cryp_dev *cryp)
|
||||
{
|
||||
dma_cap_mask_t mask;
|
||||
@ -82,20 +89,26 @@ static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
|
||||
static irqreturn_t starfive_cryp_irq(int irq, void *priv)
|
||||
{
|
||||
u32 status;
|
||||
u32 mask;
|
||||
struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)priv;
|
||||
|
||||
mask = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
status = readl(cryp->base + STARFIVE_IE_FLAG_OFFSET);
|
||||
if (status & STARFIVE_IE_FLAG_AES_DONE) {
|
||||
mask |= STARFIVE_IE_MASK_AES_DONE;
|
||||
writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
tasklet_schedule(&cryp->aes_done);
|
||||
}
|
||||
|
||||
if (status & STARFIVE_IE_FLAG_HASH_DONE) {
|
||||
status = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
status |= STARFIVE_IE_MASK_HASH_DONE;
|
||||
writel(status, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
mask |= STARFIVE_IE_MASK_HASH_DONE;
|
||||
writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
tasklet_schedule(&cryp->hash_done);
|
||||
}
|
||||
|
||||
if (status & STARFIVE_IE_FLAG_PKA_DONE) {
|
||||
status = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
status |= STARFIVE_IE_MASK_PKA_DONE;
|
||||
writel(status, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
mask |= STARFIVE_IE_MASK_PKA_DONE;
|
||||
writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
complete(&cryp->pka_done);
|
||||
}
|
||||
|
||||
@ -121,10 +134,12 @@ 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->aes_done, starfive_aes_done_task, (unsigned long)cryp);
|
||||
tasklet_init(&cryp->hash_done, starfive_hash_done_task, (unsigned long)cryp);
|
||||
|
||||
cryp->phys_base = res->start;
|
||||
cryp->dma_maxburst = 32;
|
||||
cryp->side_chan = side_chan;
|
||||
|
||||
cryp->hclk = devm_clk_get(&pdev->dev, "hclk");
|
||||
if (IS_ERR(cryp->hclk))
|
||||
@ -180,6 +195,10 @@ static int starfive_cryp_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_engine_start;
|
||||
|
||||
ret = starfive_aes_register_algs();
|
||||
if (ret)
|
||||
goto err_algs_aes;
|
||||
|
||||
ret = starfive_hash_register_algs();
|
||||
if (ret)
|
||||
goto err_algs_hash;
|
||||
@ -193,6 +212,8 @@ static int starfive_cryp_probe(struct platform_device *pdev)
|
||||
err_algs_rsa:
|
||||
starfive_hash_unregister_algs();
|
||||
err_algs_hash:
|
||||
starfive_aes_unregister_algs();
|
||||
err_algs_aes:
|
||||
crypto_engine_stop(cryp->engine);
|
||||
err_engine_start:
|
||||
crypto_engine_exit(cryp->engine);
|
||||
@ -207,6 +228,7 @@ err_dma_init:
|
||||
clk_disable_unprepare(cryp->ahb);
|
||||
reset_control_assert(cryp->rst);
|
||||
|
||||
tasklet_kill(&cryp->aes_done);
|
||||
tasklet_kill(&cryp->hash_done);
|
||||
err_probe_defer:
|
||||
return ret;
|
||||
@ -216,9 +238,11 @@ static void starfive_cryp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
|
||||
|
||||
starfive_aes_unregister_algs();
|
||||
starfive_hash_unregister_algs();
|
||||
starfive_rsa_unregister_algs();
|
||||
|
||||
tasklet_kill(&cryp->aes_done);
|
||||
tasklet_kill(&cryp->hash_done);
|
||||
|
||||
crypto_engine_stop(cryp->engine);
|
||||
|
@ -5,7 +5,9 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/engine.h>
|
||||
#include <crypto/sha2.h>
|
||||
#include <crypto/sm3.h>
|
||||
@ -17,13 +19,56 @@
|
||||
#define STARFIVE_DMA_IN_LEN_OFFSET 0x10
|
||||
#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
|
||||
|
||||
#define STARFIVE_IE_MASK_AES_DONE 0x1
|
||||
#define STARFIVE_IE_MASK_HASH_DONE 0x4
|
||||
#define STARFIVE_IE_MASK_PKA_DONE 0x8
|
||||
#define STARFIVE_IE_FLAG_AES_DONE 0x1
|
||||
#define STARFIVE_IE_FLAG_HASH_DONE 0x4
|
||||
#define STARFIVE_IE_FLAG_PKA_DONE 0x8
|
||||
|
||||
#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
|
||||
#define MAX_KEY_SIZE SHA512_BLOCK_SIZE
|
||||
#define STARFIVE_AES_IV_LEN AES_BLOCK_SIZE
|
||||
#define STARFIVE_AES_CTR_LEN AES_BLOCK_SIZE
|
||||
|
||||
union starfive_aes_csr {
|
||||
u32 v;
|
||||
struct {
|
||||
u32 cmode :1;
|
||||
#define STARFIVE_AES_KEYMODE_128 0x0
|
||||
#define STARFIVE_AES_KEYMODE_192 0x1
|
||||
#define STARFIVE_AES_KEYMODE_256 0x2
|
||||
u32 keymode :2;
|
||||
#define STARFIVE_AES_BUSY BIT(3)
|
||||
u32 busy :1;
|
||||
u32 done :1;
|
||||
#define STARFIVE_AES_KEY_DONE BIT(5)
|
||||
u32 krdy :1;
|
||||
u32 aesrst :1;
|
||||
u32 ie :1;
|
||||
#define STARFIVE_AES_CCM_START BIT(8)
|
||||
u32 ccm_start :1;
|
||||
#define STARFIVE_AES_MODE_ECB 0x0
|
||||
#define STARFIVE_AES_MODE_CBC 0x1
|
||||
#define STARFIVE_AES_MODE_CFB 0x2
|
||||
#define STARFIVE_AES_MODE_OFB 0x3
|
||||
#define STARFIVE_AES_MODE_CTR 0x4
|
||||
#define STARFIVE_AES_MODE_CCM 0x5
|
||||
#define STARFIVE_AES_MODE_GCM 0x6
|
||||
u32 mode :3;
|
||||
#define STARFIVE_AES_GCM_START BIT(12)
|
||||
u32 gcm_start :1;
|
||||
#define STARFIVE_AES_GCM_DONE BIT(13)
|
||||
u32 gcm_done :1;
|
||||
u32 delay_aes :1;
|
||||
u32 vaes_start :1;
|
||||
u32 rsvd_0 :8;
|
||||
#define STARFIVE_AES_MODE_XFB_1 0x0
|
||||
#define STARFIVE_AES_MODE_XFB_128 0x5
|
||||
u32 stmode :3;
|
||||
u32 rsvd_1 :5;
|
||||
};
|
||||
};
|
||||
|
||||
union starfive_hash_csr {
|
||||
u32 v;
|
||||
@ -116,6 +161,7 @@ struct starfive_cryp_ctx {
|
||||
struct starfive_rsa_key rsa_key;
|
||||
struct crypto_akcipher *akcipher_fbk;
|
||||
struct crypto_ahash *ahash_fbk;
|
||||
struct crypto_aead *aead_fbk;
|
||||
};
|
||||
|
||||
struct starfive_cryp_dev {
|
||||
@ -133,13 +179,26 @@ struct starfive_cryp_dev {
|
||||
struct dma_chan *rx;
|
||||
struct dma_slave_config cfg_in;
|
||||
struct dma_slave_config cfg_out;
|
||||
struct scatter_walk in_walk;
|
||||
struct scatter_walk out_walk;
|
||||
struct crypto_engine *engine;
|
||||
struct tasklet_struct aes_done;
|
||||
struct tasklet_struct hash_done;
|
||||
struct completion pka_done;
|
||||
size_t assoclen;
|
||||
size_t total_in;
|
||||
size_t total_out;
|
||||
u32 tag_in[4];
|
||||
u32 tag_out[4];
|
||||
unsigned int authsize;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
bool side_chan;
|
||||
union starfive_alg_cr alg_cr;
|
||||
union {
|
||||
struct ahash_request *hreq;
|
||||
struct aead_request *areq;
|
||||
struct skcipher_request *sreq;
|
||||
} req;
|
||||
};
|
||||
|
||||
@ -147,6 +206,7 @@ struct starfive_cryp_request_ctx {
|
||||
union {
|
||||
union starfive_hash_csr hash;
|
||||
union starfive_pka_cacr pka;
|
||||
union starfive_aes_csr aes;
|
||||
} csr;
|
||||
|
||||
struct scatterlist *in_sg;
|
||||
@ -157,6 +217,7 @@ struct starfive_cryp_request_ctx {
|
||||
unsigned int blksize;
|
||||
unsigned int digsize;
|
||||
unsigned long in_sg_len;
|
||||
unsigned char *adata;
|
||||
u8 rsa_data[] __aligned(sizeof(u32));
|
||||
};
|
||||
|
||||
@ -168,5 +229,9 @@ void starfive_hash_unregister_algs(void);
|
||||
int starfive_rsa_register_algs(void);
|
||||
void starfive_rsa_unregister_algs(void);
|
||||
|
||||
int starfive_aes_register_algs(void);
|
||||
void starfive_aes_unregister_algs(void);
|
||||
|
||||
void starfive_hash_done_task(unsigned long param);
|
||||
void starfive_aes_done_task(unsigned long param);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user