* [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine
@ 2023-04-26 6:58 Jia Jie Ho
2023-04-26 6:58 ` [PATCH v6 1/4] dt-bindings: crypto: Add StarFive crypto module Jia Jie Ho
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Jia Jie Ho @ 2023-04-26 6:58 UTC (permalink / raw)
To: Herbert Xu, David S . Miller, Rob Herring, Krzysztof Kozlowski,
Palmer Dabbelt, Emil Renner Berthing
Cc: linux-crypto, devicetree, linux-kernel, linux-riscv
This patch series adds kernel driver support for StarFive JH7110 crypto
engine. The first patch adds Documentations for the device and Patch 2
adds device probe and DMA init for the module. Patch 3 adds crypto and
DMA dts node for VisionFive 2 board. Patch 4 adds hash/hmac support to
the module.
Patch 3 needs to be applied on top of:
https://lore.kernel.org/lkml/20230424135409.6648-3-xingyu.wu@starfivetech.com/
Patch 4 needs to be applied on top of:
https://lore.kernel.org/linux-crypto/ZEEOXIHwqKblKfBJ@gondor.apana.org.au/T/#u
Changes v5->v6
- Remove set_crypt in export as request will have been created by
init/updated calls (Herbert)
- Use new helper to set statesize of crypto_ahash (Herbert)
- Use crypto_ahash_blocksize instead of crypto_ahash_tfm (Herbert)
- Switch to init_tfm/exit_tfm instead of cra_init/cra_exit (Herbert)
Changes v4->v5
- Schedule tasklet from IRQ handler instead of using completion to sync
events (Herbert)
Changes v3->v4:
- Use fallback for non-aligned cases as hardware doesn't support
hashing piece-meal (Herbert)
- Use ahash_request_set_* helpers to update members of ahash_request
(Herbert)
- Set callbacks for async fallback (Herbert)
- Remove completion variable and use dma_callback to do the rest of
processing instead. (Herbert)
Changes v2->v3:
- Only implement digest and use fallback for other ops (Herbert)
- Use interrupt instead of polling for hash complete (Herbert)
- Remove manual data copy from out-of-bound memory location as it will
be handled by DMA API. (Christoph & Herbert)
Changes v1->v2:
- Fixed yaml filename and format (Krzysztof)
- Removed unnecessary property names in yaml (Krzysztof)
- Moved of_device_id table close to usage (Krzysztof)
- Use dev_err_probe for error returns (Krzysztof)
- Dropped redundant readl and writel wrappers (Krzysztof)
- Updated commit signed offs (Conor)
- Dropped redundant node in dts, module set to on in dtsi (Conor)
Jia Jie Ho (4):
dt-bindings: crypto: Add StarFive crypto module
crypto: starfive - Add crypto engine support
riscv: dts: starfive: Add crypto and DMA node for VisionFive 2
crypto: starfive - Add hash and HMAC support
.../crypto/starfive,jh7110-crypto.yaml | 70 ++
MAINTAINERS | 7 +
arch/riscv/boot/dts/starfive/jh7110.dtsi | 28 +
drivers/crypto/Kconfig | 1 +
drivers/crypto/Makefile | 1 +
drivers/crypto/starfive/Kconfig | 21 +
drivers/crypto/starfive/Makefile | 4 +
drivers/crypto/starfive/jh7110-cryp.c | 237 +++++
drivers/crypto/starfive/jh7110-cryp.h | 127 +++
drivers/crypto/starfive/jh7110-hash.c | 896 ++++++++++++++++++
10 files changed, 1392 insertions(+)
create mode 100644 Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
create mode 100644 drivers/crypto/starfive/Kconfig
create mode 100644 drivers/crypto/starfive/Makefile
create mode 100644 drivers/crypto/starfive/jh7110-cryp.c
create mode 100644 drivers/crypto/starfive/jh7110-cryp.h
create mode 100644 drivers/crypto/starfive/jh7110-hash.c
--
2.25.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH v6 1/4] dt-bindings: crypto: Add StarFive crypto module 2023-04-26 6:58 [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine Jia Jie Ho @ 2023-04-26 6:58 ` Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 2/4] crypto: starfive - Add crypto engine support Jia Jie Ho ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Jia Jie Ho @ 2023-04-26 6:58 UTC (permalink / raw) To: Herbert Xu, David S . Miller, Rob Herring, Krzysztof Kozlowski, Palmer Dabbelt, Emil Renner Berthing Cc: linux-crypto, devicetree, linux-kernel, linux-riscv Add documentation to describe StarFive cryptographic engine. 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> Reviewed-by: Rob Herring <robh@kernel.org> --- .../crypto/starfive,jh7110-crypto.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml diff --git a/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml b/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml new file mode 100644 index 000000000000..71a2876bd6e4 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/starfive,jh7110-crypto.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive Cryptographic Module + +maintainers: + - Jia Jie Ho <jiajie.ho@starfivetech.com> + - William Qiu <william.qiu@starfivetech.com> + +properties: + compatible: + const: starfive,jh7110-crypto + + reg: + maxItems: 1 + + clocks: + items: + - description: Hardware reference clock + - description: AHB reference clock + + clock-names: + items: + - const: hclk + - const: ahb + + interrupts: + maxItems: 1 + + resets: + maxItems: 1 + + dmas: + items: + - description: TX DMA channel + - description: RX DMA channel + + dma-names: + items: + - const: tx + - const: rx + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - dmas + - dma-names + +additionalProperties: false + +examples: + - | + crypto: crypto@16000000 { + compatible = "starfive,jh7110-crypto"; + reg = <0x16000000 0x4000>; + clocks = <&clk 15>, <&clk 16>; + clock-names = "hclk", "ahb"; + interrupts = <28>; + resets = <&reset 3>; + dmas = <&dma 1 2>, + <&dma 0 2>; + dma-names = "tx", "rx"; + }; +... -- 2.25.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 2/4] crypto: starfive - Add crypto engine support 2023-04-26 6:58 [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 1/4] dt-bindings: crypto: Add StarFive crypto module Jia Jie Ho @ 2023-04-26 6:58 ` Jia Jie Ho 2023-04-26 7:56 ` Christophe JAILLET 2023-04-26 8:09 ` Christophe JAILLET 2023-04-26 6:58 ` [PATCH v6 3/4] riscv: dts: starfive: Add crypto and DMA node for VisionFive 2 Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support Jia Jie Ho 3 siblings, 2 replies; 9+ messages in thread From: Jia Jie Ho @ 2023-04-26 6:58 UTC (permalink / raw) To: Herbert Xu, David S . Miller, Rob Herring, Krzysztof Kozlowski, Palmer Dabbelt, Emil Renner Berthing Cc: linux-crypto, devicetree, linux-kernel, linux-riscv Adding device probe and DMA init for StarFive cryptographic module. 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> --- MAINTAINERS | 7 + drivers/crypto/Kconfig | 1 + drivers/crypto/Makefile | 1 + drivers/crypto/starfive/Kconfig | 17 +++ drivers/crypto/starfive/Makefile | 4 + drivers/crypto/starfive/jh7110-cryp.c | 199 ++++++++++++++++++++++++++ drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++ 7 files changed, 292 insertions(+) create mode 100644 drivers/crypto/starfive/Kconfig create mode 100644 drivers/crypto/starfive/Makefile create mode 100644 drivers/crypto/starfive/jh7110-cryp.c create mode 100644 drivers/crypto/starfive/jh7110-cryp.h diff --git a/MAINTAINERS b/MAINTAINERS index 65140500d9f8..a6f7677db4db 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19609,6 +19609,13 @@ F: Documentation/devicetree/bindings/clock/starfive* F: drivers/clk/starfive/ F: include/dt-bindings/clock/starfive* +STARFIVE CRYPTO DRIVER +M: Jia Jie Ho <jiajie.ho@starfivetech.com> +M: William Qiu <william.qiu@starfivetech.com> +S: Supported +F: Documentation/devicetree/bindings/crypto/starfive* +F: drivers/crypto/starfive/ + STARFIVE PINCTRL DRIVER M: Emil Renner Berthing <kernel@esmil.dk> M: Jianlong Huang <jianlong.huang@starfivetech.com> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 55e75fbb658e..64b94376601c 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -817,5 +817,6 @@ config CRYPTO_DEV_SA2UL source "drivers/crypto/keembay/Kconfig" source "drivers/crypto/aspeed/Kconfig" +source "drivers/crypto/starfive/Kconfig" endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 116de173a66c..212931c84412 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -53,3 +53,4 @@ obj-y += xilinx/ obj-y += hisilicon/ obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ obj-y += keembay/ +obj-y += starfive/ diff --git a/drivers/crypto/starfive/Kconfig b/drivers/crypto/starfive/Kconfig new file mode 100644 index 000000000000..73f39b6bc09f --- /dev/null +++ b/drivers/crypto/starfive/Kconfig @@ -0,0 +1,17 @@ +# +# StarFive crypto drivers configuration +# + +config CRYPTO_DEV_JH7110 + tristate "StarFive JH7110 cryptographic engine driver" + depends on SOC_STARFIVE + select CRYPTO_ENGINE + select ARM_AMBA + select DMADEVICES + select AMBA_PL08X + help + Support for StarFive JH7110 crypto hardware acceleration engine. + This module provides acceleration for public key algo, + skciphers, AEAD and hash functions. + + If you choose 'M' here, this module will be called starfive-crypto. diff --git a/drivers/crypto/starfive/Makefile b/drivers/crypto/starfive/Makefile new file mode 100644 index 000000000000..41221acaee39 --- /dev/null +++ b/drivers/crypto/starfive/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o +jh7110-crypto-objs := jh7110-cryp.o diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c new file mode 100644 index 000000000000..a944897609a2 --- /dev/null +++ b/drivers/crypto/starfive/jh7110-cryp.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Cryptographic API. + * + * Support for StarFive hardware cryptographic engine. + * Copyright (c) 2022 StarFive Technology + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> + +#include "jh7110-cryp.h" + +#define DRIVER_NAME "starfive-crypto" + +struct starfive_dev_list { + struct list_head dev_list; + spinlock_t lock; /* protect dev_list */ +}; + +static struct starfive_dev_list dev_list = { + .dev_list = LIST_HEAD_INIT(dev_list.dev_list), + .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock), +}; + +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_dev *cryp = NULL, *tmp; + + spin_lock_bh(&dev_list.lock); + if (!ctx->cryp) { + list_for_each_entry(tmp, &dev_list.dev_list, list) { + cryp = tmp; + break; + } + ctx->cryp = cryp; + } else { + cryp = ctx->cryp; + } + + spin_unlock_bh(&dev_list.lock); + + return cryp; +} + +static int starfive_dma_init(struct starfive_cryp_dev *cryp) +{ + dma_cap_mask_t mask; + + cryp->tx = NULL; + cryp->rx = NULL; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + cryp->tx = dma_request_chan(cryp->dev, "tx"); + if (IS_ERR(cryp->tx)) + return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx), + "Error requesting tx dma channel.\n"); + + cryp->rx = dma_request_chan(cryp->dev, "rx"); + if (IS_ERR(cryp->rx)) { + dma_release_channel(cryp->tx); + return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx), + "Error requesting rx dma channel.\n"); + } + + return 0; +} + +static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp) +{ + dma_release_channel(cryp->tx); + dma_release_channel(cryp->rx); +} + +static int starfive_cryp_probe(struct platform_device *pdev) +{ + struct starfive_cryp_dev *cryp; + struct resource *res; + int ret; + + cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL); + if (!cryp) + return -ENOMEM; + + platform_set_drvdata(pdev, cryp); + cryp->dev = &pdev->dev; + + cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(cryp->base)) + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base), + "Error remapping memory for platform device\n"); + + cryp->phys_base = res->start; + cryp->dma_maxburst = 32; + + cryp->hclk = devm_clk_get(&pdev->dev, "hclk"); + if (IS_ERR(cryp->hclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk), + "Error getting hardware reference clock\n"); + + cryp->ahb = devm_clk_get(&pdev->dev, "ahb"); + if (IS_ERR(cryp->ahb)) + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb), + "Error getting ahb reference clock\n"); + + cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL); + if (IS_ERR(cryp->rst)) + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst), + "Error getting hardware reset line\n"); + + clk_prepare_enable(cryp->hclk); + clk_prepare_enable(cryp->ahb); + reset_control_deassert(cryp->rst); + + spin_lock(&dev_list.lock); + list_add(&cryp->list, &dev_list.dev_list); + spin_unlock(&dev_list.lock); + + ret = starfive_dma_init(cryp); + if (ret) + goto err_dma_init; + + /* Initialize crypto engine */ + cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1); + if (!cryp->engine) { + ret = -ENOMEM; + goto err_engine; + } + + ret = crypto_engine_start(cryp->engine); + if (ret) + goto err_engine_start; + + return 0; + +err_engine_start: + crypto_engine_exit(cryp->engine); +err_engine: + starfive_dma_cleanup(cryp); +err_dma_init: + spin_lock(&dev_list.lock); + list_del(&cryp->list); + spin_unlock(&dev_list.lock); + + return ret; +} + +static int starfive_cryp_remove(struct platform_device *pdev) +{ + struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev); + + if (!cryp) + return -ENODEV; + + crypto_engine_stop(cryp->engine); + crypto_engine_exit(cryp->engine); + + starfive_dma_cleanup(cryp); + + spin_lock(&dev_list.lock); + list_del(&cryp->list); + spin_unlock(&dev_list.lock); + + clk_disable_unprepare(cryp->hclk); + clk_disable_unprepare(cryp->ahb); + reset_control_assert(cryp->rst); + + return 0; +} + +static const struct of_device_id starfive_dt_ids[] __maybe_unused = { + { .compatible = "starfive,jh7110-crypto", .data = NULL}, + {}, +}; +MODULE_DEVICE_TABLE(of, starfive_dt_ids); + +static struct platform_driver starfive_cryp_driver = { + .probe = starfive_cryp_probe, + .remove = starfive_cryp_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = starfive_dt_ids, + }, +}; + +module_platform_driver(starfive_cryp_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("StarFive Cryptographic Module"); diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h new file mode 100644 index 000000000000..393efd38b098 --- /dev/null +++ b/drivers/crypto/starfive/jh7110-cryp.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __STARFIVE_STR_H__ +#define __STARFIVE_STR_H__ + +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/dmaengine.h> + +#include <crypto/engine.h> + +#define STARFIVE_ALG_CR_OFFSET 0x0 +#define STARFIVE_ALG_FIFO_OFFSET 0x4 +#define STARFIVE_IE_MASK_OFFSET 0x8 +#define STARFIVE_IE_FLAG_OFFSET 0xc +#define STARFIVE_DMA_IN_LEN_OFFSET 0x10 +#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14 + +#define STARFIVE_MSG_BUFFER_SIZE SZ_16K + +union starfive_alg_cr { + u32 v; + struct { + u32 start :1; + u32 aes_dma_en :1; + u32 rsvd_0 :1; + u32 hash_dma_en :1; + u32 alg_done :1; + u32 rsvd_1 :3; + u32 clear :1; + u32 rsvd_2 :23; + }; +}; + +struct starfive_cryp_ctx { + struct crypto_engine_ctx enginectx; + struct starfive_cryp_dev *cryp; +}; + +struct starfive_cryp_dev { + struct list_head list; + struct device *dev; + + struct clk *hclk; + struct clk *ahb; + struct reset_control *rst; + + void __iomem *base; + phys_addr_t phys_base; + + u32 dma_maxburst; + struct dma_chan *tx; + struct dma_chan *rx; + struct dma_slave_config cfg_in; + struct dma_slave_config cfg_out; + + struct crypto_engine *engine; + + union starfive_alg_cr alg_cr; +}; + +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); + +#endif -- 2.25.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 2/4] crypto: starfive - Add crypto engine support 2023-04-26 6:58 ` [PATCH v6 2/4] crypto: starfive - Add crypto engine support Jia Jie Ho @ 2023-04-26 7:56 ` Christophe JAILLET 2023-04-27 5:06 ` Jia Jie Ho 2023-04-26 8:09 ` Christophe JAILLET 1 sibling, 1 reply; 9+ messages in thread From: Christophe JAILLET @ 2023-04-26 7:56 UTC (permalink / raw) To: jiajie.ho Cc: davem, devicetree, herbert, kernel, krzysztof.kozlowski+dt, linux-crypto, linux-kernel, linux-riscv, palmer, robh+dt Le 26/04/2023 à 08:58, Jia Jie Ho a écrit : > Adding device probe and DMA init for StarFive cryptographic module. > > Co-developed-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > --- > MAINTAINERS | 7 + > drivers/crypto/Kconfig | 1 + > drivers/crypto/Makefile | 1 + > drivers/crypto/starfive/Kconfig | 17 +++ > drivers/crypto/starfive/Makefile | 4 + > drivers/crypto/starfive/jh7110-cryp.c | 199 ++++++++++++++++++++++++++ > drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++ > 7 files changed, 292 insertions(+) > create mode 100644 drivers/crypto/starfive/Kconfig > create mode 100644 drivers/crypto/starfive/Makefile > create mode 100644 drivers/crypto/starfive/jh7110-cryp.c > create mode 100644 drivers/crypto/starfive/jh7110-cryp.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 65140500d9f8..a6f7677db4db 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -19609,6 +19609,13 @@ F: Documentation/devicetree/bindings/clock/starfive* > F: drivers/clk/starfive/ > F: include/dt-bindings/clock/starfive* > > +STARFIVE CRYPTO DRIVER > +M: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > +M: William Qiu <william.qiu-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > +S: Supported > +F: Documentation/devicetree/bindings/crypto/starfive* > +F: drivers/crypto/starfive/ > + > STARFIVE PINCTRL DRIVER > M: Emil Renner Berthing <kernel-sKpHZLTYfq0@public.gmane.org> > M: Jianlong Huang <jianlong.huang-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig > index 55e75fbb658e..64b94376601c 100644 > --- a/drivers/crypto/Kconfig > +++ b/drivers/crypto/Kconfig > @@ -817,5 +817,6 @@ config CRYPTO_DEV_SA2UL > > source "drivers/crypto/keembay/Kconfig" > source "drivers/crypto/aspeed/Kconfig" > +source "drivers/crypto/starfive/Kconfig" > > endif # CRYPTO_HW > diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile > index 116de173a66c..212931c84412 100644 > --- a/drivers/crypto/Makefile > +++ b/drivers/crypto/Makefile > @@ -53,3 +53,4 @@ obj-y += xilinx/ > obj-y += hisilicon/ > obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ > obj-y += keembay/ > +obj-y += starfive/ > diff --git a/drivers/crypto/starfive/Kconfig b/drivers/crypto/starfive/Kconfig > new file mode 100644 > index 000000000000..73f39b6bc09f > --- /dev/null > +++ b/drivers/crypto/starfive/Kconfig > @@ -0,0 +1,17 @@ > +# > +# StarFive crypto drivers configuration > +# > + > +config CRYPTO_DEV_JH7110 > + tristate "StarFive JH7110 cryptographic engine driver" > + depends on SOC_STARFIVE > + select CRYPTO_ENGINE > + select ARM_AMBA > + select DMADEVICES > + select AMBA_PL08X > + help > + Support for StarFive JH7110 crypto hardware acceleration engine. > + This module provides acceleration for public key algo, > + skciphers, AEAD and hash functions. > + > + If you choose 'M' here, this module will be called starfive-crypto. > diff --git a/drivers/crypto/starfive/Makefile b/drivers/crypto/starfive/Makefile > new file mode 100644 > index 000000000000..41221acaee39 > --- /dev/null > +++ b/drivers/crypto/starfive/Makefile > @@ -0,0 +1,4 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o > +jh7110-crypto-objs := jh7110-cryp.o > diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c > new file mode 100644 > index 000000000000..a944897609a2 > --- /dev/null > +++ b/drivers/crypto/starfive/jh7110-cryp.c > @@ -0,0 +1,199 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Cryptographic API. > + * > + * Support for StarFive hardware cryptographic engine. > + * Copyright (c) 2022 StarFive Technology > + * > + */ > + > +#include <linux/clk.h> > +#include <linux/delay.h> > +#include <linux/interrupt.h> > +#include <linux/iopoll.h> > +#include <linux/module.h> > +#include <linux/of_device.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/reset.h> > + > +#include "jh7110-cryp.h" > + > +#define DRIVER_NAME "starfive-crypto" > + > +struct starfive_dev_list { > + struct list_head dev_list; > + spinlock_t lock; /* protect dev_list */ > +}; > + > +static struct starfive_dev_list dev_list = { > + .dev_list = LIST_HEAD_INIT(dev_list.dev_list), > + .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock), > +}; > + > +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx) > +{ > + struct starfive_cryp_dev *cryp = NULL, *tmp; > + > + spin_lock_bh(&dev_list.lock); > + if (!ctx->cryp) { > + list_for_each_entry(tmp, &dev_list.dev_list, list) { > + cryp = tmp; > + break; > + } > + ctx->cryp = cryp; > + } else { > + cryp = ctx->cryp; > + } > + > + spin_unlock_bh(&dev_list.lock); > + > + return cryp; > +} > + > +static int starfive_dma_init(struct starfive_cryp_dev *cryp) > +{ > + dma_cap_mask_t mask; > + > + cryp->tx = NULL; > + cryp->rx = NULL; Harmless, but 'crypt' is kzalloc()'ed, so these fields are already NULL. > + > + dma_cap_zero(mask); > + dma_cap_set(DMA_SLAVE, mask); > + > + cryp->tx = dma_request_chan(cryp->dev, "tx"); > + if (IS_ERR(cryp->tx)) > + return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx), > + "Error requesting tx dma channel.\n"); > + > + cryp->rx = dma_request_chan(cryp->dev, "rx"); > + if (IS_ERR(cryp->rx)) { > + dma_release_channel(cryp->tx); > + return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx), > + "Error requesting rx dma channel.\n"); > + } > + > + return 0; > +} > + > +static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp) > +{ > + dma_release_channel(cryp->tx); > + dma_release_channel(cryp->rx); > +} > + > +static int starfive_cryp_probe(struct platform_device *pdev) > +{ > + struct starfive_cryp_dev *cryp; > + struct resource *res; > + int ret; > + > + cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL); > + if (!cryp) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, cryp); > + cryp->dev = &pdev->dev; > + > + cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); > + if (IS_ERR(cryp->base)) > + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base), > + "Error remapping memory for platform device\n"); > + > + cryp->phys_base = res->start; > + cryp->dma_maxburst = 32; > + > + cryp->hclk = devm_clk_get(&pdev->dev, "hclk"); > + if (IS_ERR(cryp->hclk)) > + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk), > + "Error getting hardware reference clock\n"); > + > + cryp->ahb = devm_clk_get(&pdev->dev, "ahb"); > + if (IS_ERR(cryp->ahb)) > + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb), > + "Error getting ahb reference clock\n"); > + > + cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL); > + if (IS_ERR(cryp->rst)) > + return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst), > + "Error getting hardware reset line\n"); > + > + clk_prepare_enable(cryp->hclk); > + clk_prepare_enable(cryp->ahb); > + reset_control_deassert(cryp->rst); > + > + spin_lock(&dev_list.lock); > + list_add(&cryp->list, &dev_list.dev_list); > + spin_unlock(&dev_list.lock); > + > + ret = starfive_dma_init(cryp); > + if (ret) > + goto err_dma_init; > + > + /* Initialize crypto engine */ > + cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1); > + if (!cryp->engine) { > + ret = -ENOMEM; > + goto err_engine; > + } > + > + ret = crypto_engine_start(cryp->engine); > + if (ret) > + goto err_engine_start; > + > + return 0; > + > +err_engine_start: > + crypto_engine_exit(cryp->engine); > +err_engine: > + starfive_dma_cleanup(cryp); > +err_dma_init: > + spin_lock(&dev_list.lock); > + list_del(&cryp->list); > + spin_unlock(&dev_list.lock); I think that there should be: clk_disable_unprepare(cryp->hclk); clk_disable_unprepare(cryp->ahb); reset_control_assert(cryp->rst); as in the remove function. > + > + return ret; > +} > + > +static int starfive_cryp_remove(struct platform_device *pdev) > +{ > + struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev); > + > + if (!cryp) > + return -ENODEV; I don't think that this can happen. CJ > + > + crypto_engine_stop(cryp->engine); > + crypto_engine_exit(cryp->engine); > + > + starfive_dma_cleanup(cryp); > + > + spin_lock(&dev_list.lock); > + list_del(&cryp->list); > + spin_unlock(&dev_list.lock); > + > + clk_disable_unprepare(cryp->hclk); > + clk_disable_unprepare(cryp->ahb); > + reset_control_assert(cryp->rst); > + > + return 0; > +} > + > +static const struct of_device_id starfive_dt_ids[] __maybe_unused = { > + { .compatible = "starfive,jh7110-crypto", .data = NULL}, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, starfive_dt_ids); > + > +static struct platform_driver starfive_cryp_driver = { > + .probe = starfive_cryp_probe, > + .remove = starfive_cryp_remove, > + .driver = { > + .name = DRIVER_NAME, > + .of_match_table = starfive_dt_ids, > + }, > +}; > + > +module_platform_driver(starfive_cryp_driver); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION("StarFive Cryptographic Module"); > diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h > new file mode 100644 > index 000000000000..393efd38b098 > --- /dev/null > +++ b/drivers/crypto/starfive/jh7110-cryp.h > @@ -0,0 +1,63 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __STARFIVE_STR_H__ > +#define __STARFIVE_STR_H__ > + > +#include <linux/delay.h> > +#include <linux/dma-mapping.h> > +#include <linux/dmaengine.h> > + > +#include <crypto/engine.h> > + > +#define STARFIVE_ALG_CR_OFFSET 0x0 > +#define STARFIVE_ALG_FIFO_OFFSET 0x4 > +#define STARFIVE_IE_MASK_OFFSET 0x8 > +#define STARFIVE_IE_FLAG_OFFSET 0xc > +#define STARFIVE_DMA_IN_LEN_OFFSET 0x10 > +#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14 > + > +#define STARFIVE_MSG_BUFFER_SIZE SZ_16K > + > +union starfive_alg_cr { > + u32 v; > + struct { > + u32 start :1; > + u32 aes_dma_en :1; > + u32 rsvd_0 :1; > + u32 hash_dma_en :1; > + u32 alg_done :1; > + u32 rsvd_1 :3; > + u32 clear :1; > + u32 rsvd_2 :23; > + }; > +}; > + > +struct starfive_cryp_ctx { > + struct crypto_engine_ctx enginectx; > + struct starfive_cryp_dev *cryp; > +}; > + > +struct starfive_cryp_dev { > + struct list_head list; > + struct device *dev; > + > + struct clk *hclk; > + struct clk *ahb; > + struct reset_control *rst; > + > + void __iomem *base; > + phys_addr_t phys_base; > + > + u32 dma_maxburst; > + struct dma_chan *tx; > + struct dma_chan *rx; > + struct dma_slave_config cfg_in; > + struct dma_slave_config cfg_out; > + > + struct crypto_engine *engine; > + > + union starfive_alg_cr alg_cr; > +}; > + > +struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); > + > +#endif ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 2/4] crypto: starfive - Add crypto engine support 2023-04-26 7:56 ` Christophe JAILLET @ 2023-04-27 5:06 ` Jia Jie Ho 0 siblings, 0 replies; 9+ messages in thread From: Jia Jie Ho @ 2023-04-27 5:06 UTC (permalink / raw) To: Christophe JAILLET Cc: davem, devicetree, herbert, kernel, krzysztof.kozlowski+dt, linux-crypto, linux-kernel, linux-riscv, palmer, robh+dt On 26/4/2023 3:56 pm, Christophe JAILLET wrote: > Le 26/04/2023 à 08:58, Jia Jie Ho a écrit : >> Adding device probe and DMA init for StarFive cryptographic module. >> >> Co-developed-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> >> Signed-off-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> >> Signed-off-by: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> >> --- >> MAINTAINERS | 7 + >> drivers/crypto/Kconfig | 1 + >> drivers/crypto/Makefile | 1 + >> drivers/crypto/starfive/Kconfig | 17 +++ >> drivers/crypto/starfive/Makefile | 4 + >> drivers/crypto/starfive/jh7110-cryp.c | 199 ++++++++++++++++++++++++++ >> drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++ >> 7 files changed, 292 insertions(+) >> create mode 100644 drivers/crypto/starfive/Kconfig >> create mode 100644 drivers/crypto/starfive/Makefile >> create mode 100644 drivers/crypto/starfive/jh7110-cryp.c >> create mode 100644 drivers/crypto/starfive/jh7110-cryp.h >> [...] >> + >> +static int starfive_dma_init(struct starfive_cryp_dev *cryp) >> +{ >> + dma_cap_mask_t mask; >> + >> + cryp->tx = NULL; >> + cryp->rx = NULL; > > Harmless, but 'crypt' is kzalloc()'ed, so these fields are already NULL. > Hi Christophe, I'll remove these in the next version. >> + >> + dma_cap_zero(mask); >> + dma_cap_set(DMA_SLAVE, mask); >> + >> + cryp->tx = dma_request_chan(cryp->dev, "tx"); >> + if (IS_ERR(cryp->tx)) >> + return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx), >> + "Error requesting tx dma channel.\n"); >> + >> + cryp->rx = dma_request_chan(cryp->dev, "rx"); >> + if (IS_ERR(cryp->rx)) { >> + dma_release_channel(cryp->tx); >> + return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx), >> + "Error requesting rx dma channel.\n"); >> + } >> + >> + return 0; >> +} >> + >> +static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp) >> +{ >> + dma_release_channel(cryp->tx); >> + dma_release_channel(cryp->rx); >> +} >> + >> +static int starfive_cryp_probe(struct platform_device *pdev) >> +{ [...] >> + >> + ret = crypto_engine_start(cryp->engine); >> + if (ret) >> + goto err_engine_start; >> + >> + return 0; >> + >> +err_engine_start: >> + crypto_engine_exit(cryp->engine); >> +err_engine: >> + starfive_dma_cleanup(cryp); >> +err_dma_init: >> + spin_lock(&dev_list.lock); >> + list_del(&cryp->list); >> + spin_unlock(&dev_list.lock); > > I think that there should be: > clk_disable_unprepare(cryp->hclk); > clk_disable_unprepare(cryp->ahb); > reset_control_assert(cryp->rst); > > as in the remove function. > Will add these in next version. >> + >> + return ret; >> +} >> + >> +static int starfive_cryp_remove(struct platform_device *pdev) >> +{ >> + struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev); >> + >> + if (!cryp) >> + return -ENODEV; > > I don't think that this can happen. > I'll update this too along with your other comments. Thanks for taking time reviewing this patch series. Best regards, Jia Jie ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 2/4] crypto: starfive - Add crypto engine support 2023-04-26 6:58 ` [PATCH v6 2/4] crypto: starfive - Add crypto engine support Jia Jie Ho 2023-04-26 7:56 ` Christophe JAILLET @ 2023-04-26 8:09 ` Christophe JAILLET 1 sibling, 0 replies; 9+ messages in thread From: Christophe JAILLET @ 2023-04-26 8:09 UTC (permalink / raw) To: jiajie.ho Cc: davem, devicetree, herbert, kernel, krzysztof.kozlowski+dt, linux-crypto, linux-kernel, linux-riscv, palmer, robh+dt Le 26/04/2023 à 08:58, Jia Jie Ho a écrit : > Adding device probe and DMA init for StarFive cryptographic module. > > Co-developed-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > --- > MAINTAINERS | 7 + > drivers/crypto/Kconfig | 1 + > drivers/crypto/Makefile | 1 + > drivers/crypto/starfive/Kconfig | 17 +++ > drivers/crypto/starfive/Makefile | 4 + > drivers/crypto/starfive/jh7110-cryp.c | 199 ++++++++++++++++++++++++++ > drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++ > 7 files changed, 292 insertions(+) > create mode 100644 drivers/crypto/starfive/Kconfig > create mode 100644 drivers/crypto/starfive/Makefile > create mode 100644 drivers/crypto/starfive/jh7110-cryp.c > create mode 100644 drivers/crypto/starfive/jh7110-cryp.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 65140500d9f8..a6f7677db4db 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -19609,6 +19609,13 @@ F: Documentation/devicetree/bindings/clock/starfive* > F: drivers/clk/starfive/ > F: include/dt-bindings/clock/starfive* > > +STARFIVE CRYPTO DRIVER > +M: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > +M: William Qiu <william.qiu-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > +S: Supported > +F: Documentation/devicetree/bindings/crypto/starfive* > +F: drivers/crypto/starfive/ > + > STARFIVE PINCTRL DRIVER > M: Emil Renner Berthing <kernel-sKpHZLTYfq0@public.gmane.org> > M: Jianlong Huang <jianlong.huang-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig > index 55e75fbb658e..64b94376601c 100644 > --- a/drivers/crypto/Kconfig > +++ b/drivers/crypto/Kconfig > @@ -817,5 +817,6 @@ config CRYPTO_DEV_SA2UL > > source "drivers/crypto/keembay/Kconfig" > source "drivers/crypto/aspeed/Kconfig" > +source "drivers/crypto/starfive/Kconfig" > > endif # CRYPTO_HW > diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile > index 116de173a66c..212931c84412 100644 > --- a/drivers/crypto/Makefile > +++ b/drivers/crypto/Makefile > @@ -53,3 +53,4 @@ obj-y += xilinx/ > obj-y += hisilicon/ > obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ > obj-y += keembay/ > +obj-y += starfive/ > diff --git a/drivers/crypto/starfive/Kconfig b/drivers/crypto/starfive/Kconfig > new file mode 100644 > index 000000000000..73f39b6bc09f > --- /dev/null > +++ b/drivers/crypto/starfive/Kconfig > @@ -0,0 +1,17 @@ > +# > +# StarFive crypto drivers configuration > +# > + > +config CRYPTO_DEV_JH7110 > + tristate "StarFive JH7110 cryptographic engine driver" > + depends on SOC_STARFIVE > + select CRYPTO_ENGINE > + select ARM_AMBA > + select DMADEVICES > + select AMBA_PL08X > + help > + Support for StarFive JH7110 crypto hardware acceleration engine. > + This module provides acceleration for public key algo, > + skciphers, AEAD and hash functions. > + > + If you choose 'M' here, this module will be called starfive-crypto. jh7110-cryp? > diff --git a/drivers/crypto/starfive/Makefile b/drivers/crypto/starfive/Makefile > new file mode 100644 > index 000000000000..41221acaee39 > --- /dev/null > +++ b/drivers/crypto/starfive/Makefile > @@ -0,0 +1,4 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o > +jh7110-crypto-objs := jh7110-cryp.o ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 3/4] riscv: dts: starfive: Add crypto and DMA node for VisionFive 2 2023-04-26 6:58 [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 1/4] dt-bindings: crypto: Add StarFive crypto module Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 2/4] crypto: starfive - Add crypto engine support Jia Jie Ho @ 2023-04-26 6:58 ` Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support Jia Jie Ho 3 siblings, 0 replies; 9+ messages in thread From: Jia Jie Ho @ 2023-04-26 6:58 UTC (permalink / raw) To: Herbert Xu, David S . Miller, Rob Herring, Krzysztof Kozlowski, Palmer Dabbelt, Emil Renner Berthing Cc: linux-crypto, devicetree, linux-kernel, linux-riscv Add StarFive cryptographic module and dedicated DMA controller node to VisionFive 2 SoCs. 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> Acked-by: Palmer Dabbelt <palmer@rivosinc.com> --- arch/riscv/boot/dts/starfive/jh7110.dtsi | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index 4ac159d79d66..591abe57ec31 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -455,5 +455,33 @@ uart5: serial@12020000 { reg-shift = <2>; status = "disabled"; }; + + sdma: dma@16008000 { + compatible = "arm,pl080", "arm,primecell"; + arm,primecell-periphid = <0x00041080>; + reg = <0x0 0x16008000 0x0 0x4000>; + interrupts = <29>; + clocks = <&stgcrg JH7110_STGCLK_SEC_HCLK>, + <&stgcrg JH7110_STGCLK_SEC_MISCAHB>; + clock-names = "hclk", "apb_pclk"; + resets = <&stgcrg JH7110_STGRST_SEC_TOP_HRESETN>; + lli-bus-interface-ahb1; + mem-bus-interface-ahb1; + memcpy-burst-size = <256>; + memcpy-bus-width = <32>; + #dma-cells = <2>; + }; + + crypto: crypto@16000000 { + compatible = "starfive,jh7110-crypto"; + reg = <0x0 0x16000000 0x0 0x4000>; + clocks = <&stgcrg JH7110_STGCLK_SEC_HCLK>, + <&stgcrg JH7110_STGCLK_SEC_MISCAHB>; + clock-names = "hclk", "ahb"; + interrupts = <28>; + resets = <&stgcrg JH7110_STGRST_SEC_TOP_HRESETN>; + dmas = <&sdma 1 2>, <&sdma 0 2>; + dma-names = "tx", "rx"; + }; }; }; -- 2.25.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support 2023-04-26 6:58 [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine Jia Jie Ho ` (2 preceding siblings ...) 2023-04-26 6:58 ` [PATCH v6 3/4] riscv: dts: starfive: Add crypto and DMA node for VisionFive 2 Jia Jie Ho @ 2023-04-26 6:58 ` Jia Jie Ho 2023-04-26 8:09 ` Christophe JAILLET 3 siblings, 1 reply; 9+ messages in thread From: Jia Jie Ho @ 2023-04-26 6:58 UTC (permalink / raw) To: Herbert Xu, David S . Miller, Rob Herring, Krzysztof Kozlowski, Palmer Dabbelt, Emil Renner Berthing Cc: linux-crypto, devicetree, linux-kernel, linux-riscv Adding hash/HMAC support for SHA-2 and SM3 to StarFive cryptographic module. 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> --- drivers/crypto/starfive/Kconfig | 4 + drivers/crypto/starfive/Makefile | 2 +- drivers/crypto/starfive/jh7110-cryp.c | 38 ++ drivers/crypto/starfive/jh7110-cryp.h | 70 +- drivers/crypto/starfive/jh7110-hash.c | 896 ++++++++++++++++++++++++++ 5 files changed, 1006 insertions(+), 4 deletions(-) create mode 100644 drivers/crypto/starfive/jh7110-hash.c diff --git a/drivers/crypto/starfive/Kconfig b/drivers/crypto/starfive/Kconfig index 73f39b6bc09f..cde485910f88 100644 --- a/drivers/crypto/starfive/Kconfig +++ b/drivers/crypto/starfive/Kconfig @@ -6,6 +6,10 @@ config CRYPTO_DEV_JH7110 tristate "StarFive JH7110 cryptographic engine driver" depends on SOC_STARFIVE select CRYPTO_ENGINE + select CRYPTO_HMAC + select CRYPTO_SHA256 + select CRYPTO_SHA512 + select CRYPTO_SM3_GENERIC select ARM_AMBA select DMADEVICES select AMBA_PL08X diff --git a/drivers/crypto/starfive/Makefile b/drivers/crypto/starfive/Makefile index 41221acaee39..2af49062e36d 100644 --- a/drivers/crypto/starfive/Makefile +++ b/drivers/crypto/starfive/Makefile @@ -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-crypto-objs := jh7110-cryp.o jh7110-hash.o diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c index a944897609a2..8ce8c0859e1c 100644 --- a/drivers/crypto/starfive/jh7110-cryp.c +++ b/drivers/crypto/starfive/jh7110-cryp.c @@ -82,10 +82,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); @@ -100,6 +115,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; @@ -118,6 +135,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); @@ -141,8 +168,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: @@ -151,6 +184,7 @@ static int starfive_cryp_probe(struct platform_device *pdev) spin_lock(&dev_list.lock); list_del(&cryp->list); spin_unlock(&dev_list.lock); + tasklet_kill(&cryp->hash_done); return ret; } @@ -162,6 +196,10 @@ static int starfive_cryp_remove(struct platform_device *pdev) if (!cryp) return -ENODEV; + starfive_hash_unregister_algs(); + + tasklet_kill(&cryp->hash_done); + crypto_engine_stop(cryp->engine); crypto_engine_exit(cryp->engine); diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h index 393efd38b098..7a589f6eca14 100644 --- a/drivers/crypto/starfive/jh7110-cryp.h +++ b/drivers/crypto/starfive/jh7110-cryp.h @@ -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 BIT(2) +#define STARFIVE_IE_FLAG_HASH_DONE BIT(2) + #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 diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c new file mode 100644 index 000000000000..5081abe4f5d6 --- /dev/null +++ b/drivers/crypto/starfive/jh7110-hash.c @@ -0,0 +1,896 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hash function and HMAC support for StarFive driver + * + * Copyright (c) 2022 StarFive Technology + * + */ + +#include <linux/clk.h> +#include <linux/crypto.h> +#include <linux/dma-direct.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> +#include <linux/amba/pl080.h> + +#include <crypto/hash.h> +#include <crypto/scatterwalk.h> +#include <crypto/internal/hash.h> + +#include "jh7110-cryp.h" + +#define STARFIVE_HASH_REGS_OFFSET 0x300 +#define STARFIVE_HASH_SHACSR (STARFIVE_HASH_REGS_OFFSET + 0x0) +#define STARFIVE_HASH_SHAWDR (STARFIVE_HASH_REGS_OFFSET + 0x4) +#define STARFIVE_HASH_SHARDR (STARFIVE_HASH_REGS_OFFSET + 0x8) +#define STARFIVE_HASH_SHAWSR (STARFIVE_HASH_REGS_OFFSET + 0xC) +#define STARFIVE_HASH_SHAWLEN3 (STARFIVE_HASH_REGS_OFFSET + 0x10) +#define STARFIVE_HASH_SHAWLEN2 (STARFIVE_HASH_REGS_OFFSET + 0x14) +#define STARFIVE_HASH_SHAWLEN1 (STARFIVE_HASH_REGS_OFFSET + 0x18) +#define STARFIVE_HASH_SHAWLEN0 (STARFIVE_HASH_REGS_OFFSET + 0x1C) +#define STARFIVE_HASH_SHAWKR (STARFIVE_HASH_REGS_OFFSET + 0x20) +#define STARFIVE_HASH_SHAWKLEN (STARFIVE_HASH_REGS_OFFSET + 0x24) + +#define STARFIVE_HASH_BUFLEN SHA512_BLOCK_SIZE + +static inline int starfive_hash_wait_busy(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_dev *cryp = ctx->cryp; + u32 status; + + return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, + !(status & STARFIVE_HASH_BUSY), 10, 100000); +} + +static inline int starfive_hash_wait_key_done(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_dev *cryp = ctx->cryp; + u32 status; + + return readl_relaxed_poll_timeout(cryp->base + STARFIVE_HASH_SHACSR, status, + (status & STARFIVE_HASH_KEY_DONE), 10, 100000); +} + +static int starfive_hash_hmac_key(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_cryp_dev *cryp = ctx->cryp; + int klen = ctx->keylen, loop; + unsigned int *key = (unsigned int *)ctx->key; + unsigned char *cl; + + writel(ctx->keylen, cryp->base + STARFIVE_HASH_SHAWKLEN); + + rctx->csr.hash.hmac = 1; + rctx->csr.hash.key_flag = 1; + + writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); + + for (loop = 0; loop < klen / sizeof(unsigned int); loop++, key++) + writel(*key, cryp->base + STARFIVE_HASH_SHAWKR); + + if (klen & 0x3) { + cl = (unsigned char *)key; + for (loop = 0; loop < (klen & 0x3); loop++, cl++) + writeb(*cl, cryp->base + STARFIVE_HASH_SHAWKR); + } + + if (starfive_hash_wait_key_done(ctx)) + return dev_err_probe(cryp->dev, -ETIMEDOUT, "starfive_hash_wait_key_done error\n"); + + return 0; +} + +static void starfive_hash_start(void *param) +{ + struct starfive_cryp_ctx *ctx = param; + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_cryp_dev *cryp = ctx->cryp; + union starfive_alg_cr alg_cr; + union starfive_hash_csr csr; + + dma_unmap_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); + + alg_cr.v = 0; + alg_cr.clear = 1; + + writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); + + csr.v = readl(cryp->base + STARFIVE_HASH_SHACSR); + csr.firstb = 0; + csr.final = 1; + + writel(~STARFIVE_IE_MASK_HASH_DONE, cryp->base + STARFIVE_IE_MASK_OFFSET); + writel(csr.v, cryp->base + STARFIVE_HASH_SHACSR); +} + +static int starfive_hash_xmit_dma(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_cryp_dev *cryp = ctx->cryp; + struct dma_async_tx_descriptor *in_desc; + union starfive_alg_cr alg_cr; + int total_len; + int ret; + + if (!rctx->total) { + starfive_hash_start(ctx); + return 0; + } + + writel(rctx->total, cryp->base + STARFIVE_DMA_IN_LEN_OFFSET); + + total_len = rctx->total; + total_len = (total_len & 0x3) ? (((total_len >> 2) + 1) << 2) : total_len; + sg_dma_len(rctx->in_sg) = total_len; + + alg_cr.v = 0; + alg_cr.start = 1; + alg_cr.hash_dma_en = 1; + + writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET); + + ret = dma_map_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE); + if (!ret) + return dev_err_probe(cryp->dev, -EINVAL, "dma_map_sg() error\n"); + + cryp->cfg_in.direction = DMA_MEM_TO_DEV; + cryp->cfg_in.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cryp->cfg_in.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cryp->cfg_in.src_maxburst = cryp->dma_maxburst; + cryp->cfg_in.dst_maxburst = cryp->dma_maxburst; + cryp->cfg_in.dst_addr = cryp->phys_base + STARFIVE_ALG_FIFO_OFFSET; + + dmaengine_slave_config(cryp->tx, &cryp->cfg_in); + + in_desc = dmaengine_prep_slave_sg(cryp->tx, rctx->in_sg, + ret, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + + if (!in_desc) + return -EINVAL; + + in_desc->callback = starfive_hash_start; + in_desc->callback_param = ctx; + + dmaengine_submit(in_desc); + dma_async_issue_pending(cryp->tx); + + return 0; +} + +static int starfive_hash_xmit(struct starfive_cryp_ctx *ctx) +{ + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_cryp_dev *cryp = ctx->cryp; + int ret = 0; + + rctx->csr.hash.v = 0; + rctx->csr.hash.reset = 1; + writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); + + if (starfive_hash_wait_busy(ctx)) + return dev_err_probe(cryp->dev, -ETIMEDOUT, "Error resetting engine.\n"); + + rctx->csr.hash.v = 0; + rctx->csr.hash.mode = ctx->hash_mode; + rctx->csr.hash.ie = 1; + + if (ctx->is_hmac) { + ret = starfive_hash_hmac_key(ctx); + if (ret) + return ret; + } else { + rctx->csr.hash.start = 1; + rctx->csr.hash.firstb = 1; + writel(rctx->csr.hash.v, cryp->base + STARFIVE_HASH_SHACSR); + } + + return starfive_hash_xmit_dma(ctx); +} + +static int starfive_hash_copy_hash(struct ahash_request *req) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + int count, *data; + int mlen; + + if (!req->result) + return 0; + + mlen = rctx->digsize / sizeof(u32); + data = (u32 *)req->result; + + for (count = 0; count < mlen; count++) + data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR); + + return 0; +} + +void starfive_hash_done_task(unsigned long param) +{ + struct starfive_cryp_dev *cryp = (struct starfive_cryp_dev *)param; + int err = cryp->err; + + if (!err) + err = starfive_hash_copy_hash(cryp->req.hreq); + + crypto_finalize_hash_request(cryp->engine, cryp->req.hreq, err); +} + +static int starfive_hash_check_aligned(struct scatterlist *sg, size_t total, size_t align) +{ + int len = 0; + + if (!total) + return 0; + + if (!IS_ALIGNED(total, align)) + return -EINVAL; + + while (sg) { + if (!IS_ALIGNED(sg->offset, sizeof(u32))) + return -EINVAL; + + if (!IS_ALIGNED(sg->length, align)) + return -EINVAL; + + len += sg->length; + sg = sg_next(sg); + } + + if (len != total) + return -EINVAL; + + return 0; +} + +static int starfive_hash_one_request(struct crypto_engine *engine, void *areq) +{ + struct ahash_request *req = container_of(areq, struct ahash_request, + base); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + struct starfive_cryp_dev *cryp = ctx->cryp; + + if (!cryp) + return -ENODEV; + + return starfive_hash_xmit(ctx); +} + +static int starfive_hash_init(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, + req->result, req->nbytes); + + return crypto_ahash_init(&rctx->ahash_fbk_req); +} + +static int starfive_hash_update(struct ahash_request *req) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, + req->result, req->nbytes); + + return crypto_ahash_update(&rctx->ahash_fbk_req); +} + +static int starfive_hash_final(struct ahash_request *req) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, + req->result, req->nbytes); + + return crypto_ahash_final(&rctx->ahash_fbk_req); +} + +static int starfive_hash_finup(struct ahash_request *req) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, + req->result, req->nbytes); + + return crypto_ahash_finup(&rctx->ahash_fbk_req); +} + +static int starfive_hash_digest_fb(struct ahash_request *req) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, req->base.flags, + req->base.complete, req->base.data); + + ahash_request_set_crypt(&rctx->ahash_fbk_req, req->src, + req->result, req->nbytes); + + return crypto_ahash_digest(&rctx->ahash_fbk_req); +} + +static int starfive_hash_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_dev *cryp = ctx->cryp; + + memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); + + cryp->req.hreq = req; + rctx->total = req->nbytes; + rctx->in_sg = req->src; + rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + rctx->digsize = crypto_ahash_digestsize(tfm); + rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); + ctx->rctx = rctx; + + if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize)) + return starfive_hash_digest_fb(req); + + return crypto_transfer_hash_request_to_engine(cryp->engine, req); +} + +static int starfive_hash_export(struct ahash_request *req, void *out) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + return crypto_ahash_export(&rctx->ahash_fbk_req, out); +} + +static int starfive_hash_import(struct ahash_request *req, const void *in) +{ + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&rctx->ahash_fbk_req, ctx->ahash_fbk); + ahash_request_set_callback(&rctx->ahash_fbk_req, + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP, + req->base.complete, req->base.data); + + return crypto_ahash_import(&rctx->ahash_fbk_req, in); +} + +static int starfive_hash_init_tfm(struct crypto_ahash *hash, + const char *alg_name, + unsigned int mode) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->cryp = starfive_cryp_find_dev(ctx); + + if (!ctx->cryp) + return -ENODEV; + + ctx->ahash_fbk = crypto_alloc_ahash(alg_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + + if (IS_ERR(ctx->ahash_fbk)) + return dev_err_probe(ctx->cryp->dev, PTR_ERR(ctx->ahash_fbk), + "starfive_hash: Could not load fallback driver.\n"); + + crypto_ahash_set_statesize(hash, crypto_ahash_statesize(ctx->ahash_fbk)); + crypto_ahash_set_reqsize(hash, sizeof(struct starfive_cryp_request_ctx) + + crypto_ahash_reqsize(ctx->ahash_fbk)); + + ctx->keylen = 0; + ctx->hash_mode = mode; + + ctx->enginectx.op.do_one_request = starfive_hash_one_request; + ctx->enginectx.op.prepare_request = NULL; + ctx->enginectx.op.unprepare_request = NULL; + + return 0; +} + +static void starfive_hash_exit_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + crypto_free_ahash(ctx->ahash_fbk); + + ctx->ahash_fbk = NULL; + ctx->enginectx.op.do_one_request = NULL; + ctx->enginectx.op.prepare_request = NULL; + ctx->enginectx.op.unprepare_request = NULL; +} + +static int starfive_hash_long_setkey(struct starfive_cryp_ctx *ctx, + const u8 *key, unsigned int keylen, + const char *alg_name) +{ + struct crypto_wait wait; + struct ahash_request *req; + struct scatterlist sg; + struct crypto_ahash *ahash_tfm; + u8 *buf; + int ret; + + ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); + if (IS_ERR(ahash_tfm)) + return PTR_ERR(ahash_tfm); + + req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); + if (!req) { + ret = -ENOMEM; + goto err_free_ahash; + } + + crypto_init_wait(&wait); + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &wait); + crypto_ahash_clear_flags(ahash_tfm, ~0); + + buf = kzalloc(keylen + STARFIVE_HASH_BUFLEN, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto err_free_req; + } + + memcpy(buf, key, keylen); + sg_init_one(&sg, buf, keylen); + ahash_request_set_crypt(req, &sg, ctx->key, keylen); + + ret = crypto_wait_req(crypto_ahash_digest(req), &wait); + + kfree(buf); +err_free_req: + ahash_request_free(req); +err_free_ahash: + crypto_free_ahash(ahash_tfm); + return ret; +} + +static int starfive_hash_setkey(struct crypto_ahash *hash, + const u8 *key, unsigned int keylen) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + unsigned int digestsize = crypto_ahash_digestsize(hash); + unsigned int blocksize = crypto_ahash_blocksize(hash); + const char *alg_name; + + crypto_ahash_setkey(ctx->ahash_fbk, key, keylen); + + if (keylen <= blocksize) { + memcpy(ctx->key, key, keylen); + ctx->keylen = keylen; + return 0; + } + + ctx->keylen = digestsize; + + switch (digestsize) { + case SHA224_DIGEST_SIZE: + alg_name = "sha224-starfive"; + break; + case SHA256_DIGEST_SIZE: + if (ctx->hash_mode == STARFIVE_HASH_SM3) + alg_name = "sm3-starfive"; + else + alg_name = "sha256-starfive"; + break; + case SHA384_DIGEST_SIZE: + alg_name = "sha384-starfive"; + break; + case SHA512_DIGEST_SIZE: + alg_name = "sha512-starfive"; + break; + default: + return -EINVAL; + } + + return starfive_hash_long_setkey(ctx, key, keylen, alg_name); +} + +static int starfive_sha224_init_tfm(struct crypto_ahash *hash) +{ + return starfive_hash_init_tfm(hash, "sha224-generic", + STARFIVE_HASH_SHA224); +} + +static int starfive_sha256_init_tfm(struct crypto_ahash *hash) +{ + return starfive_hash_init_tfm(hash, "sha256-generic", + STARFIVE_HASH_SHA256); +} + +static int starfive_sha384_init_tfm(struct crypto_ahash *hash) +{ + return starfive_hash_init_tfm(hash, "sha384-generic", + STARFIVE_HASH_SHA384); +} + +static int starfive_sha512_init_tfm(struct crypto_ahash *hash) +{ + return starfive_hash_init_tfm(hash, "sha512-generic", + STARFIVE_HASH_SHA512); +} + +static int starfive_sm3_init_tfm(struct crypto_ahash *hash) +{ + return starfive_hash_init_tfm(hash, "sm3-generic", + STARFIVE_HASH_SM3); +} + +static int starfive_hmac_sha224_init_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->is_hmac = true; + + return starfive_hash_init_tfm(hash, "hmac(sha224-generic)", + STARFIVE_HASH_SHA224); +} + +static int starfive_hmac_sha256_init_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->is_hmac = true; + + return starfive_hash_init_tfm(hash, "hmac(sha256-generic)", + STARFIVE_HASH_SHA256); +} + +static int starfive_hmac_sha384_init_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->is_hmac = true; + + return starfive_hash_init_tfm(hash, "hmac(sha384-generic)", + STARFIVE_HASH_SHA384); +} + +static int starfive_hmac_sha512_init_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->is_hmac = true; + + return starfive_hash_init_tfm(hash, "hmac(sha512-generic)", + STARFIVE_HASH_SHA512); +} + +static int starfive_hmac_sm3_init_tfm(struct crypto_ahash *hash) +{ + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(hash); + + ctx->is_hmac = true; + + return starfive_hash_init_tfm(hash, "hmac(sm3-generic)", + STARFIVE_HASH_SM3); +} + +static struct ahash_alg algs_sha2_sm3[] = { +{ + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_sha224_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_hmac_sha224_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .setkey = starfive_hash_setkey, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "hmac(sha224)", + .cra_driver_name = "sha224-hmac-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_sha256_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_hmac_sha256_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .setkey = starfive_hash_setkey, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "hmac(sha256)", + .cra_driver_name = "sha256-hmac-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_sha384_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .halg = { + .digestsize = SHA384_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha384", + .cra_driver_name = "sha384-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_hmac_sha384_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .setkey = starfive_hash_setkey, + .halg = { + .digestsize = SHA384_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "hmac(sha384)", + .cra_driver_name = "sha384-hmac-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_sha512_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .halg = { + .digestsize = SHA512_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "sha512", + .cra_driver_name = "sha512-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_hmac_sha512_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .setkey = starfive_hash_setkey, + .halg = { + .digestsize = SHA512_DIGEST_SIZE, + .statesize = sizeof(struct sha512_state), + .base = { + .cra_name = "hmac(sha512)", + .cra_driver_name = "sha512-hmac-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_sm3_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .halg = { + .digestsize = SM3_DIGEST_SIZE, + .statesize = sizeof(struct sm3_state), + .base = { + .cra_name = "sm3", + .cra_driver_name = "sm3-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SM3_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, { + .init = starfive_hash_init, + .update = starfive_hash_update, + .final = starfive_hash_final, + .finup = starfive_hash_finup, + .digest = starfive_hash_digest, + .export = starfive_hash_export, + .import = starfive_hash_import, + .init_tfm = starfive_hmac_sm3_init_tfm, + .exit_tfm = starfive_hash_exit_tfm, + .setkey = starfive_hash_setkey, + .halg = { + .digestsize = SM3_DIGEST_SIZE, + .statesize = sizeof(struct sm3_state), + .base = { + .cra_name = "hmac(sm3)", + .cra_driver_name = "sm3-hmac-starfive", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SM3_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct starfive_cryp_ctx), + .cra_alignmask = 3, + .cra_module = THIS_MODULE, + } + } +}, +}; + +int starfive_hash_register_algs(void) +{ + int ret = 0; + + ret = crypto_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); + + return ret; +} + +void starfive_hash_unregister_algs(void) +{ + crypto_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); +} -- 2.25.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support 2023-04-26 6:58 ` [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support Jia Jie Ho @ 2023-04-26 8:09 ` Christophe JAILLET 0 siblings, 0 replies; 9+ messages in thread From: Christophe JAILLET @ 2023-04-26 8:09 UTC (permalink / raw) To: jiajie.ho Cc: davem, devicetree, herbert, kernel, krzysztof.kozlowski+dt, linux-crypto, linux-kernel, linux-riscv, palmer, robh+dt Le 26/04/2023 à 08:58, Jia Jie Ho a écrit : > Adding hash/HMAC support for SHA-2 and SM3 to StarFive cryptographic > module. > > Co-developed-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Huan Feng <huan.feng-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > Signed-off-by: Jia Jie Ho <jiajie.ho-bONrM45KWFOXmMXjJBpWqg@public.gmane.org> > --- > drivers/crypto/starfive/Kconfig | 4 + > drivers/crypto/starfive/Makefile | 2 +- > drivers/crypto/starfive/jh7110-cryp.c | 38 ++ > drivers/crypto/starfive/jh7110-cryp.h | 70 +- > drivers/crypto/starfive/jh7110-hash.c | 896 ++++++++++++++++++++++++++ > 5 files changed, 1006 insertions(+), 4 deletions(-) > create mode 100644 drivers/crypto/starfive/jh7110-hash.c > [...] > +int starfive_hash_register_algs(void) > +{ > + int ret = 0; > + > + ret = crypto_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); > + > + return ret; Nit: return crypto_register_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); ? > +} > + > +void starfive_hash_unregister_algs(void) > +{ > + crypto_unregister_ahashes(algs_sha2_sm3, ARRAY_SIZE(algs_sha2_sm3)); > +} ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-04-27 5:07 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-04-26 6:58 [PATCH v6 0/4] crypto: starfive - Add drivers for crypto engine Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 1/4] dt-bindings: crypto: Add StarFive crypto module Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 2/4] crypto: starfive - Add crypto engine support Jia Jie Ho 2023-04-26 7:56 ` Christophe JAILLET 2023-04-27 5:06 ` Jia Jie Ho 2023-04-26 8:09 ` Christophe JAILLET 2023-04-26 6:58 ` [PATCH v6 3/4] riscv: dts: starfive: Add crypto and DMA node for VisionFive 2 Jia Jie Ho 2023-04-26 6:58 ` [PATCH v6 4/4] crypto: starfive - Add hash and HMAC support Jia Jie Ho 2023-04-26 8:09 ` Christophe JAILLET
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®