Commit 445a4aaf authored by Jia Jie Ho's avatar Jia Jie Ho Committed by Herbert Xu

crypto: starfive - Add RSA algo support

Adding RSA enc/dec and sign/verify feature for StarFive cryptographic
module. The module only supports mod sizes up to 2048, therefore
calculations more than that will use fallback algo.
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 df12284a
...@@ -11,6 +11,7 @@ config CRYPTO_DEV_JH7110 ...@@ -11,6 +11,7 @@ config CRYPTO_DEV_JH7110
select CRYPTO_SHA256 select CRYPTO_SHA256
select CRYPTO_SHA512 select CRYPTO_SHA512
select CRYPTO_SM3_GENERIC select CRYPTO_SM3_GENERIC
select CRYPTO_RSA
help help
Support for StarFive JH7110 crypto hardware acceleration engine. Support for StarFive JH7110 crypto hardware acceleration engine.
This module provides acceleration for public key algo, This module provides acceleration for public key algo,
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
jh7110-crypto-objs := jh7110-cryp.o jh7110-hash.o jh7110-crypto-objs := jh7110-cryp.o jh7110-hash.o jh7110-rsa.o
...@@ -86,10 +86,19 @@ static irqreturn_t starfive_cryp_irq(int irq, void *priv) ...@@ -86,10 +86,19 @@ static irqreturn_t starfive_cryp_irq(int irq, void *priv)
status = readl(cryp->base + STARFIVE_IE_FLAG_OFFSET); status = readl(cryp->base + STARFIVE_IE_FLAG_OFFSET);
if (status & STARFIVE_IE_FLAG_HASH_DONE) { if (status & STARFIVE_IE_FLAG_HASH_DONE) {
writel(STARFIVE_IE_MASK_HASH_DONE, cryp->base + STARFIVE_IE_MASK_OFFSET); status = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
status |= STARFIVE_IE_MASK_HASH_DONE;
writel(status, cryp->base + STARFIVE_IE_MASK_OFFSET);
tasklet_schedule(&cryp->hash_done); 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);
complete(&cryp->pka_done);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -132,6 +141,8 @@ static int starfive_cryp_probe(struct platform_device *pdev) ...@@ -132,6 +141,8 @@ static int starfive_cryp_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst), return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
"Error getting hardware reset line\n"); "Error getting hardware reset line\n");
init_completion(&cryp->pka_done);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
...@@ -173,8 +184,14 @@ static int starfive_cryp_probe(struct platform_device *pdev) ...@@ -173,8 +184,14 @@ static int starfive_cryp_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_algs_hash; goto err_algs_hash;
ret = starfive_rsa_register_algs();
if (ret)
goto err_algs_rsa;
return 0; return 0;
err_algs_rsa:
starfive_hash_unregister_algs();
err_algs_hash: err_algs_hash:
crypto_engine_stop(cryp->engine); crypto_engine_stop(cryp->engine);
err_engine_start: err_engine_start:
...@@ -200,6 +217,7 @@ static int starfive_cryp_remove(struct platform_device *pdev) ...@@ -200,6 +217,7 @@ static int starfive_cryp_remove(struct platform_device *pdev)
struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev); struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
starfive_hash_unregister_algs(); starfive_hash_unregister_algs();
starfive_rsa_unregister_algs();
tasklet_kill(&cryp->hash_done); tasklet_kill(&cryp->hash_done);
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14 #define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
#define STARFIVE_IE_MASK_HASH_DONE 0x4 #define STARFIVE_IE_MASK_HASH_DONE 0x4
#define STARFIVE_IE_MASK_PKA_DONE 0x8
#define STARFIVE_IE_FLAG_HASH_DONE 0x4 #define STARFIVE_IE_FLAG_HASH_DONE 0x4
#define STARFIVE_IE_FLAG_PKA_DONE 0x8
#define STARFIVE_MSG_BUFFER_SIZE SZ_16K #define STARFIVE_MSG_BUFFER_SIZE SZ_16K
#define MAX_KEY_SIZE SHA512_BLOCK_SIZE #define MAX_KEY_SIZE SHA512_BLOCK_SIZE
...@@ -54,6 +56,39 @@ union starfive_hash_csr { ...@@ -54,6 +56,39 @@ union starfive_hash_csr {
}; };
}; };
union starfive_pka_cacr {
u32 v;
struct {
u32 start :1;
u32 reset :1;
u32 ie :1;
u32 rsvd_0 :1;
u32 fifo_mode :1;
u32 not_r2 :1;
u32 ecc_sub :1;
u32 pre_expf :1;
u32 cmd :4;
u32 rsvd_1 :1;
u32 ctrl_dummy :1;
u32 ctrl_false :1;
u32 cln_done :1;
u32 opsize :6;
u32 rsvd_2 :2;
u32 exposize :6;
u32 rsvd_3 :1;
u32 bigendian :1;
};
};
struct starfive_rsa_key {
u8 *n;
u8 *e;
u8 *d;
int e_bitlen;
int d_bitlen;
int bitlen;
size_t key_sz;
};
union starfive_alg_cr { union starfive_alg_cr {
u32 v; u32 v;
...@@ -78,6 +113,8 @@ struct starfive_cryp_ctx { ...@@ -78,6 +113,8 @@ struct starfive_cryp_ctx {
u8 key[MAX_KEY_SIZE]; u8 key[MAX_KEY_SIZE];
int keylen; int keylen;
bool is_hmac; bool is_hmac;
struct starfive_rsa_key rsa_key;
struct crypto_akcipher *akcipher_fbk;
struct crypto_ahash *ahash_fbk; struct crypto_ahash *ahash_fbk;
}; };
...@@ -98,6 +135,7 @@ struct starfive_cryp_dev { ...@@ -98,6 +135,7 @@ struct starfive_cryp_dev {
struct dma_slave_config cfg_out; struct dma_slave_config cfg_out;
struct crypto_engine *engine; struct crypto_engine *engine;
struct tasklet_struct hash_done; struct tasklet_struct hash_done;
struct completion pka_done;
int err; int err;
union starfive_alg_cr alg_cr; union starfive_alg_cr alg_cr;
union { union {
...@@ -108,14 +146,18 @@ struct starfive_cryp_dev { ...@@ -108,14 +146,18 @@ struct starfive_cryp_dev {
struct starfive_cryp_request_ctx { struct starfive_cryp_request_ctx {
union { union {
union starfive_hash_csr hash; union starfive_hash_csr hash;
union starfive_pka_cacr pka;
} csr; } csr;
struct scatterlist *in_sg; struct scatterlist *in_sg;
struct scatterlist *out_sg;
struct ahash_request ahash_fbk_req; struct ahash_request ahash_fbk_req;
size_t total; size_t total;
size_t nents;
unsigned int blksize; unsigned int blksize;
unsigned int digsize; unsigned int digsize;
unsigned long in_sg_len; unsigned long in_sg_len;
u8 rsa_data[] __aligned(sizeof(u32));
}; };
struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
...@@ -123,5 +165,8 @@ struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); ...@@ -123,5 +165,8 @@ struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
int starfive_hash_register_algs(void); int starfive_hash_register_algs(void);
void starfive_hash_unregister_algs(void); void starfive_hash_unregister_algs(void);
int starfive_rsa_register_algs(void);
void starfive_rsa_unregister_algs(void);
void starfive_hash_done_task(unsigned long param); void starfive_hash_done_task(unsigned long param);
#endif #endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment