mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
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: 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:
@@ -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,
|
||||
|
||||
@@ -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-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
|
||||
|
||||
617
drivers/crypto/starfive/jh7110-rsa.c
Normal file
617
drivers/crypto/starfive/jh7110-rsa.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user