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
select CRYPTO_SHA256
select CRYPTO_SHA512
select CRYPTO_SM3_GENERIC
select CRYPTO_RSA
help
Support for StarFive JH7110 crypto hardware acceleration engine.
This module provides acceleration for public key algo,
......
# SPDX-License-Identifier: GPL-2.0
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)
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);
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);
}
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;
}
......@@ -132,6 +141,8 @@ 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");
init_completion(&cryp->pka_done);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
......@@ -173,8 +184,14 @@ static int starfive_cryp_probe(struct platform_device *pdev)
if (ret)
goto err_algs_hash;
ret = starfive_rsa_register_algs();
if (ret)
goto err_algs_rsa;
return 0;
err_algs_rsa:
starfive_hash_unregister_algs();
err_algs_hash:
crypto_engine_stop(cryp->engine);
err_engine_start:
......@@ -200,6 +217,7 @@ static int starfive_cryp_remove(struct platform_device *pdev)
struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
starfive_hash_unregister_algs();
starfive_rsa_unregister_algs();
tasklet_kill(&cryp->hash_done);
......
......@@ -18,7 +18,9 @@
#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
#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_PKA_DONE 0x8
#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
#define MAX_KEY_SIZE SHA512_BLOCK_SIZE
......@@ -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 {
u32 v;
......@@ -78,6 +113,8 @@ struct starfive_cryp_ctx {
u8 key[MAX_KEY_SIZE];
int keylen;
bool is_hmac;
struct starfive_rsa_key rsa_key;
struct crypto_akcipher *akcipher_fbk;
struct crypto_ahash *ahash_fbk;
};
......@@ -98,6 +135,7 @@ struct starfive_cryp_dev {
struct dma_slave_config cfg_out;
struct crypto_engine *engine;
struct tasklet_struct hash_done;
struct completion pka_done;
int err;
union starfive_alg_cr alg_cr;
union {
......@@ -108,14 +146,18 @@ struct starfive_cryp_dev {
struct starfive_cryp_request_ctx {
union {
union starfive_hash_csr hash;
union starfive_pka_cacr pka;
} csr;
struct scatterlist *in_sg;
struct scatterlist *out_sg;
struct ahash_request ahash_fbk_req;
size_t total;
size_t nents;
unsigned int blksize;
unsigned int digsize;
unsigned long in_sg_len;
u8 rsa_data[] __aligned(sizeof(u32));
};
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);
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);
#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